mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-10768] Make the comments reusable (#7983)
* [AAE-10768] Refactor core comments * [AAE-10768] Add models export in core comments refactor * [AAE-10768] Add comments implementation inside process-services package * [AAE-10768] Add task comments module to process module * [AAE-10768] Add node comments module to content services * [AAE-10768] Add id check to getComments and addComments in adf-core comments component * [AAE-10768] Remove unused service files in process-comments module * [AAE-10768] Remove unused service files in process-comments module * [AAE-10768] Add testing logic to spec files * [AAE-10768] Add comments components readme * [AAE-10768] Add a mock service to inject into the comment stories file * [AAE-10768] Add mock data for comments stories * [AAE-10768] Add mock service to inject into comments stories * [AAE-10768] Rename mock service and mock data * [AAE-10768] change taskId with id into the comments test because taskId is never used * [AAE-10768] Resolve pr suggestions * [AAE-10768] Resolve task-comments pr suggestions * [AAE-10768] Resolve comments pr suggestions * [AAE-10768] Fix merge error in comments.component.html * [AAE-10768] Add missing markdown files * [AAE-10768] Remove events from md files * [AAE-10768] Update upgrade50-60.md with renamed input property Co-authored-by: Amedeo Lepore <amedeo.lepore@hyland.com>
This commit is contained in:
@@ -1,24 +1,29 @@
|
||||
<div class="adf-comments-container">
|
||||
<div id="comment-header" class="adf-comments-header">
|
||||
{{'COMMENTS.HEADER' | translate: { count: comments?.length} }}
|
||||
{{'COMMENTS.HEADER' | translate: { count: comments?.length } }}
|
||||
</div>
|
||||
<div class="adf-comments-input-container" *ngIf="!isReadOnly()">
|
||||
<div class="adf-comments-input-container" *ngIf="!readOnly">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<textarea id="comment-input"
|
||||
<textarea
|
||||
matInput
|
||||
id="comment-input"
|
||||
[attr.aria-label]="'COMMENTS.ADD' | translate"
|
||||
placeholder="{{'COMMENTS.ADD' | translate}}"
|
||||
[(ngModel)]="message"
|
||||
(keydown.escape)="clear($event)"></textarea>
|
||||
(keydown.escape)="clearMessage($event)"
|
||||
>
|
||||
</textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-comments-input-actions">
|
||||
<button mat-button
|
||||
<button
|
||||
mat-button
|
||||
class="adf-comments-input-add"
|
||||
data-automation-id="comments-input-add"
|
||||
color="primary"
|
||||
(click)="add()"
|
||||
[disabled]="!message">
|
||||
(click)="addComment()"
|
||||
[disabled]="!message"
|
||||
>
|
||||
{{ 'COMMENTS.ADD' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
@@ -17,100 +17,74 @@
|
||||
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { CommentProcessService } from '../services/comment-process.service';
|
||||
import { CommentsComponent } from './comments.component';
|
||||
import { CommentContentService } from '../services/comment-content.service';
|
||||
import { setupTestBed } from '../testing/setup-test-bed';
|
||||
import { CoreTestingModule } from '../testing/core.testing.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { CommentsServiceMock, commentsResponseMock } from './mocks/comments.service.mock';
|
||||
import { ADF_COMMENTS_SERVICE, CommentsService } from './interfaces';
|
||||
import { of, throwError } from 'rxjs';
|
||||
|
||||
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;
|
||||
let getCommentSpy: jasmine.Spy;
|
||||
let addCommentSpy: jasmine.Spy;
|
||||
let commentsService: CommentsService;
|
||||
|
||||
setupTestBed({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
CoreTestingModule
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
providers: [
|
||||
{
|
||||
provide: ADF_COMMENTS_SERVICE,
|
||||
useClass: CommentsServiceMock
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CommentsComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
commentProcessService = fixture.debugElement.injector.get(CommentProcessService);
|
||||
commentContentService = fixture.debugElement.injector.get(CommentContentService);
|
||||
commentsService = fixture.componentInstance['commentsService'];
|
||||
|
||||
addContentCommentSpy = spyOn(commentContentService, 'addNodeComment').and.returnValue(of(new CommentModel({
|
||||
id: 123,
|
||||
message: 'Test Comment',
|
||||
createdBy: {id: '999'}
|
||||
})));
|
||||
|
||||
getContentCommentsSpy = spyOn(commentContentService, 'getNodeComments').and.returnValue(of([
|
||||
new CommentModel({message: 'Test1', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}}),
|
||||
new CommentModel({message: 'Test2', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}}),
|
||||
new CommentModel({message: 'Test3', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}})
|
||||
]));
|
||||
|
||||
getProcessCommentsSpy = spyOn(commentProcessService, 'getTaskComments').and.returnValue(of([
|
||||
new CommentModel({message: 'Test1', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}}),
|
||||
new CommentModel({message: 'Test2', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}}),
|
||||
new CommentModel({message: 'Test3', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}})
|
||||
]));
|
||||
addProcessCommentSpy = spyOn(commentProcessService, 'addTaskComment').and.returnValue(of(new CommentModel({
|
||||
id: 123,
|
||||
message: 'Test Comment',
|
||||
createdBy: {id: '999'}
|
||||
})));
|
||||
getCommentSpy = spyOn(commentsService, 'get').and.returnValue(commentsResponseMock.getComments());
|
||||
addCommentSpy = spyOn(commentsService, 'add').and.returnValue(commentsResponseMock.addComment());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should load comments when taskId specified', () => {
|
||||
it('should load comments when id specified', () => {
|
||||
const change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({taskId: change});
|
||||
component.ngOnChanges({id: change});
|
||||
|
||||
expect(getProcessCommentsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load comments when nodeId specified', () => {
|
||||
const change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({nodeId: change});
|
||||
|
||||
expect(getContentCommentsSpy).toHaveBeenCalled();
|
||||
expect(getCommentSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs loading comments', () => {
|
||||
const emitSpy = spyOn(component.error, 'emit');
|
||||
getProcessCommentsSpy.and.returnValue(throwError({}));
|
||||
getCommentSpy.and.returnValue(throwError({}));
|
||||
|
||||
const change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({taskId: change});
|
||||
component.ngOnChanges({id: change});
|
||||
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not load comments when no taskId is specified', () => {
|
||||
it('should not load comments when no id is specified', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getProcessCommentsSpy).not.toHaveBeenCalled();
|
||||
expect(getCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should display comments when the task has comments', async () => {
|
||||
it('should display comments when the entity has comments', async () => {
|
||||
const change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({taskId: change});
|
||||
component.ngOnChanges({id: change});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -119,9 +93,9 @@ describe('CommentsComponent', () => {
|
||||
expect(fixture.nativeElement.querySelector('.adf-comment-message:empty')).toBeNull();
|
||||
});
|
||||
|
||||
it('should display comments count when the task has comments', async () => {
|
||||
it('should display comments count when the entity has comments', async () => {
|
||||
const change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({taskId: change});
|
||||
component.ngOnChanges({id: change});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -130,9 +104,9 @@ describe('CommentsComponent', () => {
|
||||
expect(element.innerText).toBe('COMMENTS.HEADER');
|
||||
});
|
||||
|
||||
it('should not display comments when the task has no comments', async () => {
|
||||
component.taskId = '123';
|
||||
getProcessCommentsSpy.and.returnValue(of([]));
|
||||
it('should not display comments when the entity has no comments', async () => {
|
||||
component.id = '123';
|
||||
getCommentSpy.and.returnValue(of([]));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -142,7 +116,7 @@ describe('CommentsComponent', () => {
|
||||
|
||||
it('should display comments input by default', async () => {
|
||||
const change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({taskId: change});
|
||||
component.ngOnChanges({id: change});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -150,7 +124,7 @@ describe('CommentsComponent', () => {
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should not display comments input when the task is readonly', async () => {
|
||||
it('should not display comments input when the entity is readonly', async () => {
|
||||
component.readOnly = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -159,60 +133,35 @@ describe('CommentsComponent', () => {
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).toBeNull();
|
||||
});
|
||||
|
||||
describe('change detection taskId', () => {
|
||||
describe('Change detection id', () => {
|
||||
const change = new SimpleChange('123', '456', true);
|
||||
const nullChange = new SimpleChange('123', null, true);
|
||||
|
||||
beforeEach(() => {
|
||||
component.taskId = '123';
|
||||
component.id = '123';
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should fetch new comments when taskId changed', () => {
|
||||
component.ngOnChanges({taskId: change});
|
||||
expect(getProcessCommentsSpy).toHaveBeenCalledWith('456');
|
||||
it('should fetch new comments when id changed', () => {
|
||||
component.ngOnChanges({id: change});
|
||||
expect(getCommentSpy).toHaveBeenCalledWith('456');
|
||||
});
|
||||
|
||||
it('should not fetch new comments when empty changeset made', () => {
|
||||
component.ngOnChanges({});
|
||||
expect(getProcessCommentsSpy).not.toHaveBeenCalled();
|
||||
expect(getCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not fetch new comments when taskId changed to null', () => {
|
||||
component.ngOnChanges({taskId: nullChange});
|
||||
expect(getProcessCommentsSpy).not.toHaveBeenCalled();
|
||||
it('should not fetch new comments when id changed to null', () => {
|
||||
component.ngOnChanges({id: nullChange});
|
||||
expect(getCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('change detection node', () => {
|
||||
const change = new SimpleChange('123', '456', true);
|
||||
const nullChange = new SimpleChange('123', null, true);
|
||||
describe('Add comment', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.nodeId = '123';
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
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(() => {
|
||||
component.taskId = '123';
|
||||
component.id = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
});
|
||||
@@ -225,18 +174,18 @@ describe('CommentsComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addProcessCommentSpy).toHaveBeenCalledWith('123', 'action');
|
||||
expect(addCommentSpy).toHaveBeenCalledWith('123', 'action');
|
||||
});
|
||||
|
||||
it('should normalize comment when user input contains spaces sequence', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'test comment';
|
||||
component.message = 'test comment';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addProcessCommentSpy).toHaveBeenCalledWith('123', 'test comment');
|
||||
expect(addCommentSpy).toHaveBeenCalledWith('123', 'test comment');
|
||||
});
|
||||
|
||||
it('should add break lines to comment when user input contains new line characters', async () => {
|
||||
@@ -247,18 +196,21 @@ describe('CommentsComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addProcessCommentSpy).toHaveBeenCalledWith('123', 'these<br/>are<br/>paragraphs');
|
||||
expect(addCommentSpy).toHaveBeenCalledWith('123', 'these<br/>are<br/>paragraphs');
|
||||
});
|
||||
|
||||
it('should call service to add a comment when add button is pressed', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
|
||||
component.message = 'Test Comment';
|
||||
addCommentSpy.and.returnValue(commentsResponseMock.addComment(component.message));
|
||||
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addProcessCommentSpy).toHaveBeenCalled();
|
||||
expect(addCommentSpy).toHaveBeenCalled();
|
||||
const elements = fixture.nativeElement.querySelectorAll('.adf-comment-message');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe('Test Comment');
|
||||
@@ -272,7 +224,7 @@ describe('CommentsComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addProcessCommentSpy).not.toHaveBeenCalled();
|
||||
expect(addCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should clear comment when escape key is pressed', async () => {
|
||||
@@ -289,97 +241,34 @@ describe('CommentsComponent', () => {
|
||||
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
const emitSpy = spyOn(component.error, 'emit');
|
||||
addProcessCommentSpy.and.returnValue(throwError({}));
|
||||
addCommentSpy.and.returnValue(throwError({}));
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
component.addComment();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Add comment node', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
component.nodeId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
it('should set beingAdded variable back to false when an error occurs adding the comment', () => {
|
||||
addCommentSpy.and.returnValue(throwError({}));
|
||||
component.addComment();
|
||||
expect(component.beingAdded).toBeFalse();
|
||||
});
|
||||
|
||||
it('should call service to add a comment when add button is pressed', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'Test Comment';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addContentCommentSpy).toHaveBeenCalled();
|
||||
const elements = fixture.nativeElement.querySelectorAll('.adf-comment-message');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe('Test Comment');
|
||||
it('should set beingAdded variable back to false on successful response when adding the comment', () => {
|
||||
addCommentSpy.and.returnValue(commentsResponseMock.addComment());
|
||||
component.addComment();
|
||||
expect(component.beingAdded).toBeFalse();
|
||||
});
|
||||
|
||||
it('should sanitize comment when user input contains html elements', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = '<div class="text-class"><button onclick=""><h1>action</h1></button></div>';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addContentCommentSpy).toHaveBeenCalledWith('123', 'action');
|
||||
it('should not add comment if id is not provided', () => {
|
||||
component.id = '';
|
||||
component.addComment();
|
||||
expect(addCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should normalize comment when user input contains spaces sequence', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'test comment';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addContentCommentSpy).toHaveBeenCalledWith('123', 'test comment');
|
||||
});
|
||||
|
||||
it('should add break lines to comment when user input contains new line characters', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'these\nare\nparagraphs\n';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addContentCommentSpy).toHaveBeenCalledWith('123', 'these<br/>are<br/>paragraphs');
|
||||
});
|
||||
|
||||
it('should not call service to add a comment when comment is empty', async () => {
|
||||
const element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
it('should not add comment if message is empty', () => {
|
||||
component.message = '';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(addContentCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should clear comment when escape key is pressed', async () => {
|
||||
const event = new KeyboardEvent('keydown', {key: 'Escape'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
element.dispatchEvent(event);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
element = fixture.nativeElement.querySelector('#comment-input');
|
||||
expect(element.value).toBe('');
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
const emitSpy = spyOn(component.error, 'emit');
|
||||
addContentCommentSpy.and.returnValue(throwError({}));
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
component.addComment();
|
||||
expect(addCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -16,13 +16,13 @@
|
||||
*/
|
||||
|
||||
import { Meta, moduleMetadata, Story } from '@storybook/angular';
|
||||
import { CommentContentService, CommentProcessService, EcmUserService } from '../services';
|
||||
import { EcmUserService } from '../services';
|
||||
import { CoreStoryModule } from '../testing/core.story.module';
|
||||
import { CommentsComponent } from './comments.component';
|
||||
import { CommentsModule } from './comments.module';
|
||||
import { CommentContentServiceMock } from '../mock/comment-content-service.mock';
|
||||
import { CommentProcessServiceMock } from '../mock/comment-process-service.mock';
|
||||
import { commentsTaskData, commentsNodeData } from '../mock/comment-content.mock';
|
||||
import { ADF_COMMENTS_SERVICE } from './interfaces/comments.token';
|
||||
import { commentsStoriesData } from './mocks/comments.stories.mock';
|
||||
import { CommentsServiceStoriesMock } from './mocks/comments.service.stories.mock';
|
||||
|
||||
export default {
|
||||
component: CommentsComponent,
|
||||
@@ -31,17 +31,16 @@ export default {
|
||||
moduleMetadata({
|
||||
imports: [CoreStoryModule, CommentsModule],
|
||||
providers: [
|
||||
{ provide: CommentContentService, useClass: CommentContentServiceMock },
|
||||
{ provide: CommentProcessService, useClass: CommentProcessServiceMock },
|
||||
{ provide: EcmUserService, useValue: { getUserProfileImage: () => '../assets/images/logo.png' } }
|
||||
{ provide: EcmUserService, useValue: { getUserProfileImage: () => '../assets/images/logo.png' } },
|
||||
{ provide: ADF_COMMENTS_SERVICE, useClass: CommentsServiceStoriesMock }
|
||||
]
|
||||
})
|
||||
],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: `Displays comments from users involved in a specified task or node.
|
||||
Allows an involved user to add a comment to a task or a node.`
|
||||
component: `Displays comments from users involved in a specified environment.
|
||||
Allows an involved user to add a comment to a environment.`
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -60,21 +59,12 @@ export default {
|
||||
defaultValue: { summary: 'false' }
|
||||
}
|
||||
},
|
||||
nodeId: {
|
||||
id: {
|
||||
control: 'text',
|
||||
description: 'Necessary in order to add a new Node comment',
|
||||
description: 'Necessary in order to add a new comment',
|
||||
table: {
|
||||
type: { summary: 'string' }
|
||||
},
|
||||
if: { arg: 'taskId', exists: false }
|
||||
},
|
||||
taskId: {
|
||||
control: 'text',
|
||||
description: 'Necessary in order to add a new Task comment',
|
||||
table: {
|
||||
type: { summary: 'string' }
|
||||
},
|
||||
if: { arg: 'nodeId', exists: false }
|
||||
}
|
||||
},
|
||||
error: {
|
||||
action: 'error',
|
||||
@@ -93,13 +83,13 @@ const template: Story<CommentsComponent> = (args: CommentsComponent) => ({
|
||||
|
||||
export const singleCommentWithAvatar = template.bind({});
|
||||
singleCommentWithAvatar.args = {
|
||||
comments: [commentsNodeData[0]],
|
||||
comments: [commentsStoriesData[0]],
|
||||
readOnly: true
|
||||
};
|
||||
|
||||
export const singleCommentWithoutAvatar = template.bind({});
|
||||
singleCommentWithoutAvatar.args = {
|
||||
comments: [commentsTaskData[1]],
|
||||
comments: [commentsStoriesData[1]],
|
||||
readOnly: true
|
||||
};
|
||||
|
||||
@@ -109,14 +99,9 @@ noComments.args = {
|
||||
readOnly: true
|
||||
};
|
||||
|
||||
export const nodeComments = template.bind({});
|
||||
nodeComments.args = {
|
||||
comments: commentsNodeData,
|
||||
nodeId: '-fake-'
|
||||
export const comments = template.bind({});
|
||||
comments.args = {
|
||||
comments: commentsStoriesData,
|
||||
id: '-fake-'
|
||||
};
|
||||
|
||||
export const taskComments = template.bind({});
|
||||
taskComments.args = {
|
||||
comments: commentsTaskData,
|
||||
taskId: '-fake-'
|
||||
};
|
||||
|
@@ -15,12 +15,21 @@
|
||||
* 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, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Inject,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
import { share } from 'rxjs/operators';
|
||||
import { ADF_COMMENTS_SERVICE } from './interfaces/comments.token';
|
||||
import { CommentsService } from './interfaces/comments-service.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-comments',
|
||||
@@ -32,11 +41,7 @@ export class CommentsComponent implements OnChanges {
|
||||
|
||||
/** The numeric ID of the task. */
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
/** The numeric ID of the node. */
|
||||
@Input()
|
||||
nodeId: string;
|
||||
id: string;
|
||||
|
||||
/** Are the comments read only? */
|
||||
@Input()
|
||||
@@ -46,143 +51,129 @@ export class CommentsComponent implements OnChanges {
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
comments: CommentModel [] = [];
|
||||
|
||||
private commentObserver: Observer<CommentModel>;
|
||||
comment$: Observable<CommentModel>;
|
||||
comments: CommentModel[] = [];
|
||||
|
||||
message: string;
|
||||
|
||||
beingAdded: boolean = false;
|
||||
|
||||
constructor(private commentProcessService: CommentProcessService,
|
||||
private commentContentService: CommentContentService) {
|
||||
private commentObserver: Observer<CommentModel>;
|
||||
comment$: Observable<CommentModel>;
|
||||
|
||||
constructor(@Inject(ADF_COMMENTS_SERVICE) private commentsService: CommentsService) {
|
||||
this.comment$ = new Observable<CommentModel>((observer) => this.commentObserver = observer)
|
||||
.pipe(share());
|
||||
.pipe(
|
||||
share()
|
||||
);
|
||||
|
||||
this.comment$.subscribe((comment: CommentModel) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
this.taskId = null;
|
||||
this.nodeId = null;
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
this.id = null;
|
||||
|
||||
this.taskId = changes['taskId'] ? changes['taskId'].currentValue : null;
|
||||
this.nodeId = changes['nodeId'] ? changes['nodeId'].currentValue : null;
|
||||
this.id = changes['id'] ? changes['id'].currentValue : null;
|
||||
|
||||
if (this.taskId || this.nodeId) {
|
||||
this.getComments();
|
||||
if (this.id) {
|
||||
this.loadComments();
|
||||
} else {
|
||||
this.resetComments();
|
||||
}
|
||||
}
|
||||
|
||||
private getComments(): void {
|
||||
loadComments() {
|
||||
this.resetComments();
|
||||
if (this.isATask()) {
|
||||
this.commentProcessService.getTaskComments(this.taskId).subscribe(
|
||||
(comments: CommentModel[]) => {
|
||||
if (comments && comments instanceof Array) {
|
||||
comments = comments.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;
|
||||
});
|
||||
comments.forEach((currentComment) => {
|
||||
this.commentObserver.next(currentComment);
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.hasId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.commentsService.get(this.id).subscribe(
|
||||
(comments: CommentModel[]) => {
|
||||
if (!this.isArrayInstance(comments)) {
|
||||
return;
|
||||
}
|
||||
|
||||
comments = this.sortedComments(comments);
|
||||
this.addCommentsToObserver(comments);
|
||||
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
addComment() {
|
||||
if (!this.canAddComment()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const comment: string = this.sanitize(this.message);
|
||||
|
||||
this.beingAdded = true;
|
||||
|
||||
this.commentsService.add(this.id, comment)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.addToComments(res);
|
||||
this.resetMessage();
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isANode()) {
|
||||
this.commentContentService.getNodeComments(this.nodeId).subscribe(
|
||||
(comments: CommentModel[]) => {
|
||||
if (comments && comments instanceof Array) {
|
||||
|
||||
comments = comments.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;
|
||||
});
|
||||
comments.forEach((comment) => {
|
||||
this.commentObserver.next(comment);
|
||||
});
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
() => {
|
||||
this.beingAdded = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
clearMessage(event: Event): void {
|
||||
event.stopPropagation();
|
||||
this.resetMessage();
|
||||
}
|
||||
|
||||
private addToComments(comment: CommentModel): void {
|
||||
this.comments.unshift(comment);
|
||||
}
|
||||
|
||||
private resetMessage(): void {
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
private canAddComment(): boolean {
|
||||
return this.hasId() && this.message && this.message.trim() && !this.beingAdded;
|
||||
}
|
||||
|
||||
private hasId(): boolean {
|
||||
return !!this.id;
|
||||
}
|
||||
|
||||
private isArrayInstance(entity: any): boolean {
|
||||
return entity && entity instanceof Array;
|
||||
}
|
||||
|
||||
private sortedComments(comments: CommentModel[]): CommentModel[] {
|
||||
return comments.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;
|
||||
});
|
||||
}
|
||||
|
||||
private addCommentsToObserver(comments: CommentModel[]): void {
|
||||
comments.forEach((currentComment: CommentModel) => {
|
||||
this.commentObserver.next(currentComment);
|
||||
});
|
||||
}
|
||||
|
||||
private resetComments(): void {
|
||||
this.comments = [];
|
||||
}
|
||||
|
||||
add(): void {
|
||||
if (this.message && this.message.trim() && !this.beingAdded) {
|
||||
const comment = this.sanitize(this.message);
|
||||
|
||||
this.beingAdded = true;
|
||||
if (this.isATask()) {
|
||||
this.commentProcessService.addTaskComment(this.taskId, comment)
|
||||
.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, comment)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
this.message = '';
|
||||
this.beingAdded = false;
|
||||
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.beingAdded = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear(event: Event): void {
|
||||
event.stopPropagation();
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
isReadOnly(): boolean {
|
||||
return this.readOnly;
|
||||
}
|
||||
|
||||
isATask(): boolean {
|
||||
return !!this.taskId;
|
||||
}
|
||||
|
||||
isANode(): boolean {
|
||||
return !!this.nodeId;
|
||||
}
|
||||
|
||||
private sanitize(input: string): string {
|
||||
return input.replace(/<[^>]+>/g, '')
|
||||
.replace(/^\s+|\s+$|\s+(?=\s)/g, '')
|
||||
|
@@ -0,0 +1,24 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { CommentModel } from '../../models/comment.model';
|
||||
|
||||
export interface CommentsService {
|
||||
get(id: string): Observable<CommentModel[]>;
|
||||
add(id: string, message: string): Observable<CommentModel>;
|
||||
}
|
20
lib/core/src/lib/comments/interfaces/comments.token.ts
Normal file
20
lib/core/src/lib/comments/interfaces/comments.token.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { InjectionToken } from '@angular/core';
|
||||
|
||||
export const ADF_COMMENTS_SERVICE = new InjectionToken('ADF_COMMENTS_SERVICE');
|
18
lib/core/src/lib/comments/interfaces/index.ts
Normal file
18
lib/core/src/lib/comments/interfaces/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './public-api';
|
19
lib/core/src/lib/comments/interfaces/public-api.ts
Normal file
19
lib/core/src/lib/comments/interfaces/public-api.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './comments-service.interface';
|
||||
export * from './comments.token';
|
145
lib/core/src/lib/comments/mocks/comments.service.mock.ts
Normal file
145
lib/core/src/lib/comments/mocks/comments.service.mock.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommentModel, EcmUserModel } from '../../models';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { CommentsService } from '../interfaces';
|
||||
|
||||
export class CommentsServiceMock implements CommentsService {
|
||||
|
||||
constructor() {}
|
||||
|
||||
get(_id: string): Observable<CommentModel[]> {
|
||||
return commentsResponseMock.getComments();
|
||||
}
|
||||
add(_id: string): Observable<CommentModel> {
|
||||
return commentsResponseMock.addComment();
|
||||
}
|
||||
}
|
||||
|
||||
export const commentsResponseMock = {
|
||||
getComments: () => of([
|
||||
{
|
||||
id: 1,
|
||||
message: 'Test Comment',
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel,
|
||||
{
|
||||
id: 2,
|
||||
message: 'Test Comment',
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel,
|
||||
{
|
||||
id: 3,
|
||||
message: 'Test Comment',
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel
|
||||
]),
|
||||
addComment: (message = 'test comment') => of({
|
||||
id: 1,
|
||||
message,
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel)
|
||||
};
|
126
lib/core/src/lib/comments/mocks/comments.service.stories.mock.ts
Normal file
126
lib/core/src/lib/comments/mocks/comments.service.stories.mock.ts
Normal file
@@ -0,0 +1,126 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommentModel, EcmUserModel } from '../../models';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { CommentsService } from '../interfaces';
|
||||
import { testUser } from './comments.stories.mock';
|
||||
|
||||
export class CommentsServiceStoriesMock implements CommentsService {
|
||||
|
||||
constructor() {}
|
||||
|
||||
get(_id: string): Observable<CommentModel[]> {
|
||||
return commentsResponseMock.getComments();
|
||||
}
|
||||
add(_id: string, message = 'test comment'): Observable<CommentModel> {
|
||||
return commentsResponseMock.addComment(message);
|
||||
}
|
||||
}
|
||||
|
||||
export const commentsResponseMock = {
|
||||
getComments: () => of([
|
||||
{
|
||||
id: 1,
|
||||
message: 'Test Comment',
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel,
|
||||
{
|
||||
id: 2,
|
||||
message: 'Test Comment',
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel,
|
||||
{
|
||||
id: 3,
|
||||
message: 'Test Comment',
|
||||
created: new Date(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'hruser',
|
||||
displayName: 'hruser',
|
||||
quota: -1,
|
||||
quotaUsed: 12,
|
||||
emailNotificationsEnabled: true,
|
||||
company: {
|
||||
organization: 'test',
|
||||
address1: 'test',
|
||||
address2: 'test',
|
||||
address3: 'test',
|
||||
postcode: 'test',
|
||||
telephone: 'test',
|
||||
fax: 'test',
|
||||
email: 'test'
|
||||
},
|
||||
id: 'hruser',
|
||||
email: 'test',
|
||||
isAdmin: () => false
|
||||
} as EcmUserModel,
|
||||
isSelected: false
|
||||
} as CommentModel
|
||||
]),
|
||||
addComment: (message: string) => of({
|
||||
id: 1,
|
||||
message,
|
||||
created: new Date(),
|
||||
createdBy: testUser,
|
||||
isSelected: false
|
||||
} as CommentModel)
|
||||
};
|
105
lib/core/src/lib/comments/mocks/comments.stories.mock.ts
Normal file
105
lib/core/src/lib/comments/mocks/comments.stories.mock.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommentModel, EcmCompanyModel, EcmUserModel } from '../../models';
|
||||
|
||||
const fakeCompany: EcmCompanyModel = {
|
||||
organization: '',
|
||||
address1: '',
|
||||
address2: '',
|
||||
address3: '',
|
||||
postcode: '',
|
||||
telephone: '',
|
||||
fax: '',
|
||||
email: ''
|
||||
};
|
||||
|
||||
export const getDateXMinutesAgo = (minutes: number) => new Date(new Date().getTime() - minutes * 60000);
|
||||
|
||||
const johnDoe: EcmUserModel = {
|
||||
id: '1',
|
||||
email: 'john.doe@alfresco.com',
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
company: fakeCompany,
|
||||
enabled: true,
|
||||
isAdmin: undefined,
|
||||
avatarId: '001'
|
||||
};
|
||||
|
||||
const janeEod: EcmUserModel = {
|
||||
id: '2',
|
||||
email: 'jane.eod@alfresco.com',
|
||||
firstName: 'Jane',
|
||||
lastName: 'Eod',
|
||||
company: fakeCompany,
|
||||
enabled: true,
|
||||
isAdmin: undefined
|
||||
};
|
||||
|
||||
const robertSmith: EcmUserModel = {
|
||||
id: '3',
|
||||
email: 'robert.smith@alfresco.com',
|
||||
firstName: 'Robert',
|
||||
lastName: 'Smith',
|
||||
company: fakeCompany,
|
||||
enabled: true,
|
||||
isAdmin: undefined
|
||||
};
|
||||
|
||||
export const testUser: EcmUserModel = {
|
||||
id: '44',
|
||||
email: 'test.user@hyland.com',
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
company: fakeCompany,
|
||||
enabled: true,
|
||||
isAdmin: undefined,
|
||||
avatarId: '044'
|
||||
};
|
||||
|
||||
|
||||
export const commentsStoriesData: CommentModel[] = [
|
||||
{
|
||||
id: 1,
|
||||
message: `I've done this task, what's next?`,
|
||||
created: getDateXMinutesAgo(30),
|
||||
createdBy: johnDoe,
|
||||
isSelected: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
message: `I've assigned you another one 🤠`,
|
||||
created: getDateXMinutesAgo(15),
|
||||
createdBy: janeEod,
|
||||
isSelected: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
message: '+1',
|
||||
created: getDateXMinutesAgo(12),
|
||||
createdBy: robertSmith,
|
||||
isSelected: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
message: 'Cheers',
|
||||
created: new Date(),
|
||||
createdBy: johnDoe,
|
||||
isSelected: false
|
||||
}
|
||||
];
|
@@ -18,4 +18,6 @@
|
||||
export * from './comment-list.component';
|
||||
export * from './comments.component';
|
||||
|
||||
export * from './interfaces/index';
|
||||
|
||||
export * from './comments.module';
|
||||
|
@@ -38,3 +38,4 @@ export * from './node-metadata.model';
|
||||
export * from './application-access.model';
|
||||
export * from './user-access.model';
|
||||
export * from './general-user.model';
|
||||
export * from './comment.model';
|
||||
|
Reference in New Issue
Block a user