Merge Request #30

Closed
noosfero-themes/angular-theme!30
Created by Michel Felipe

Comment Paragraph - Comment count update

Added EventEmitter structure using Typescript mixin pattern to allow multiple events by different component objects with plugin workflow created by @vfcosta

This screenshot bellow shows with the value updated when the user add a new comment:

count-comment

Assignee: Ábner Oliveira
Milestone: None

Closed by Ábner Oliveira

Changes were not merged into target branch

Commits (3)
3 participants
src/app/article/comment/comments.component.spec.ts
@@ -11,7 +11,7 @@ describe("Components", () => { @@ -11,7 +11,7 @@ describe("Components", () => {
11 11
12 beforeEach(angular.mock.module("templates")); 12 beforeEach(angular.mock.module("templates"));
13 13
14 - let commentService = jasmine.createSpyObj("commentService", ["getByArticle"]); 14 + let commentService = helpers.mocks.commentService;
15 15
16 let comments = [{ id: 2 }, { id: 3 }]; 16 let comments = [{ id: 2 }, { id: 3 }];
17 commentService.getByArticle = jasmine.createSpy("getByArticle") 17 commentService.getByArticle = jasmine.createSpy("getByArticle")
@@ -19,7 +19,7 @@ describe("Components", () => { @@ -19,7 +19,7 @@ describe("Components", () => {
19 19
20 let properties = { article: { id: 1 }, parent: <any>null }; 20 let properties = { article: { id: 1 }, parent: <any>null };
21 function createComponent() { 21 function createComponent() {
22 - // postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["subscribe"]); 22 +
23 let providers = [ 23 let providers = [
24 helpers.createProviderToValue('CommentService', commentService), 24 helpers.createProviderToValue('CommentService', commentService),
25 helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), 25 helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService),
@@ -52,7 +52,9 @@ describe(&quot;Components&quot;, () =&gt; { @@ -52,7 +52,9 @@ describe(&quot;Components&quot;, () =&gt; {
52 it("update comments list when receive an reply", done => { 52 it("update comments list when receive an reply", done => {
53 properties.parent = { id: 3 }; 53 properties.parent = { id: 3 };
54 createComponent().then(fixture => { 54 createComponent().then(fixture => {
55 - (<CommentsComponent>fixture.debugElement.componentViewChildren[0].componentInstance).commentAdded(<noosfero.Comment>{ id: 1, reply_of: { id: 3 } }); 55 + let component = (<CommentsComponent>fixture.debugElement.componentViewChildren[0].componentInstance);
  56 + component.commentAdded(<noosfero.Comment>{ id: 1, reply_of: { id: 3 } });
  57 +
56 fixture.detectChanges(); 58 fixture.detectChanges();
57 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(3); 59 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(3);
58 done(); 60 done();
src/app/article/comment/comments.component.ts
@@ -6,10 +6,9 @@ import { CommentComponent } from &quot;./comment.component&quot;; @@ -6,10 +6,9 @@ import { CommentComponent } from &quot;./comment.component&quot;;
6 @Component({ 6 @Component({
7 selector: 'noosfero-comments', 7 selector: 'noosfero-comments',
8 templateUrl: 'app/article/comment/comments.html', 8 templateUrl: 'app/article/comment/comments.html',
9 - directives: [PostCommentComponent, CommentComponent],  
10 - outputs: ['commentAdded'] 9 + directives: [PostCommentComponent, CommentComponent]
11 }) 10 })
12 -@Inject(CommentService, "$element") 11 +@Inject(CommentService, "$scope")
13 export class CommentsComponent { 12 export class CommentsComponent {
14 13
15 comments: noosfero.CommentViewModel[] = []; 14 comments: noosfero.CommentViewModel[] = [];
@@ -22,7 +21,7 @@ export class CommentsComponent { @@ -22,7 +21,7 @@ export class CommentsComponent {
22 21
23 newComment = <noosfero.Comment>{}; 22 newComment = <noosfero.Comment>{};
24 23
25 - constructor(protected commentService: CommentService, private $scope: ng.IScope) { } 24 + constructor(public commentService: CommentService, private $scope: ng.IScope) { }
26 25
27 ngOnInit() { 26 ngOnInit() {
28 if (this.parent) { 27 if (this.parent) {
@@ -30,20 +29,27 @@ export class CommentsComponent { @@ -30,20 +29,27 @@ export class CommentsComponent {
30 } else { 29 } else {
31 this.loadNextPage(); 30 this.loadNextPage();
32 } 31 }
  32 +
  33 + this.commentService.addEvent<noosfero.Comment>({
  34 + event: 'onSave',
  35 + component: 'CommentsComponent',
  36 + callback: (comment: noosfero.Comment) => {
  37 +
  38 + if (this.commentService.called !== <string>comment.id.toString()) {
  39 +
  40 + this.commentAdded(comment);
  41 + this.commentService.called = comment.id.toString();
  42 + }
  43 + }
  44 + });
  45 +
33 } 46 }
34 47
35 - commentAdded(comment: noosfero.Comment): void { 48 + commentAdded(comment: noosfero.CommentViewModel): void {
  49 + comment.__show_reply = false;
36 this.comments.push(comment); 50 this.comments.push(comment);
37 this.resetShowReply(); 51 this.resetShowReply();
38 - }  
39 -  
40 - private resetShowReply() {  
41 - this.comments.forEach((comment: noosfero.CommentViewModel) => {  
42 - comment.__show_reply = false;  
43 - });  
44 - if (this.parent) {  
45 - this.parent.__show_reply = false;  
46 - } 52 + this.$scope.$apply();
47 } 53 }
48 54
49 loadComments() { 55 loadComments() {
@@ -62,4 +68,13 @@ export class CommentsComponent { @@ -62,4 +68,13 @@ export class CommentsComponent {
62 let pages = Math.ceil(this.total / this.perPage); 68 let pages = Math.ceil(this.total / this.perPage);
63 return !this.parent && pages >= this.page; 69 return !this.parent && pages >= this.page;
64 } 70 }
  71 +
  72 + private resetShowReply() {
  73 + this.comments.forEach((comment: noosfero.CommentViewModel) => {
  74 + comment.__show_reply = false;
  75 + });
  76 + if (this.parent) {
  77 + this.parent.__show_reply = false;
  78 + }
  79 + }
65 } 80 }
src/app/article/comment/comments.html
1 <div class="comments"> 1 <div class="comments">
2 - <noosfero-post-comment (comment-saved)="ctrl.commentAdded($event.detail)" ng-if="ctrl.showForm" [article]="ctrl.article" [parent]="ctrl.parent" [comment]="ctrl.newComment"></noosfero-post-comment>  
3 - 2 + <noosfero-post-comment ng-if="ctrl.showForm" [article]="ctrl.article" [parent]="ctrl.parent" [comment]="ctrl.newComment"></noosfero-post-comment>
  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>
6 </div> 6 </div>
src/app/article/comment/post-comment/post-comment.component.spec.ts
@@ -11,7 +11,8 @@ describe(&quot;Components&quot;, () =&gt; { @@ -11,7 +11,8 @@ describe(&quot;Components&quot;, () =&gt; {
11 11
12 beforeEach(angular.mock.module("templates")); 12 beforeEach(angular.mock.module("templates"));
13 13
14 - let commentService = jasmine.createSpyObj("commentService", ["createInArticle"]); 14 + let commentService = helpers.mocks.commentService;
  15 + commentService.emitEvent = jasmine.createSpy("emitEvent");
15 let user = {}; 16 let user = {};
16 let providers = [ 17 let providers = [
17 new Provider('CommentService', { useValue: commentService }), 18 new Provider('CommentService', { useValue: commentService }),
@@ -43,10 +44,9 @@ describe(&quot;Components&quot;, () =&gt; { @@ -43,10 +44,9 @@ describe(&quot;Components&quot;, () =&gt; {
43 it("emit an event when create comment", done => { 44 it("emit an event when create comment", done => {
44 helpers.createComponentFromClass(ContainerComponent).then(fixture => { 45 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
45 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance; 46 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
46 - component.commentSaved.next = jasmine.createSpy("next");  
47 commentService.createInArticle = jasmine.createSpy("createInArticle").and.returnValue(helpers.mocks.promiseResultTemplate({ data: {} })); 47 commentService.createInArticle = jasmine.createSpy("createInArticle").and.returnValue(helpers.mocks.promiseResultTemplate({ data: {} }));
48 component.save(); 48 component.save();
49 - expect(component.commentSaved.next).toHaveBeenCalled(); 49 + expect(component.commentService.emitEvent).toHaveBeenCalled();
50 done(); 50 done();
51 }); 51 });
52 }); 52 });
src/app/article/comment/post-comment/post-comment.component.ts
  1 +import {ngClass} from 'ng-forward/cjs/testing/test-component-builder';
1 import { Inject, Input, Output, EventEmitter, Component } from 'ng-forward'; 2 import { Inject, Input, Output, EventEmitter, Component } from 'ng-forward';
2 import { CommentService } from "../../../../lib/ng-noosfero-api/http/comment.service"; 3 import { CommentService } from "../../../../lib/ng-noosfero-api/http/comment.service";
3 import { NotificationService } from "../../../shared/services/notification.service"; 4 import { NotificationService } from "../../../shared/services/notification.service";
@@ -17,11 +18,12 @@ export class PostCommentComponent { @@ -17,11 +18,12 @@ export class PostCommentComponent {
17 18
18 @Input() article: noosfero.Article; 19 @Input() article: noosfero.Article;
19 @Input() parent: noosfero.Comment; 20 @Input() parent: noosfero.Comment;
20 - @Output() commentSaved: EventEmitter<Comment> = new EventEmitter<Comment>();  
21 @Input() comment = <noosfero.Comment>{}; 21 @Input() comment = <noosfero.Comment>{};
  22 + @Input() identifier: any;
22 private currentUser: noosfero.User; 23 private currentUser: noosfero.User;
23 24
24 - constructor(private commentService: CommentService, 25 + constructor(
  26 + public commentService: CommentService,
25 private notificationService: NotificationService, 27 private notificationService: NotificationService,
26 private session: SessionService) { 28 private session: SessionService) {
27 this.currentUser = this.session.currentUser(); 29 this.currentUser = this.session.currentUser();
@@ -32,7 +34,22 @@ export class PostCommentComponent { @@ -32,7 +34,22 @@ export class PostCommentComponent {
32 this.comment.reply_of_id = this.parent.id; 34 this.comment.reply_of_id = this.parent.id;
33 } 35 }
34 this.commentService.createInArticle(this.article, this.comment).then((result: noosfero.RestResult<noosfero.Comment>) => { 36 this.commentService.createInArticle(this.article, this.comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
35 - this.commentSaved.next(result.data); 37 +
  38 + if (this.identifier) {
  39 + this.commentService.emitEvent({
  40 + id: this.identifier,
  41 + event: 'onSave',
  42 + param: result.data
  43 + });
  44 + } else {
  45 + this.commentService.emitEvent({
  46 + id: result.data.id,
  47 + component: 'CommentsComponent',
  48 + event: 'onSave',
  49 + param: result.data
  50 + });
  51 + }
  52 +
36 this.comment.body = ""; 53 this.comment.body = "";
37 this.notificationService.success({ title: "comment.post.success.title", message: "comment.post.success.message" }); 54 this.notificationService.success({ title: "comment.post.success.title", message: "comment.post.success.message" });
38 }); 55 });
src/lib/ng-noosfero-api/decorators/mixins.ts 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +export function Mixins(...mixins: Function[]) {
  2 + return function(target: Function) {
  3 + mixins.forEach(mixin => {
  4 + Object.getOwnPropertyNames(mixin.prototype).forEach(name => {
  5 + target.prototype[name] = mixin.prototype[name];
  6 + });
  7 + });
  8 + };
  9 +}
src/lib/ng-noosfero-api/http/comment.service.ts
1 -import { Injectable, Inject } from "ng-forward"; 1 +import { Injectable, Inject, EventEmitter } from "ng-forward";
2 import {RestangularService} from "./restangular_service"; 2 import {RestangularService} from "./restangular_service";
3 import {ArticleService} from "./article.service"; 3 import {ArticleService} from "./article.service";
  4 +import {Mixins, EventService, IEvent} from '../mixins/event-service.mixin';
  5 +
4 6
5 @Injectable() 7 @Injectable()
  8 +@Mixins(EventService)
6 @Inject("Restangular", "$q", "$log", ArticleService) 9 @Inject("Restangular", "$q", "$log", ArticleService)
7 -export class CommentService extends RestangularService<noosfero.Comment> { 10 +export class CommentService extends RestangularService<noosfero.Comment> implements EventService {
  11 +
  12 + events: IEvent[] = [];
  13 +
  14 + called: string;
8 15
9 constructor(Restangular: restangular.IService, $q: ng.IQService, $log: ng.ILogService, protected articleService: ArticleService) { 16 constructor(Restangular: restangular.IService, $q: ng.IQService, $log: ng.ILogService, protected articleService: ArticleService) {
10 super(Restangular, $q, $log); 17 super(Restangular, $q, $log);
@@ -31,4 +38,9 @@ export class CommentService extends RestangularService&lt;noosfero.Comment&gt; { @@ -31,4 +38,9 @@ export class CommentService extends RestangularService&lt;noosfero.Comment&gt; {
31 let articleElement = this.articleService.getElement(<number>article.id); 38 let articleElement = this.articleService.getElement(<number>article.id);
32 return this.create(comment, articleElement, null, { 'Content-Type': 'application/json' }, false); 39 return this.create(comment, articleElement, null, { 'Content-Type': 'application/json' }, false);
33 } 40 }
  41 +
  42 + // Mixin "EventService" declarations
  43 + addEvent: <T>(data: { event: string, callback: Function, id?: any, component?: string, scope?: any }) => void;
  44 + getEvents: (data: { event: string, id?: any, component?: string }) => void;
  45 + emitEvent: <T>(data: { event: string, param: T, id?: any, component?: string }) => void;
34 } 46 }
src/lib/ng-noosfero-api/mixins/event-service.mixin.ts 0 → 100644
@@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
  1 +import { EventEmitter } from "ng-forward";
  2 +export {Mixins} from "../decorators/mixins";
  3 +
  4 +export interface IEvent {
  5 + id: any;
  6 + component: string;
  7 + emitters: {
  8 + onSave?: EventEmitter<noosfero.Comment>
  9 + };
  10 +}
  11 +
  12 +/**
  13 + * @ngdoc object
  14 + * @name mixins.EventService
  15 + * @see Typescript official documentation https://www.typescriptlang.org/docs/mixins.html
  16 + * @description
  17 + *
  18 + * A mixin class to be implemented by another class (e.g. Angular Services)
  19 + * to emit's and subscribe events
  20 + *
  21 + * <pre>
  22 + * @Mixins(EventService)
  23 + * export class MyService implements EventService {
  24 + *
  25 + * }
  26 + * </pre>
  27 + */
  28 +export class EventService {
  29 +
  30 + events: IEvent[] = [];
  31 +
  32 + called: string;
  33 +
  34 + addEvent<T>(data: { event: string, callback: Function, id?: any, component?: string, scope?: any }) {
  35 +
  36 + let hasEvent = false;
  37 +
  38 + if (this.events.length > 0) {
  39 +
  40 + this.events.forEach((eventData: IEvent, index: number) => {
  41 + if (data.id === eventData.id) {
  42 +
  43 + if (!(<any>this.events)[index].emitters[data.event]) {
  44 + (<any>this.events)[index].emitters[data.event] = new EventEmitter();
  45 + } else {
  46 + (<EventEmitter<T>>(<any>this.events)[index].emitters[data.event]).subscribe(data.callback.bind(data.scope || this));
  47 + }
  48 +
  49 + return (hasEvent = true);
  50 + }
  51 + });
  52 + }
  53 +
  54 + if (!hasEvent) {
  55 +
  56 + let newEvent: IEvent = {
  57 + id: data.id,
  58 + component: data.component,
  59 + emitters: <any>{}
  60 + };
  61 +
  62 + (<any>newEvent.emitters)[data.event] = <EventEmitter<T>>new EventEmitter();
  63 + (<any>newEvent.emitters)[data.event].subscribe(data.callback);
  64 +
  65 + this.events.push(newEvent);
  66 + }
  67 + }
  68 +
  69 + getEvents(data: { event: string, id?: any, component?: string }): any {
  70 + let result: any = {};
  71 +
  72 + for (let i = 0; i < this.events.length; i++) {
  73 + if (data.id === (<Array<IEvent>>this.events)[i].id && !data.component) {
  74 +
  75 + result = (<any>this.events)[i].emitters[data.event];
  76 + break;
  77 + } else if (data.component === (<any>this.events)[i].component) {
  78 + result[data.component] = (<any>this.events)[i].emitters[data.event];
  79 +
  80 + break;
  81 + } else {
  82 + result[(<any>this.events)[i].component] = (<any>this.events)[i].emitters[data.event];
  83 + }
  84 + }
  85 +
  86 + return result;
  87 + }
  88 +
  89 + emitEvent<T>(data: { event: string, param: T, id?: any, component?: string }) {
  90 +
  91 + let eventOrEmitters = this.getEvents(data);
  92 +
  93 + if (eventOrEmitters instanceof EventEmitter) {
  94 +
  95 + eventOrEmitters.next(data.param);
  96 + } else {
  97 +
  98 + Object.keys(eventOrEmitters).forEach((emitter: string) => {
  99 + (<EventEmitter<T>>eventOrEmitters[emitter]).next(data.param);
  100 + });
  101 +
  102 + }
  103 + }
  104 +}
src/plugins/comment_paragraph/allow-comment/allow-comment.component.spec.ts
@@ -24,7 +24,8 @@ describe(&quot;Components&quot;, () =&gt; { @@ -24,7 +24,8 @@ describe(&quot;Components&quot;, () =&gt; {
24 24
25 let providers = [ 25 let providers = [
26 new Provider('CommentParagraphService', { useValue: serviceMock }), 26 new Provider('CommentParagraphService', { useValue: serviceMock }),
27 - new Provider('CommentParagraphEventService', { useValue: eventServiceMock }) 27 + new Provider('CommentParagraphEventService', { useValue: eventServiceMock }),
  28 + new Provider('CommentService', { useValue: helpers.mocks.commentService })
28 ]; 29 ];
29 let helper: ComponentTestHelper<AllowCommentComponent>; 30 let helper: ComponentTestHelper<AllowCommentComponent>;
30 31
src/plugins/comment_paragraph/allow-comment/allow-comment.component.ts
1 -import {Component, Input, Inject} from "ng-forward"; 1 +import {Component, Input, Inject, bundleStore} from "ng-forward";
2 import {SideCommentsComponent} from "../side-comments/side-comments.component"; 2 import {SideCommentsComponent} from "../side-comments/side-comments.component";
3 import {CommentParagraphEventService} from "../events/comment-paragraph-event.service"; 3 import {CommentParagraphEventService} from "../events/comment-paragraph-event.service";
4 import {CommentParagraphService} from "../http/comment-paragraph.service"; 4 import {CommentParagraphService} from "../http/comment-paragraph.service";
  5 +import {CommentService} from "../../../lib/ng-noosfero-api/http/comment.service";
  6 +import {PostCommentComponent} from '../../../app/article/comment/post-comment/post-comment.component';
5 7
6 @Component({ 8 @Component({
7 selector: "comment-paragraph-plugin-allow-comment", 9 selector: "comment-paragraph-plugin-allow-comment",
8 templateUrl: "plugins/comment_paragraph/allow-comment/allow-comment.html", 10 templateUrl: "plugins/comment_paragraph/allow-comment/allow-comment.html",
9 directives: [SideCommentsComponent] 11 directives: [SideCommentsComponent]
10 }) 12 })
11 -@Inject("$scope", CommentParagraphEventService, CommentParagraphService) 13 +@Inject("$scope", CommentParagraphEventService, CommentParagraphService, CommentService)
12 export class AllowCommentComponent { 14 export class AllowCommentComponent {
13 15
14 @Input() content: string; 16 @Input() content: string;
15 @Input() paragraphUuid: string; 17 @Input() paragraphUuid: string;
16 @Input() article: noosfero.Article; 18 @Input() article: noosfero.Article;
17 - commentsCount: number; 19 + commentsCount: number = 0;
18 display = false; 20 display = false;
19 21
20 - constructor(private $scope: ng.IScope, 22 + constructor(
  23 + private $scope: ng.IScope,
21 private commentParagraphEventService: CommentParagraphEventService, 24 private commentParagraphEventService: CommentParagraphEventService,
22 - private commentParagraphService: CommentParagraphService) { } 25 + private commentParagraphService: CommentParagraphService,
  26 + private commentService: CommentService
  27 + ) { }
23 28
24 ngOnInit() { 29 ngOnInit() {
25 this.commentParagraphEventService.subscribeToggleCommentParagraph((article: noosfero.Article) => { 30 this.commentParagraphEventService.subscribeToggleCommentParagraph((article: noosfero.Article) => {
@@ -29,6 +34,20 @@ export class AllowCommentComponent { @@ -29,6 +34,20 @@ export class AllowCommentComponent {
29 this.commentParagraphService.commentParagraphCount(this.article, this.paragraphUuid).then((count: number) => { 34 this.commentParagraphService.commentParagraphCount(this.article, this.paragraphUuid).then((count: number) => {
30 this.commentsCount = count; 35 this.commentsCount = count;
31 }); 36 });
  37 +
  38 + this.commentService.addEvent<noosfero.Comment>({
  39 + id: this.paragraphUuid,
  40 + event: 'onSave',
  41 + component: 'SideCommentsComponent',
  42 + scope: this,
  43 + callback: () => {
  44 + if (!this.commentsCount) {
  45 + this.commentsCount = 0;
  46 + }
  47 + this.commentsCount++;
  48 + this.$scope.$apply();
  49 + }
  50 + });
32 } 51 }
33 52
34 isActivated() { 53 isActivated() {
src/plugins/comment_paragraph/side-comments/side-comments.component.spec.ts
@@ -12,14 +12,9 @@ describe(&quot;Components&quot;, () =&gt; { @@ -12,14 +12,9 @@ describe(&quot;Components&quot;, () =&gt; {
12 let serviceMock = jasmine.createSpyObj("CommentParagraphService", ["getByArticle"]); 12 let serviceMock = jasmine.createSpyObj("CommentParagraphService", ["getByArticle"]);
13 serviceMock.getByArticle = jasmine.createSpy("getByArticle").and.returnValue(Promise.resolve({ data: {} })); 13 serviceMock.getByArticle = jasmine.createSpy("getByArticle").and.returnValue(Promise.resolve({ data: {} }));
14 14
15 - let commentServiceMock = {};  
16 - let postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["emit", "subscribe"]);  
17 - postCommentEventService.subscribe = jasmine.createSpy("subscribe");  
18 -  
19 let providers = [ 15 let providers = [
20 new Provider('CommentParagraphService', { useValue: serviceMock }), 16 new Provider('CommentParagraphService', { useValue: serviceMock }),
21 - new Provider('CommentService', { useValue: commentServiceMock }),  
22 - new Provider('PostCommentEventService', { useValue: postCommentEventService }) 17 + new Provider('CommentService', { useValue: helpers.mocks.commentService }),
23 ]; 18 ];
24 let helper: ComponentTestHelper<SideCommentsComponent>; 19 let helper: ComponentTestHelper<SideCommentsComponent>;
25 20
src/plugins/comment_paragraph/side-comments/side-comments.component.ts
@@ -5,7 +5,7 @@ import {CommentParagraphService} from &quot;../http/comment-paragraph.service&quot;; @@ -5,7 +5,7 @@ import {CommentParagraphService} from &quot;../http/comment-paragraph.service&quot;;
5 5
6 @Component({ 6 @Component({
7 selector: "comment-paragraph-side-comments", 7 selector: "comment-paragraph-side-comments",
8 - templateUrl: 'app/article/comment/comments.html', 8 + templateUrl: 'plugins/comment_paragraph/side-comments/side-comments.html',
9 }) 9 })
10 @Inject(CommentService, "$scope", CommentParagraphService) 10 @Inject(CommentService, "$scope", CommentParagraphService)
11 export class SideCommentsComponent extends CommentsComponent { 11 export class SideCommentsComponent extends CommentsComponent {
src/plugins/comment_paragraph/side-comments/side-comments.html 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<div class="comments">
  2 + <noosfero-post-comment ng-if="ctrl.showForm" [article]="ctrl.article" [parent]="ctrl.parent" [comment]="ctrl.newComment" [identifier]="ctrl.paragraphUuid"></noosfero-post-comment>
  3 +
  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>
  6 + </div>
  7 + <button type="button" ng-if="ctrl.displayMore()" class="more-comments btn btn-default btn-block" ng-click="ctrl.loadNextPage()">{{"comment.pagination.more" | translate}}</button>
  8 +</div>
src/spec/mocks.ts
@@ -122,9 +122,13 @@ export var mocks: any = { @@ -122,9 +122,13 @@ export var mocks: any = {
122 instant: () => { } 122 instant: () => { }
123 }, 123 },
124 commentService: { 124 commentService: {
  125 + events: <any[]>[],
  126 + called: <string>'',
125 getByArticle: (article: noosfero.Article) => { 127 getByArticle: (article: noosfero.Article) => {
126 return Promise.resolve({ data: {} }); 128 return Promise.resolve({ data: {} });
127 - } 129 + },
  130 + addEvent: () => { },
  131 + emitEvent: () => { }
128 }, 132 },
129 sessionWithCurrentUser: (user: any) => { 133 sessionWithCurrentUser: (user: any) => {
130 return { 134 return {