Commit 45e136413c812b5d1d447f75930635a6260d5621

Authored by ABNER SILVA DE OLIVEIRA
2 parents ea217b65 00882cc3

Merge branch 'comments'

src/app/article/article-default-view-component.spec.ts
... ... @@ -27,7 +27,8 @@ describe("Components", () => {
27 27 providers: [
28 28 helpers.createProviderToValue('CommentService', helpers.mocks.commentService),
29 29 helpers.provideFilters("translateFilter"),
30   - helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService)
  30 + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService),
  31 + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({}))
31 32 ]
32 33 })
33 34 class ArticleContainerComponent {
... ... @@ -64,7 +65,8 @@ describe("Components", () => {
64 65 providers: [
65 66 helpers.createProviderToValue('CommentService', helpers.mocks.commentService),
66 67 helpers.provideFilters("translateFilter"),
67   - helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService)
  68 + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService),
  69 + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({}))
68 70 ]
69 71 })
70 72 class ArticleContainerComponent {
... ...
src/app/article/comment/comment.component.spec.ts
1 1 import {Provider, provide, Component} from 'ng-forward';
2 2 import * as helpers from "../../../spec/helpers";
3   -
4 3 import {CommentComponent} from './comment.component';
5 4  
6 5 const htmlTemplate: string = '<noosfero-comment [article]="ctrl.article" [comment]="ctrl.comment"></noosfero-comment>';
... ... @@ -10,35 +9,48 @@ describe(&quot;Components&quot;, () =&gt; {
10 9  
11 10 beforeEach(angular.mock.module("templates"));
12 11  
13   - @Component({ selector: 'test-container-component', directives: [CommentComponent], template: htmlTemplate, providers: helpers.provideFilters("translateFilter") })
14   - class ContainerComponent {
15   - article = { id: 1 };
16   - comment = { title: "title", body: "body" };
  12 +
  13 + function createComponent() {
  14 + let providers = helpers.provideFilters("translateFilter");
  15 +
  16 + @Component({ selector: 'test-container-component', directives: [CommentComponent], template: htmlTemplate, providers: providers })
  17 + class ContainerComponent {
  18 + article = { id: 1 };
  19 + comment = { title: "title", body: "body" };
  20 + }
  21 + return helpers.createComponentFromClass(ContainerComponent);
17 22 }
18 23  
19 24 it("render a comment", done => {
20   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  25 + createComponent().then(fixture => {
21 26 expect(fixture.debugElement.queryAll(".comment").length).toEqual(1);
22 27 done();
23 28 });
24 29 });
25 30  
26 31 it("not render a post comment tag in the beginning", done => {
27   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  32 + createComponent().then(fixture => {
28 33 expect(fixture.debugElement.queryAll("noosfero-post-comment").length).toEqual(0);
29 34 done();
30 35 });
31 36 });
32 37  
33   - it("render a post comment tag when click in reply", done => {
34   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  38 + it("set show reply to true when click reply", done => {
  39 + createComponent().then(fixture => {
35 40 let component: CommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
36 41 component.reply();
37   - fixture.debugElement.getLocal("$rootScope").$apply();
38   - expect(fixture.debugElement.queryAll("noosfero-post-comment").length).toEqual(1);
  42 + expect(component.showReply()).toBeTruthy("Reply was expected to be true");
39 43 done();
40 44 });
41 45 });
42 46  
  47 + it("show reply relies on current comment __showReply attribute", done => {
  48 + createComponent().then(fixture => {
  49 + let component = fixture.debugElement.componentViewChildren[0];
  50 + component.componentInstance.comment.__showReply = false;
  51 + expect(component.componentInstance.showReply()).toEqual(false);
  52 + done();
  53 + });
  54 + });
43 55 });
44 56 });
... ...
src/app/article/comment/comment.component.ts
1   -import { 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 3  
3 4 @Component({
4 5 selector: 'noosfero-comment',
... ... @@ -6,12 +7,18 @@ import { Input, Component } from &#39;ng-forward&#39;;
6 7 })
7 8 export class CommentComponent {
8 9  
9   - @Input() comment: noosfero.Comment;
  10 + @Input() comment: noosfero.CommentViewModel;
10 11 @Input() article: noosfero.Article;
11 12  
12   - showReply: boolean = false;
  13 + showReply() {
  14 + return this.comment && this.comment.__show_reply === true;
  15 + }
  16 +
  17 + constructor() {
  18 + }
  19 +
13 20  
14 21 reply() {
15   - this.showReply = true;
  22 + this.comment.__show_reply = !this.comment.__show_reply;
16 23 }
17 24 }
... ...
src/app/article/comment/comment.html
... ... @@ -10,16 +10,12 @@
10 10 <h4 class="media-heading">{{ctrl.comment.author.name}}</h4>
11 11 </a>
12 12 <span class="date" am-time-ago="ctrl.comment.created_at | dateFormat"></span>
13   - <a href="#" (click)="ctrl.reply()">
14   - <span class="pull-right small text-muted">
15   - {{"comment.reply" | translate}}
16   - </span>
17   - </a>
18 13 </div>
19 14 <div class="title">{{ctrl.comment.title}}</div>
20 15 <div class="body">{{ctrl.comment.body}}</div>
  16 + <a href="#" (click)="ctrl.reply()" class="small text-muted">
  17 + {{"comment.reply" | translate}}
  18 + </a>
21 19 </div>
22   -
23   - <noosfero-post-comment ng-if="ctrl.showReply" [article]="ctrl.article" [reply-of]="ctrl.comment"></noosfero-post-comment>
24   -
  20 + <noosfero-comments [show-form]="ctrl.showReply()" [article]="ctrl.article" [parent]="ctrl.comment"></noosfero-comments>
25 21 </div>
... ...
src/app/article/comment/comment.scss
... ... @@ -13,8 +13,7 @@
13 13 min-width: 40px;
14 14 }
15 15 .media-body {
16   - background-color: #F9F9F9;
17   - padding: 10px;
  16 + padding: 0 10px 10px 10px;
18 17 }
19 18 noosfero-profile-image {
20 19 img {
... ... @@ -28,5 +27,8 @@
28 27 font-size: 1.7em;
29 28 }
30 29 }
  30 + .comments {
  31 + margin-left: 30px;
  32 + }
31 33 }
32 34 }
... ...
src/app/article/comment/comments.component.spec.ts
... ... @@ -17,38 +17,71 @@ describe(&quot;Components&quot;, () =&gt; {
17 17 commentService.getByArticle = jasmine.createSpy("getByArticle")
18 18 .and.returnValue(helpers.mocks.promiseResultTemplate({ data: comments }));
19 19  
20   - let providers = [
21   - new Provider('CommentService', { useValue: commentService }),
22   - new Provider('NotificationService', { useValue: helpers.mocks.notificationService })
23   - ].concat(helpers.provideFilters("translateFilter"));
24   -
25   - @Component({ selector: 'test-container-component', directives: [CommentsComponent], template: htmlTemplate, providers: providers })
26   - class ContainerComponent {
27   - article = { id: 1 };
  20 + let properties = { article: { id: 1 }, parent: <any>null };
  21 + function createComponent() {
  22 + // postCommentEventService = jasmine.createSpyObj("postCommentEventService", ["subscribe"]);
  23 + let providers = [
  24 + helpers.createProviderToValue('CommentService', commentService),
  25 + helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService),
  26 + helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({}))
  27 + ].concat(helpers.provideFilters("translateFilter"));
  28 +
  29 + return helpers.quickCreateComponent({
  30 + providers: providers,
  31 + directives: [CommentsComponent],
  32 + template: htmlTemplate,
  33 + properties: properties
  34 + });
28 35 }
29 36  
  37 +
30 38 it("render comments associated to an article", done => {
31   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  39 + createComponent().then(fixture => {
32 40 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(2);
33 41 done();
34 42 });
35 43 });
36 44  
37 45 it("render a post comment tag", done => {
38   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
  46 + createComponent().then(fixture => {
39 47 expect(fixture.debugElement.queryAll("noosfero-post-comment").length).toEqual(1);
40 48 done();
41 49 });
42 50 });
43 51  
44   - it("update comments list when receive an event", done => {
45   - helpers.createComponentFromClass(ContainerComponent).then(fixture => {
46   - fixture.debugElement.getLocal("$rootScope").$emit(PostCommentComponent.EVENT_COMMENT_RECEIVED, { id: 1 });
47   - fixture.debugElement.getLocal("$rootScope").$apply();
  52 + it("update comments list when receive an reply", done => {
  53 + properties.parent = { id: 3 };
  54 + createComponent().then(fixture => {
  55 + (<CommentsComponent>fixture.debugElement.componentViewChildren[0].componentInstance).commentAdded(<noosfero.Comment>{ id: 1, reply_of: { id: 3 } });
  56 + fixture.detectChanges();
48 57 expect(fixture.debugElement.queryAll("noosfero-comment").length).toEqual(3);
49 58 done();
50 59 });
51 60 });
52 61  
  62 + it("load comments for next page", done => {
  63 + createComponent().then(fixture => {
  64 + let headers = jasmine.createSpy("headers").and.returnValue(3);
  65 + commentService.getByArticle = jasmine.createSpy("getByArticle")
  66 + .and.returnValue(helpers.mocks.promiseResultTemplate({ data: { id: 4 }, headers: headers }));
  67 + let component: CommentsComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  68 + component.loadNextPage();
  69 + expect(component['page']).toEqual(3);
  70 + expect(component.comments.length).toEqual(3);
  71 + expect(component['total']).toEqual(3);
  72 + done();
  73 + });
  74 + });
  75 +
  76 + it("not display more when there is no more comments to load", done => {
  77 + createComponent().then(fixture => {
  78 + let component: CommentsComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  79 + component['total'] = 0;
  80 + component.parent = null;
  81 + expect(component.displayMore()).toBeFalsy();
  82 + done();
  83 + });
  84 + });
  85 +
53 86 });
54 87 });
... ...
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 5 import { PostCommentComponent } from "./post-comment/post-comment.component";
3 6 import { CommentService } from "../../../lib/ng-noosfero-api/http/comment.service";
4 7 import { CommentComponent } from "./comment.component";
... ... @@ -6,23 +9,59 @@ import { CommentComponent } from &quot;./comment.component&quot;;
6 9 @Component({
7 10 selector: 'noosfero-comments',
8 11 templateUrl: 'app/article/comment/comments.html',
9   - directives: [PostCommentComponent, CommentComponent]
  12 + directives: [PostCommentComponent, CommentComponent],
  13 + outputs: ['commentAdded']
10 14 })
11   -@Inject(CommentService, "$rootScope")
  15 +@Inject(CommentService, "$element")
12 16 export class CommentsComponent {
13 17  
14   - comments: noosfero.Comment[] = [];
  18 + comments: noosfero.CommentViewModel[] = [];
  19 + @Input() showForm = true;
15 20 @Input() article: noosfero.Article;
  21 + @Input() parent: noosfero.CommentViewModel;
  22 +
  23 + protected page = 1;
  24 + protected perPage = 5;
  25 + protected total = 0;
  26 +
  27 + constructor(protected commentService: CommentService) { }
  28 +
  29 + ngOnInit() {
  30 + if (this.parent) {
  31 + this.comments = this.parent.replies;
  32 + } else {
  33 + this.loadNextPage();
  34 + }
  35 + }
16 36  
17   - constructor(private commentService: CommentService, private $rootScope: ng.IScope) {
18   - $rootScope.$on(PostCommentComponent.EVENT_COMMENT_RECEIVED, (event: ng.IAngularEvent, comment: noosfero.Comment) => {
19   - this.comments.push(comment);
  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;
20 45 });
  46 + if (this.parent) {
  47 + this.parent.__show_reply = false;
  48 + }
21 49 }
22 50  
23   - ngOnInit() {
24   - this.commentService.getByArticle(this.article).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
25   - this.comments = result.data;
  51 + loadComments() {
  52 + return this.commentService.getByArticle(this.article, { page: this.page, per_page: this.perPage });
  53 + }
  54 +
  55 + loadNextPage() {
  56 + this.loadComments().then((result: noosfero.RestResult<noosfero.Comment[]>) => {
  57 + this.comments = this.comments.concat(result.data);
  58 + this.total = result.headers ? result.headers("total") : this.comments.length;
  59 + this.page++;
26 60 });
27 61 }
  62 +
  63 + displayMore() {
  64 + let pages = Math.ceil(this.total / this.perPage);
  65 + return !this.parent && pages >= this.page;
  66 + }
28 67 }
... ...
src/app/article/comment/comments.html
1 1 <div class="comments">
2   - <noosfero-post-comment [article]="ctrl.article"></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 4 <div class="comments-list">
5   - <noosfero-comment ng-repeat="comment in ctrl.comments" [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 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>
7 8 </div>
... ...
src/app/article/comment/post-comment/post-comment.component.spec.ts
1 1 import {Provider, provide, Component} from 'ng-forward';
2 2 import * as helpers from "../../../../spec/helpers";
3   -
4 3 import {PostCommentComponent} from './post-comment.component';
5 4  
6 5 const htmlTemplate: string = '<noosfero-post-comment [article]="ctrl.article" [reply-of]="ctrl.comment"></noosfero-post-comment>';
... ... @@ -11,9 +10,11 @@ describe(&quot;Components&quot;, () =&gt; {
11 10 beforeEach(angular.mock.module("templates"));
12 11  
13 12 let commentService = jasmine.createSpyObj("commentService", ["createInArticle"]);
  13 + let user = {};
14 14 let providers = [
15 15 new Provider('CommentService', { useValue: commentService }),
16   - new Provider('NotificationService', { useValue: helpers.mocks.notificationService })
  16 + new Provider('NotificationService', { useValue: helpers.mocks.notificationService }),
  17 + new Provider('SessionService', { useValue: helpers.mocks.sessionWithCurrentUser(user) })
17 18 ].concat(helpers.provideFilters("translateFilter"));
18 19  
19 20 @Component({ selector: 'test-container-component', directives: [PostCommentComponent], template: htmlTemplate, providers: providers })
... ... @@ -32,10 +33,10 @@ describe(&quot;Components&quot;, () =&gt; {
32 33 it("emit an event when create comment", done => {
33 34 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
34 35 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
  36 + component.commentSaved.next = jasmine.createSpy("next");
35 37 commentService.createInArticle = jasmine.createSpy("createInArticle").and.returnValue(helpers.mocks.promiseResultTemplate({ data: {} }));
36   - component["$rootScope"].$emit = jasmine.createSpy("$emit");
37 38 component.save();
38   - expect(component["$rootScope"].$emit).toHaveBeenCalledWith(PostCommentComponent.EVENT_COMMENT_RECEIVED, jasmine.any(Object));
  39 + expect(component.commentSaved.next).toHaveBeenCalled();
39 40 done();
40 41 });
41 42 });
... ... @@ -55,9 +56,9 @@ describe(&quot;Components&quot;, () =&gt; {
55 56 helpers.createComponentFromClass(ContainerComponent).then(fixture => {
56 57 let component: PostCommentComponent = fixture.debugElement.componentViewChildren[0].componentInstance;
57 58 component.comment = <any>{ reply_of_id: null };
58   - component.replyOf = <any>{ id: 10 };
  59 + component.parent = <any>{ id: 10 };
59 60 component.save();
60   - expect(component.comment.reply_of_id).toEqual(component.replyOf.id);
  61 + expect(component.comment.reply_of_id).toEqual(component.parent.id);
61 62 done();
62 63 });
63 64 });
... ...
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 2 import { CommentService } from "../../../../lib/ng-noosfero-api/http/comment.service";
3 3 import { NotificationService } from "../../../shared/services/notification.service";
  4 +import { SessionService } from "../../../login";
4 5  
5 6 @Component({
6 7 selector: 'noosfero-post-comment',
7   - templateUrl: 'app/article/comment/post-comment/post-comment.html'
  8 + templateUrl: 'app/article/comment/post-comment/post-comment.html',
  9 + outputs: ['commentSaved']
8 10 })
9   -@Inject(CommentService, NotificationService, "$rootScope")
  11 +@Inject(CommentService, NotificationService, SessionService)
10 12 export class PostCommentComponent {
11 13  
12   - public static EVENT_COMMENT_RECEIVED = "comment.received";
13   -
14 14 @Input() article: noosfero.Article;
15   - @Input() replyOf: noosfero.Comment;
  15 + @Input() parent: noosfero.Comment;
  16 + @Output() commentSaved: EventEmitter<Comment> = new EventEmitter<Comment>();
16 17  
17   - comment: noosfero.Comment;
  18 + comment = <noosfero.Comment>{};
  19 + private currentUser: noosfero.User;
18 20  
19   - constructor(private commentService: CommentService, private notificationService: NotificationService, private $rootScope: ng.IScope) { }
  21 + constructor(private commentService: CommentService,
  22 + private notificationService: NotificationService,
  23 + private session: SessionService) {
  24 + this.currentUser = this.session.currentUser();
  25 + }
20 26  
21 27 save() {
22   - if (this.replyOf && this.comment) {
23   - this.comment.reply_of_id = this.replyOf.id;
  28 + if (this.parent && this.comment) {
  29 + this.comment.reply_of_id = this.parent.id;
24 30 }
25 31 this.commentService.createInArticle(this.article, this.comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
26   - this.$rootScope.$emit(PostCommentComponent.EVENT_COMMENT_RECEIVED, result.data);
27   - this.notificationService.success({ title: "Good job!", message: "Comment saved!" });
  32 + this.commentSaved.next(result.data);
  33 + this.comment.body = "";
  34 + this.notificationService.success({ title: "comment.post.success.title", message: "comment.post.success.message" });
28 35 });
29 36 }
30 37 }
... ...
src/app/article/comment/post-comment/post-comment.html
1   -<form>
  1 +<form class="clearfix post-comment">
2 2 <div class="form-group">
3   - <textarea class="form-control custom-control" rows="3" ng-model="ctrl.comment.body"></textarea>
  3 + <div class="comment media">
  4 + <div class="media-left">
  5 + <a ui-sref="main.profile.home({profile: ctrl.currentUser.person.identifier})">
  6 + <noosfero-profile-image [profile]="ctrl.currentUser.person"></noosfero-profile-image>
  7 + </a>
  8 + </div>
  9 + <div class="media-body">
  10 + <textarea class="form-control custom-control" rows="1" ng-model="ctrl.comment.body" placeholder="{{'comment.post.placeholder' | translate}}"></textarea>
  11 + <button ng-show="ctrl.comment.body" type="submit" class="btn btn-default pull-right ng-hide" ng-click="ctrl.save()">{{"comment.post" | translate}}</button>
  12 + </div>
  13 + </div>
4 14 </div>
5   - <button type="submit" class="btn btn-default" ng-click="ctrl.save()">{{"comment.post" | translate}}</button>
6 15 </form>
... ...
src/app/article/comment/post-comment/post-comment.scss 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +.comments {
  2 + .post-comment {
  3 + .media {
  4 + border-top: 2px solid #F3F3F3;
  5 + padding-top: 10px;
  6 + .media-left {
  7 + padding: 10px 0;
  8 + }
  9 + button {
  10 + margin-top: 10px;
  11 + &.ng-hide-add {
  12 + animation: 0.5s lightSpeedOut ease;
  13 + }
  14 + &.ng-hide-remove {
  15 + animation: 0.5s lightSpeedIn ease;
  16 + }
  17 + }
  18 + }
  19 + }
  20 +}
... ...
src/app/shared/services/notification.service.ts
... ... @@ -20,13 +20,7 @@ export class NotificationService {
20 20 title = NotificationService.DEFAULT_ERROR_TITLE,
21 21 showConfirmButton = true
22 22 } = {}) {
23   - this.$log.debug("Notification error:", title, message, this.translatorService.currentLanguage());
24   - this.SweetAlert.swal({
25   - title: this.translatorService.translate(title),
26   - text: this.translatorService.translate(message),
27   - type: "error",
28   - showConfirmButton: showConfirmButton
29   - });
  23 + this.showMessage({ title: title, text: message, showConfirmButton: showConfirmButton, type: "error" });
30 24 }
31 25  
32 26 httpError(status: number, data: any): boolean {
... ... @@ -39,11 +33,17 @@ export class NotificationService {
39 33 message,
40 34 timer = NotificationService.DEFAULT_SUCCESS_TIMER
41 35 }) {
  36 + this.showMessage({ title: title, text: message, timer: timer });
  37 + }
  38 +
  39 + private showMessage({title, text, type = "success", timer = null, showConfirmButton = true}) {
  40 + this.$log.debug("Notification message:", title, text, type, this.translatorService.currentLanguage());
42 41 this.SweetAlert.swal({
43   - title: title,
44   - text: message,
45   - type: "success",
46   - timer: timer
  42 + title: this.translatorService.translate(title),
  43 + text: this.translatorService.translate(text),
  44 + type: type,
  45 + timer: timer,
  46 + showConfirmButton: showConfirmButton
47 47 });
48 48 }
49 49  
... ...
src/languages/en.json
... ... @@ -31,5 +31,9 @@
31 31 "notification.http_error.401.message": "Unauthorized",
32 32 "notification.http_error.500.message": "Server error",
33 33 "comment.post": "Post a comment",
  34 + "comment.post.placeholder": "Join the discussion...",
  35 + "comment.pagination.more": "More",
  36 + "comment.post.success.title": "Good job!",
  37 + "comment.post.success.message": "Comment saved!",
34 38 "comment.reply": "reply"
35 39 }
... ...
src/languages/pt.json
... ... @@ -31,5 +31,9 @@
31 31 "notification.http_error.401.message": "Não autorizado",
32 32 "notification.http_error.500.message": "Erro no servidor",
33 33 "comment.post": "Commentar",
  34 + "comment.post.placeholder": "Participe da discussão...",
  35 + "comment.pagination.more": "Mais",
  36 + "comment.post.success.title": "Bom trabalho!",
  37 + "comment.post.success.message": "Comentário salvo com sucesso!",
34 38 "comment.reply": "responder"
35 39 }
... ...
src/lib/ng-noosfero-api/http/comment.service.spec.ts
... ... @@ -22,8 +22,8 @@ describe(&quot;Services&quot;, () =&gt; {
22 22  
23 23 it("should return comments by article", (done) => {
24 24 let articleId = 1;
25   - $httpBackend.expectGET(`/api/v1/articles/${articleId}/comments`).respond(200, { comments: [{ name: "comment1" }] });
26   - commentService.getByArticle(<noosfero.Article>{id: articleId}).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
  25 + $httpBackend.expectGET(`/api/v1/articles/${articleId}/comments?without_reply=true`).respond(200, { comments: [{ name: "comment1" }] });
  26 + commentService.getByArticle(<noosfero.Article>{ id: articleId }).then((result: noosfero.RestResult<noosfero.Comment[]>) => {
27 27 expect(result.data).toEqual([{ name: "comment1" }]);
28 28 done();
29 29 });
... ... @@ -32,9 +32,9 @@ describe(&quot;Services&quot;, () =&gt; {
32 32  
33 33 it("should create a comment in an article", (done) => {
34 34 let articleId = 1;
35   - let comment: noosfero.Comment = <any>{ id: null};
36   - $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comments`, comment ).respond(200, {comment: { id: 2 }});
37   - commentService.createInArticle(<noosfero.Article>{id: articleId}, comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
  35 + let comment: noosfero.Comment = <any>{ id: null };
  36 + $httpBackend.expectPOST(`/api/v1/articles/${articleId}/comments`, comment).respond(200, { comment: { id: 2 } });
  37 + commentService.createInArticle(<noosfero.Article>{ id: articleId }, comment).then((result: noosfero.RestResult<noosfero.Comment>) => {
38 38 expect(result.data).toEqual({ id: 2 });
39 39 done();
40 40 });
... ...
src/lib/ng-noosfero-api/http/comment.service.ts
... ... @@ -21,9 +21,10 @@ export class CommentService extends RestangularService&lt;noosfero.Comment&gt; {
21 21 };
22 22 }
23 23  
24   - getByArticle(article: noosfero.Article, params?: any): ng.IPromise<noosfero.RestResult<noosfero.Comment[]>> {
  24 + getByArticle(article: noosfero.Article, params: any = {}): ng.IPromise<noosfero.RestResult<noosfero.Comment[]>> {
  25 + params['without_reply'] = true;
25 26 let articleElement = this.articleService.getElement(<number>article.id);
26   - return this.list(articleElement);
  27 + return this.list(articleElement, params);
27 28 }
28 29  
29 30 createInArticle(article: noosfero.Article, comment: noosfero.Comment): ng.IPromise<noosfero.RestResult<noosfero.Comment>> {
... ...
src/lib/ng-noosfero-api/interfaces/comment.ts
1 1 namespace noosfero {
2 2 export interface Comment extends RestModel {
3 3 reply_of_id: number;
  4 + reply_of: Comment;
  5 + replies: Comment[];
  6 + body: string;
  7 + }
  8 +
  9 + export interface CommentViewModel extends Comment {
  10 + __show_reply?: boolean;
4 11 }
5 12 }
... ...