mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ADF-3374] Comments - add/view multiline comments (#3607)
* multiline comment * add comment e2e * fix locator syntax * lint * clear textarea on ESCAPE event * multiline comment * add comment e2e * fix locator syntax * lint * clear textarea on ESCAPE event
This commit is contained in:
parent
61dff96e8b
commit
f36f9fa862
@ -51,6 +51,9 @@
|
||||
"TITLE": "Metadata"
|
||||
}
|
||||
},
|
||||
"COMMENTS": {
|
||||
"ADD_COMMENT": "ADD"
|
||||
},
|
||||
"APP_LAYOUT": {
|
||||
"APP_NAME": "ADF Demo Application",
|
||||
"HOME": "Home",
|
||||
|
@ -30,7 +30,8 @@ var TaskDetailsPage = function () {
|
||||
var descriptionField = element(by.css("span[data-automation-id*='description'] span"));
|
||||
var dueDateField = element(by.css("span[data-automation-id*='dueDate'] span"));
|
||||
var activitiesTitle = element(by.css("div[class*='adf-info-drawer-layout-header-title'] div"));
|
||||
var commentField = element(by.css("input[id='comment-input']"));
|
||||
var commentField = element(by.id("comment-input"));
|
||||
var addCommentButton = element(by.css("[data-automation-id='comments-input-add']"));
|
||||
var activityTab = element(by.cssContainingText("div[class*='mat-tab-label ']", "Activity"));
|
||||
var detailsTab = element(by.cssContainingText("div[class*='mat-tab-label ']", "Details"));
|
||||
var involvePeopleButton = element(by.css("div[class*='add-people']"));
|
||||
@ -116,6 +117,12 @@ var TaskDetailsPage = function () {
|
||||
this.addComment = function (comment) {
|
||||
Util.waitUntilElementIsVisible(commentField);
|
||||
commentField.sendKeys(comment);
|
||||
addCommentButton.click();
|
||||
return this;
|
||||
};
|
||||
|
||||
this.clearComment = function (comment) {
|
||||
Util.waitUntilElementIsVisible(commentField);
|
||||
commentField.sendKeys(protractor.Key.ENTER);
|
||||
return this;
|
||||
};
|
||||
|
@ -21,9 +21,7 @@
|
||||
<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-message" class="adf-comment-message" [innerHTML]="comment.message"></div>
|
||||
<div matLine id="comment-time" class="adf-comment-message-time">
|
||||
{{ comment.created | adfTimeAgo: currentLocale }}
|
||||
</div>
|
||||
|
@ -4,8 +4,19 @@
|
||||
</div>
|
||||
<div class="adf-comments-input-container" *ngIf="!isReadOnly()">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<input matInput id="comment-input" placeholder="{{'COMMENTS.ADD' | translate}}" [(ngModel)]="message" (keyup.enter)="add()" (keyup.esc)="clear()">
|
||||
<textarea (keyup.escape)="clear()" matInput id="comment-input" placeholder="{{'COMMENTS.ADD' | translate}}" [(ngModel)]="message"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-comments-input-actions">
|
||||
<button mat-button
|
||||
class="adf-comments-input-add"
|
||||
data-automation-id="comments-input-add"
|
||||
color="primary"
|
||||
(click)="add()"
|
||||
[disabled]="!message">
|
||||
{{ 'COMMENTS.ADD_COMMENT' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="comments.length > 0">
|
||||
|
@ -20,6 +20,16 @@
|
||||
width: calc(100% - 30px);
|
||||
padding-top: 8px;
|
||||
border-bottom: $header-border;
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.adf-comments-input-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.adf-full-width {
|
||||
|
@ -219,11 +219,43 @@ describe('CommentsComponent', () => {
|
||||
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');
|
||||
it('should sanitize comment when user input contains html elements', async(() => {
|
||||
let 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();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addProcessCommentSpy).toHaveBeenCalledWith('123', 'action');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should normalize comment when user input contains spaces sequence', async(() => {
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'test comment';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addProcessCommentSpy).toHaveBeenCalledWith('123', 'test comment');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should add break lines to comment when user input contains new line characters', async(() => {
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'these\nare\nparagraphs\n';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addProcessCommentSpy).toHaveBeenCalledWith('123', 'these<br/>are<br/>paragraphs');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should call service to add a comment when add button is pressed', async(() => {
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'Test Comment';
|
||||
element.dispatchEvent(event);
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
@ -235,10 +267,9 @@ describe('CommentsComponent', () => {
|
||||
}));
|
||||
|
||||
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');
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = '';
|
||||
element.dispatchEvent(event);
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
@ -249,7 +280,6 @@ describe('CommentsComponent', () => {
|
||||
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(() => {
|
||||
@ -277,11 +307,10 @@ describe('CommentsComponent', () => {
|
||||
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');
|
||||
it('should call service to add a comment when add button is pressed', async(() => {
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'Test Comment';
|
||||
element.dispatchEvent(event);
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
@ -292,11 +321,43 @@ describe('CommentsComponent', () => {
|
||||
});
|
||||
}));
|
||||
|
||||
it('should sanitize comment when user input contains html elements', async(() => {
|
||||
let 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();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addContentCommentSpy).toHaveBeenCalledWith('123', 'action');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should normalize comment when user input contains spaces sequence', async(() => {
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'test comment';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addContentCommentSpy).toHaveBeenCalledWith('123', 'test comment');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should add break lines to comment when user input contains new line characters', async(() => {
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = 'these\nare\nparagraphs\n';
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addContentCommentSpy).toHaveBeenCalledWith('123', 'these<br/>are<br/>paragraphs');
|
||||
});
|
||||
}));
|
||||
|
||||
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');
|
||||
let element = fixture.nativeElement.querySelector('.adf-comments-input-add');
|
||||
component.message = '';
|
||||
element.dispatchEvent(event);
|
||||
element.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
@ -307,7 +368,6 @@ describe('CommentsComponent', () => {
|
||||
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(() => {
|
||||
|
@ -126,9 +126,11 @@ export class CommentsComponent implements OnChanges {
|
||||
|
||||
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, this.message)
|
||||
this.commentProcessService.addTaskComment(this.taskId, comment)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
@ -144,7 +146,7 @@ export class CommentsComponent implements OnChanges {
|
||||
}
|
||||
|
||||
if (this.isANode()) {
|
||||
this.commentContentService.addNodeComment(this.nodeId, this.message)
|
||||
this.commentContentService.addNodeComment(this.nodeId, comment)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
@ -176,4 +178,10 @@ export class CommentsComponent implements OnChanges {
|
||||
isANode(): boolean {
|
||||
return this.nodeId ? true : false;
|
||||
}
|
||||
|
||||
private sanitize(input: string) {
|
||||
return input.replace(/<[^>]+>/g, '')
|
||||
.replace(/^\s+|\s+$|\s+(?=\s)/g, '')
|
||||
.replace(/\r?\n/g, '<br/>');
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user