Commit 00882cc3edbc26721fd392b5a314c0a24bee977a

Authored by ABNER SILVA DE OLIVEIRA
1 parent 132b5d04

changed to use @Output on post-comment-component to propagate event to the comme…

…nts list. removed post-comment-event-service
src/app/article/comment/comment.component.spec.ts
1 import {Provider, provide, Component} from 'ng-forward'; 1 import {Provider, provide, Component} from 'ng-forward';
2 import * as helpers from "../../../spec/helpers"; 2 import * as helpers from "../../../spec/helpers";
3 -  
4 import {CommentComponent} from './comment.component'; 3 import {CommentComponent} from './comment.component';
5 -import {PostCommentComponent} from './post-comment/post-comment.component';  
6 4
7 const htmlTemplate: string = '<noosfero-comment [article]="ctrl.article" [comment]="ctrl.comment"></noosfero-comment>'; 5 const htmlTemplate: string = '<noosfero-comment [article]="ctrl.article" [comment]="ctrl.comment"></noosfero-comment>';
8 6
@@ -11,12 +9,9 @@ describe(&quot;Components&quot;, () =&gt; { @@ -11,12 +9,9 @@ describe(&quot;Components&quot;, () =&gt; {
11 9
12 beforeEach(angular.mock.module("templates")); 10 beforeEach(angular.mock.module("templates"));
13 11
14 - let postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["subscribe"]);  
15 12
16 function createComponent() { 13 function createComponent() {
17 - let providers = [  
18 - new Provider('PostCommentEventService', { useValue: postCommentEventService })  
19 - ].concat(helpers.provideFilters("translateFilter")); 14 + let providers = helpers.provideFilters("translateFilter");
20 15
21 @Component({ selector: 'test-container-component', directives: [CommentComponent], template: htmlTemplate, providers: providers }) 16 @Component({ selector: 'test-container-component', directives: [CommentComponent], template: htmlTemplate, providers: providers })
22 class ContainerComponent { 17 class ContainerComponent {
@@ -44,21 +39,16 @@ describe(&quot;Components&quot;, () =&gt; { @@ -44,21 +39,16 @@ describe(&quot;Components&quot;, () =&gt; {
44 createComponent().then(fixture => { 39 createComponent().then(fixture => {
45 let component: CommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance; 40 let component: CommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
46 component.reply(); 41 component.reply();
47 - expect(component.showReply).toBeTruthy(1); 42 + expect(component.showReply()).toBeTruthy("Reply was expected to be true");
48 done(); 43 done();
49 }); 44 });
50 }); 45 });
51 46
52 - it("close form when receive a reply", done => {  
53 - let func: Function;  
54 - postCommentEventService.subscribe = (fn: Function) => {  
55 - func = fn;  
56 - }; 47 + it("show reply relies on current comment __showReply attribute", done => {
57 createComponent().then(fixture => { 48 createComponent().then(fixture => {
58 let component = fixture.debugElement.componentViewChildren[0]; 49 let component = fixture.debugElement.componentViewChildren[0];
59 - component.componentInstance.showReply = true;  
60 - func(<noosfero.Comment>{});  
61 - expect(component.componentInstance.showReply).toEqual(false); 50 + component.componentInstance.comment.__showReply = false;
  51 + expect(component.componentInstance.showReply()).toEqual(false);
62 done(); 52 done();
63 }); 53 });
64 }); 54 });
src/app/article/comment/comment.component.ts
1 -import { Inject, Input, Component } from 'ng-forward'; 1 +import { Inject, Input, Component, Output, EventEmitter } from 'ng-forward';
2 import { PostCommentComponent } from "./post-comment/post-comment.component"; 2 import { PostCommentComponent } from "./post-comment/post-comment.component";
3 -import { PostCommentEventService } from "./post-comment/post-comment-event.service";  
4 3
5 @Component({ 4 @Component({
6 selector: 'noosfero-comment', 5 selector: 'noosfero-comment',
7 templateUrl: 'app/article/comment/comment.html' 6 templateUrl: 'app/article/comment/comment.html'
8 }) 7 })
9 -@Inject(PostCommentEventService, "$scope")  
10 export class CommentComponent { 8 export class CommentComponent {
11 9
12 - @Input() comment: noosfero.Comment; 10 + @Input() comment: noosfero.CommentViewModel;
13 @Input() article: noosfero.Article; 11 @Input() article: noosfero.Article;
14 12
15 - showReply: boolean = false; 13 + showReply() {
  14 + return this.comment && this.comment.__show_reply === true;
  15 + }
16 16
17 - constructor(postCommentEventService: PostCommentEventService, private $scope: ng.IScope) {  
18 - postCommentEventService.subscribe((comment: noosfero.Comment) => {  
19 - this.showReply = false;  
20 - this.$scope.$apply();  
21 - }); 17 + constructor() {
22 } 18 }
23 19
  20 +
24 reply() { 21 reply() {
25 - this.showReply = !this.showReply; 22 + this.comment.__show_reply = !this.comment.__show_reply;
26 } 23 }
27 } 24 }
src/app/article/comment/comment.html
@@ -17,5 +17,5 @@ @@ -17,5 +17,5 @@
17 {{"comment.reply" | translate}} 17 {{"comment.reply" | translate}}
18 </a> 18 </a>
19 </div> 19 </div>
20 - <noosfero-comments [show-form]="ctrl.showReply" [article]="ctrl.article" [parent]="ctrl.comment"></noosfero-comments> 20 + <noosfero-comments [show-form]="ctrl.showReply()" [article]="ctrl.article" [parent]="ctrl.comment"></noosfero-comments>
21 </div> 21 </div>
src/app/article/comment/comments.component.spec.ts
@@ -17,21 +17,13 @@ describe(&quot;Components&quot;, () =&gt; { @@ -17,21 +17,13 @@ describe(&quot;Components&quot;, () =&gt; {
17 commentService.getByArticle = jasmine.createSpy("getByArticle") 17 commentService.getByArticle = jasmine.createSpy("getByArticle")
18 .and.returnValue(helpers.mocks.promiseResultTemplate({ data: comments })); 18 .and.returnValue(helpers.mocks.promiseResultTemplate({ data: comments }));
19 19
20 - let emitEvent: Function;  
21 - let postCommentEventService = {  
22 - subscribe: (fn: Function) => {  
23 - emitEvent = fn;  
24 - }  
25 - };  
26 -  
27 let properties = { article: { id: 1 }, parent: <any>null }; 20 let properties = { article: { id: 1 }, parent: <any>null };
28 function createComponent() { 21 function createComponent() {
29 // postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["subscribe"]); 22 // postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["subscribe"]);
30 let providers = [ 23 let providers = [
31 helpers.createProviderToValue('CommentService', commentService), 24 helpers.createProviderToValue('CommentService', commentService),
32 helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), 25 helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService),
33 - helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})),  
34 - new Provider('PostCommentEventService', { useValue: postCommentEventService }) 26 + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({}))
35 ].concat(helpers.provideFilters("translateFilter")); 27 ].concat(helpers.provideFilters("translateFilter"));
36 28
37 return helpers.quickCreateComponent({ 29 return helpers.quickCreateComponent({
@@ -60,7 +52,8 @@ describe(&quot;Components&quot;, () =&gt; { @@ -60,7 +52,8 @@ describe(&quot;Components&quot;, () =&gt; {
60 it("update comments list when receive an reply", done => { 52 it("update comments list when receive an reply", done => {
61 properties.parent = { id: 3 }; 53 properties.parent = { id: 3 };
62 createComponent().then(fixture => { 54 createComponent().then(fixture => {
63 - emitEvent(<noosfero.Comment>{ id: 1, reply_of: { id: 3 } }); 55 + (<CommentsComponent>fixture.debugElement.componentViewChildren[0].componentInstance).commentAdded(<noosfero.Comment>{ id: 1, reply_of: { id: 3 } });
  56 + fixture.detectChanges();
64 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(3); 57 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(3);
65 done(); 58 done();
66 }); 59 });
src/app/article/comment/comments.component.ts
1 -import { Inject, Input, Component, provide } from 'ng-forward'; 1 +import { Inject, Input, Output, Component, provide, EventEmitter } from 'ng-forward';
  2 +import {INgForwardJQuery} from "ng-forward/cjs/util/jqlite-extensions";
  3 +
  4 +
2 import { PostCommentComponent } from "./post-comment/post-comment.component"; 5 import { PostCommentComponent } from "./post-comment/post-comment.component";
3 import { CommentService } from "../../../lib/ng-noosfero-api/http/comment.service"; 6 import { CommentService } from "../../../lib/ng-noosfero-api/http/comment.service";
4 import { CommentComponent } from "./comment.component"; 7 import { CommentComponent } from "./comment.component";
5 -import { PostCommentEventService } from "./post-comment/post-comment-event.service";  
6 8
7 @Component({ 9 @Component({
8 selector: 'noosfero-comments', 10 selector: 'noosfero-comments',
9 templateUrl: 'app/article/comment/comments.html', 11 templateUrl: 'app/article/comment/comments.html',
10 - directives: [PostCommentComponent, CommentComponent] 12 + directives: [PostCommentComponent, CommentComponent],
  13 + outputs: ['commentAdded']
11 }) 14 })
12 -@Inject(CommentService, PostCommentEventService, "$scope") 15 +@Inject(CommentService, "$element")
13 export class CommentsComponent { 16 export class CommentsComponent {
14 17
15 - comments: noosfero.Comment[] = []; 18 + comments: noosfero.CommentViewModel[] = [];
16 @Input() showForm = true; 19 @Input() showForm = true;
17 @Input() article: noosfero.Article; 20 @Input() article: noosfero.Article;
18 - @Input() parent: noosfero.Comment; 21 + @Input() parent: noosfero.CommentViewModel;
  22 +
19 protected page = 1; 23 protected page = 1;
20 protected perPage = 5; 24 protected perPage = 5;
21 protected total = 0; 25 protected total = 0;
22 26
23 - constructor(protected commentService: CommentService, private postCommentEventService: PostCommentEventService, private $scope: ng.IScope) { } 27 + constructor(protected commentService: CommentService) { }
24 28
25 ngOnInit() { 29 ngOnInit() {
26 if (this.parent) { 30 if (this.parent) {
@@ -28,13 +32,20 @@ export class CommentsComponent { @@ -28,13 +32,20 @@ export class CommentsComponent {
28 } else { 32 } else {
29 this.loadNextPage(); 33 this.loadNextPage();
30 } 34 }
31 - this.postCommentEventService.subscribe((comment: noosfero.Comment) => {  
32 - if ((!this.parent && !comment.reply_of) || (comment.reply_of && this.parent && comment.reply_of.id === this.parent.id)) {  
33 - if (!this.comments) this.comments = [];  
34 - this.comments.push(comment);  
35 - this.$scope.$apply();  
36 - } 35 + }
  36 +
  37 + commentAdded(comment: noosfero.Comment): void {
  38 + this.comments.push(comment);
  39 + this.resetShowReply();
  40 + }
  41 +
  42 + private resetShowReply() {
  43 + this.comments.forEach((comment: noosfero.CommentViewModel) => {
  44 + comment.__show_reply = false;
37 }); 45 });
  46 + if (this.parent) {
  47 + this.parent.__show_reply = false;
  48 + }
38 } 49 }
39 50
40 loadComments() { 51 loadComments() {
src/app/article/comment/comments.html
1 <div class="comments"> 1 <div class="comments">
2 - <noosfero-post-comment ng-if="ctrl.showForm" [article]="ctrl.article" [parent]="ctrl.parent"></noosfero-post-comment> 2 + <noosfero-post-comment (comment-saved)="ctrl.commentAdded($event.detail)" ng-if="ctrl.showForm" [article]="ctrl.article" [parent]="ctrl.parent"></noosfero-post-comment>
3 3
4 <div class="comments-list"> 4 <div class="comments-list">
5 <noosfero-comment ng-repeat="comment in ctrl.comments | orderBy: 'created_at':true" [comment]="comment" [article]="ctrl.article"></noosfero-comment> 5 <noosfero-comment ng-repeat="comment in ctrl.comments | orderBy: 'created_at':true" [comment]="comment" [article]="ctrl.article"></noosfero-comment>
src/app/article/comment/post-comment/post-comment-event.service.spec.ts
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -import {PostCommentEventService} from "./post-comment-event.service";  
2 -import {ComponentTestHelper, createClass} from '../../../../spec/component-test-helper';  
3 -import * as helpers from "../../../../spec/helpers";  
4 -import {Provider} from 'ng-forward';  
5 -import {ComponentFixture} from 'ng-forward/cjs/testing/test-component-builder';  
6 -  
7 -describe("Services", () => {  
8 - describe("Comment Paragraph Event Service", () => {  
9 - let eventService: PostCommentEventService;  
10 -  
11 - beforeEach(() => {  
12 - eventService = new PostCommentEventService();  
13 - eventService['eventEmitter'] = jasmine.createSpyObj("eventEmitter", ["next", "subscribe"]);  
14 - });  
15 -  
16 - it('subscribe to post comment event', () => {  
17 - eventService.subscribe(() => { });  
18 - expect(eventService['eventEmitter'].subscribe).toHaveBeenCalled();  
19 - });  
20 -  
21 - it('emit event when post comment', () => {  
22 - eventService.emit(<noosfero.Comment>{});  
23 - expect(eventService['eventEmitter'].next).toHaveBeenCalled();  
24 - });  
25 - });  
26 -});  
src/app/article/comment/post-comment/post-comment-event.service.ts
@@ -1,19 +0,0 @@ @@ -1,19 +0,0 @@
1 -import {Injectable, EventEmitter} from "ng-forward";  
2 -  
3 -@Injectable()  
4 -export class PostCommentEventService {  
5 -  
6 - private eventEmitter: EventEmitter<noosfero.Comment>;  
7 -  
8 - constructor() {  
9 - this.eventEmitter = new EventEmitter();  
10 - }  
11 -  
12 - emit(comment: noosfero.Comment) {  
13 - this.eventEmitter.next(comment);  
14 - }  
15 -  
16 - subscribe(fn: (comment: noosfero.Comment) => void) {  
17 - this.eventEmitter.subscribe(fn);  
18 - }  
19 -}  
src/app/article/comment/post-comment/post-comment.component.spec.ts
1 import {Provider, provide, Component} from 'ng-forward'; 1 import {Provider, provide, Component} from 'ng-forward';
2 import * as helpers from "../../../../spec/helpers"; 2 import * as helpers from "../../../../spec/helpers";
3 -  
4 import {PostCommentComponent} from './post-comment.component'; 3 import {PostCommentComponent} from './post-comment.component';
5 4
6 const htmlTemplate: string = '<noosfero-post-comment [article]="ctrl.article" [reply-of]="ctrl.comment"></noosfero-post-comment>'; 5 const htmlTemplate: string = '<noosfero-post-comment [article]="ctrl.article" [reply-of]="ctrl.comment"></noosfero-post-comment>';
@@ -11,13 +10,11 @@ describe(&quot;Components&quot;, () =&gt; { @@ -11,13 +10,11 @@ describe(&quot;Components&quot;, () =&gt; {
11 beforeEach(angular.mock.module("templates")); 10 beforeEach(angular.mock.module("templates"));
12 11
13 let commentService = jasmine.createSpyObj("commentService", ["createInArticle"]); 12 let commentService = jasmine.createSpyObj("commentService", ["createInArticle"]);
14 - let postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["emit"]);  
15 let user = {}; 13 let user = {};
16 let providers = [ 14 let providers = [
17 new Provider('CommentService', { useValue: commentService }), 15 new Provider('CommentService', { useValue: commentService }),
18 new Provider('NotificationService', { useValue: helpers.mocks.notificationService }), 16 new Provider('NotificationService', { useValue: helpers.mocks.notificationService }),
19 - new Provider('SessionService', { useValue: helpers.mocks.sessionWithCurrentUser(user) }),  
20 - new Provider('PostCommentEventService', { useValue: postCommentEventService }) 17 + new Provider('SessionService', { useValue: helpers.mocks.sessionWithCurrentUser(user) })
21 ].concat(helpers.provideFilters("translateFilter")); 18 ].concat(helpers.provideFilters("translateFilter"));
22 19
23 @Component({ selector: 'test-container-component', directives: [PostCommentComponent], template: htmlTemplate, providers: providers }) 20 @Component({ selector: 'test-container-component', directives: [PostCommentComponent], template: htmlTemplate, providers: providers })
@@ -36,9 +33,10 @@ describe(&quot;Components&quot;, () =&gt; { @@ -36,9 +33,10 @@ describe(&quot;Components&quot;, () =&gt; {
36 it("emit an event when create comment", done => { 33 it("emit an event when create comment", done => {
37 helpers.createComponentFromClass(ContainerComponent).then(fixture => { 34 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
38 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance; 35 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  36 + component.commentSaved.next = jasmine.createSpy("next");
39 commentService.createInArticle = jasmine.createSpy("createInArticle").and.returnValue(helpers.mocks.promiseResultTemplate({ data: {} })); 37 commentService.createInArticle = jasmine.createSpy("createInArticle").and.returnValue(helpers.mocks.promiseResultTemplate({ data: {} }));
40 component.save(); 38 component.save();
41 - expect(postCommentEventService.emit).toHaveBeenCalled(); 39 + expect(component.commentSaved.next).toHaveBeenCalled();
42 done(); 40 done();
43 }); 41 });
44 }); 42 });
src/app/article/comment/post-comment/post-comment.component.ts
1 -import { Inject, Input, Component } from 'ng-forward'; 1 +import { Inject, Input, Output, EventEmitter, Component } from 'ng-forward';
2 import { CommentService } from "../../../../lib/ng-noosfero-api/http/comment.service"; 2 import { CommentService } from "../../../../lib/ng-noosfero-api/http/comment.service";
3 import { NotificationService } from "../../../shared/services/notification.service"; 3 import { NotificationService } from "../../../shared/services/notification.service";
4 import { SessionService } from "../../../login"; 4 import { SessionService } from "../../../login";
5 -import { PostCommentEventService } from "./post-comment-event.service";  
6 5
7 @Component({ 6 @Component({
8 selector: 'noosfero-post-comment', 7 selector: 'noosfero-post-comment',
9 - templateUrl: 'app/article/comment/post-comment/post-comment.html' 8 + templateUrl: 'app/article/comment/post-comment/post-comment.html',
  9 + outputs: ['commentSaved']
10 }) 10 })
11 -@Inject(CommentService, NotificationService, SessionService, PostCommentEventService) 11 +@Inject(CommentService, NotificationService, SessionService)
12 export class PostCommentComponent { 12 export class PostCommentComponent {
13 13
14 - public static EVENT_COMMENT_RECEIVED = "comment.received";  
15 -  
16 @Input() article: noosfero.Article; 14 @Input() article: noosfero.Article;
17 @Input() parent: noosfero.Comment; 15 @Input() parent: noosfero.Comment;
  16 + @Output() commentSaved: EventEmitter<Comment> = new EventEmitter<Comment>();
18 17
19 comment = <noosfero.Comment>{}; 18 comment = <noosfero.Comment>{};
20 private currentUser: noosfero.User; 19 private currentUser: noosfero.User;
21 20
22 constructor(private commentService: CommentService, 21 constructor(private commentService: CommentService,
23 private notificationService: NotificationService, 22 private notificationService: NotificationService,
24 - private session: SessionService,  
25 - private postCommentEventService: PostCommentEventService) { 23 + private session: SessionService) {
26 this.currentUser = this.session.currentUser(); 24 this.currentUser = this.session.currentUser();
27 } 25 }
28 26
@@ -31,7 +29,7 @@ export class PostCommentComponent { @@ -31,7 +29,7 @@ export class PostCommentComponent {
31 this.comment.reply_of_id = this.parent.id; 29 this.comment.reply_of_id = this.parent.id;
32 } 30 }
33 this.commentService.createInArticle(this.article, this.comment).then((result: noosfero.RestResult<noosfero.Comment>) => { 31 this.commentService.createInArticle(this.article, this.comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
34 - this.postCommentEventService.emit(result.data); 32 + this.commentSaved.next(result.data);
35 this.comment.body = ""; 33 this.comment.body = "";
36 this.notificationService.success({ title: "comment.post.success.title", message: "comment.post.success.message" }); 34 this.notificationService.success({ title: "comment.post.success.title", message: "comment.post.success.message" });
37 }); 35 });
src/lib/ng-noosfero-api/interfaces/comment.ts
@@ -5,4 +5,8 @@ namespace noosfero { @@ -5,4 +5,8 @@ namespace noosfero {
5 replies: Comment[]; 5 replies: Comment[];
6 body: string; 6 body: string;
7 } 7 }
  8 +
  9 + export interface CommentViewModel extends Comment {
  10 + __show_reply?: boolean;
  11 + }
8 } 12 }