Commit 22792707e2168842b9362dcae881e2a5e4764735

Authored by Victor Costa
1 parent f25f5c3c

Emit and subscribe to events for task accept/reject

src/app/known-events.ts
1 import { EventsHubKnownEventNames } from './shared/services/events-hub.service'; 1 import { EventsHubKnownEventNames } from './shared/services/events-hub.service';
2 2
3 -export class NoosferoKnownEvents implements EventsHubKnownEventNames { 3 +export class NoosferoKnownEvents implements EventsHubKnownEventNames {
4 IMAGE_PROFILE_UPDATED: string = 'IMAGE_PROFILE_UPDATED'; 4 IMAGE_PROFILE_UPDATED: string = 'IMAGE_PROFILE_UPDATED';
5 PROFILE_INFO_UPDATED: string = 'PROFILE_INFO_UPDATED'; 5 PROFILE_INFO_UPDATED: string = 'PROFILE_INFO_UPDATED';
6 ARTICLE_UPDATED: string = 'ARTICLE_UPDATED'; 6 ARTICLE_UPDATED: string = 'ARTICLE_UPDATED';
  7 + TASK_CLOSED: string = 'TASK_CLOSED';
7 8
8 constructor() { 9 constructor() {
9 } 10 }
@@ -11,4 +12,4 @@ export class NoosferoKnownEvents implements EventsHubKnownEventNames { @@ -11,4 +12,4 @@ export class NoosferoKnownEvents implements EventsHubKnownEventNames {
11 getNames() { 12 getNames() {
12 return Object.getOwnPropertyNames(this); 13 return Object.getOwnPropertyNames(this);
13 } 14 }
14 -}  
15 \ No newline at end of file 15 \ No newline at end of file
  16 +}
src/app/main/main.component.spec.ts
@@ -40,7 +40,8 @@ describe("MainComponent", function () { @@ -40,7 +40,8 @@ describe("MainComponent", function () {
40 useValue: [ 40 useValue: [
41 'IMAGE_PROFILE_UPDATED', 41 'IMAGE_PROFILE_UPDATED',
42 'PROFILE_INFO_UPDATED', 42 'PROFILE_INFO_UPDATED',
43 - 'ARTICLE_UPDATED' 43 + 'ARTICLE_UPDATED',
  44 + 'TASK_CLOSED'
44 ] 45 ]
45 }), 46 }),
46 ] 47 ]
src/app/shared/services/events-hub.service.ts
@@ -31,13 +31,13 @@ export class EventsHubService { @@ -31,13 +31,13 @@ export class EventsHubService {
31 emitEvent(eventType: string, payload?: any) { 31 emitEvent(eventType: string, payload?: any) {
32 this.checkKnownEvent(eventType); 32 this.checkKnownEvent(eventType);
33 let event = this.emitters.get(eventType); 33 let event = this.emitters.get(eventType);
34 - if ( event ) this.emitters.get(eventType).next(payload); 34 + if (event) this.emitters.get(eventType).next(payload);
35 } 35 }
36 36
37 subscribeToEvent<T>(eventType: string, generatorOrNext?: ((p?: T) => void), error?: any, complete?: any) { 37 subscribeToEvent<T>(eventType: string, generatorOrNext?: ((p?: T) => void), error?: any, complete?: any) {
38 this.checkKnownEvent(eventType); 38 this.checkKnownEvent(eventType);
39 let event = this.emitters.get(eventType); 39 let event = this.emitters.get(eventType);
40 - if (event) event.subscribe(generatorOrNext, error, complete); 40 + if (event) event.subscribe(generatorOrNext, error, complete);
41 } 41 }
42 42
43 private setupEmitters() { 43 private setupEmitters() {
@@ -53,4 +53,4 @@ export class EventsHubService { @@ -53,4 +53,4 @@ export class EventsHubService {
53 } 53 }
54 54
55 55
56 -}  
57 \ No newline at end of file 56 \ No newline at end of file
  57 +}
src/app/task/task-list/task-accept.component.spec.ts
@@ -19,7 +19,7 @@ describe(&quot;Components&quot;, () =&gt; { @@ -19,7 +19,7 @@ describe(&quot;Components&quot;, () =&gt; {
19 properties: { task: task }, 19 properties: { task: task },
20 providers: [ 20 providers: [
21 helpers.createProviderToValue("RoleService", roleService) 21 helpers.createProviderToValue("RoleService", roleService)
22 - ] 22 + ].concat(helpers.provideFilters("translateFilter"))
23 }); 23 });
24 } 24 }
25 25
src/app/task/task-list/task-list.component.spec.ts
@@ -12,6 +12,7 @@ describe(&quot;Components&quot;, () =&gt; { @@ -12,6 +12,7 @@ describe(&quot;Components&quot;, () =&gt; {
12 let taskService = jasmine.createSpyObj("taskService", ["getAllPending"]); 12 let taskService = jasmine.createSpyObj("taskService", ["getAllPending"]);
13 let tasks = [{ id: 1 }, { id: 2 }]; 13 let tasks = [{ id: 1 }, { id: 2 }];
14 let modal = helpers.mocks.$modal; 14 let modal = helpers.mocks.$modal;
  15 + let eventsHubService = jasmine.createSpyObj("eventsHubService", ["subscribeToEvent", "emitEvent"]);
15 taskService.getAllPending = jasmine.createSpy("getAllPending").and.returnValue(Promise.resolve({ headers: () => { }, data: tasks })); 16 taskService.getAllPending = jasmine.createSpy("getAllPending").and.returnValue(Promise.resolve({ headers: () => { }, data: tasks }));
16 17
17 beforeEach(angular.mock.module("templates")); 18 beforeEach(angular.mock.module("templates"));
@@ -22,6 +23,7 @@ describe(&quot;Components&quot;, () =&gt; { @@ -22,6 +23,7 @@ describe(&quot;Components&quot;, () =&gt; {
22 directives: [TaskListComponent], 23 directives: [TaskListComponent],
23 providers: [ 24 providers: [
24 helpers.createProviderToValue("TaskService", taskService), 25 helpers.createProviderToValue("TaskService", taskService),
  26 + helpers.createProviderToValue("EventsHubService", eventsHubService),
25 helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService), 27 helpers.createProviderToValue('NotificationService', helpers.mocks.notificationService),
26 helpers.createProviderToValue('$uibModal', modal), 28 helpers.createProviderToValue('$uibModal', modal),
27 ].concat(helpers.provideFilters("groupByFilter")), 29 ].concat(helpers.provideFilters("groupByFilter")),
@@ -66,24 +68,24 @@ describe(&quot;Components&quot;, () =&gt; { @@ -66,24 +68,24 @@ describe(&quot;Components&quot;, () =&gt; {
66 expect(helper.component.callReject).toHaveBeenCalled(); 68 expect(helper.component.callReject).toHaveBeenCalled();
67 }); 69 });
68 70
69 - it("call cancel and remove the current task when accept was called successfully", () => { 71 + it("call cancel and emit event when accept was called successfully", () => {
70 helper.component.currentTask = <any>{ id: 1 }; 72 helper.component.currentTask = <any>{ id: 1 };
71 let result = helpers.mocks.promiseResultTemplate({ data: { id: 1 } }); 73 let result = helpers.mocks.promiseResultTemplate({ data: { id: 1 } });
72 taskService.finishTask = jasmine.createSpy("finishTask").and.returnValue(result); 74 taskService.finishTask = jasmine.createSpy("finishTask").and.returnValue(result);
73 helper.component.cancel = jasmine.createSpy("cancel"); 75 helper.component.cancel = jasmine.createSpy("cancel");
74 helper.component.callAccept(); 76 helper.component.callAccept();
75 expect(helper.component.cancel).toHaveBeenCalled(); 77 expect(helper.component.cancel).toHaveBeenCalled();
76 - expect(helper.component.tasks).toEqual([{ id: 2 }]); 78 + expect((<any>helper.component)['eventsHubService'].emitEvent).toHaveBeenCalled();
77 }); 79 });
78 80
79 - it("call cancel and remove the current task when reject was called successfully", () => { 81 + it("call cancel and emit event when reject was called successfully", () => {
80 helper.component.currentTask = <any>{ id: 1 }; 82 helper.component.currentTask = <any>{ id: 1 };
81 let result = helpers.mocks.promiseResultTemplate({ data: { id: 1 } }); 83 let result = helpers.mocks.promiseResultTemplate({ data: { id: 1 } });
82 taskService.cancelTask = jasmine.createSpy("cancelTask").and.returnValue(result); 84 taskService.cancelTask = jasmine.createSpy("cancelTask").and.returnValue(result);
83 helper.component.cancel = jasmine.createSpy("cancel"); 85 helper.component.cancel = jasmine.createSpy("cancel");
84 helper.component.callReject(); 86 helper.component.callReject();
85 expect(helper.component.cancel).toHaveBeenCalled(); 87 expect(helper.component.cancel).toHaveBeenCalled();
86 - expect(helper.component.tasks).toEqual([{ id: 2 }]); 88 + expect((<any>helper.component)['eventsHubService'].emitEvent).toHaveBeenCalled();
87 }); 89 });
88 90
89 it("reset currentTask and close modal when call cancel", () => { 91 it("reset currentTask and close modal when call cancel", () => {
src/app/task/task-list/task-list.component.ts
1 -import { Component, Input, Inject } from "ng-forward"; 1 +import { Component, Input, Inject, provide } from "ng-forward";
2 import { NotificationService } from "../../shared/services/notification.service"; 2 import { NotificationService } from "../../shared/services/notification.service";
3 import { TaskService } from "../../../lib/ng-noosfero-api/http/task.service"; 3 import { TaskService } from "../../../lib/ng-noosfero-api/http/task.service";
4 import { TaskAcceptComponent } from "./task-accept.component"; 4 import { TaskAcceptComponent } from "./task-accept.component";
5 import { Arrays } from "../../../lib/util/arrays"; 5 import { Arrays } from "../../../lib/util/arrays";
  6 +import { EventsHubService } from "../../shared/services/events-hub.service";
  7 +import { NoosferoKnownEvents } from "../../known-events";
6 8
7 @Component({ 9 @Component({
8 selector: "task-list", 10 selector: "task-list",
9 templateUrl: "app/task/task-list/task-list.html", 11 templateUrl: "app/task/task-list/task-list.html",
10 - directives: [TaskAcceptComponent] 12 + directives: [TaskAcceptComponent],
  13 + providers: [
  14 + provide('eventsHubService', { useClass: EventsHubService })
  15 + ]
11 }) 16 })
12 -@Inject(NotificationService, "$scope", "$uibModal", TaskService) 17 +@Inject(NotificationService, "$scope", "$uibModal", TaskService, EventsHubService)
13 export class TaskListComponent { 18 export class TaskListComponent {
14 19
15 @Input() tasks: noosfero.Task[]; 20 @Input() tasks: noosfero.Task[];
@@ -18,9 +23,23 @@ export class TaskListComponent { @@ -18,9 +23,23 @@ export class TaskListComponent {
18 23
19 currentTask: noosfero.Task; 24 currentTask: noosfero.Task;
20 confirmationTask: noosfero.Task; 25 confirmationTask: noosfero.Task;
  26 + eventsNames: NoosferoKnownEvents;
21 private modalInstance: any = null; 27 private modalInstance: any = null;
22 28
23 - constructor(private notificationService: NotificationService, private $scope: ng.IScope, private $uibModal: any, private taskService: TaskService) { } 29 + constructor(private notificationService: NotificationService,
  30 + private $scope: ng.IScope,
  31 + private $uibModal: any,
  32 + private taskService: TaskService,
  33 + private eventsHubService: EventsHubService) {
  34 +
  35 + this.eventsNames = new NoosferoKnownEvents();
  36 + }
  37 +
  38 + ngOnInit() {
  39 + this.eventsHubService.subscribeToEvent(this.eventsNames.TASK_CLOSED, (task: noosfero.Task) => {
  40 + Arrays.remove(this.tasks, task);
  41 + });
  42 + }
24 43
25 getTaskTemplate(task: noosfero.Task) { 44 getTaskTemplate(task: noosfero.Task) {
26 if (this.taskTemplates.indexOf(task.type) >= 0) { 45 if (this.taskTemplates.indexOf(task.type) >= 0) {
@@ -65,7 +84,7 @@ export class TaskListComponent { @@ -65,7 +84,7 @@ export class TaskListComponent {
65 84
66 callAccept() { 85 callAccept() {
67 this.taskService.finishTask(this.confirmationTask).then(() => { 86 this.taskService.finishTask(this.confirmationTask).then(() => {
68 - Arrays.remove(this.tasks, this.currentTask); 87 + this.eventsHubService.emitEvent(this.eventsNames.TASK_CLOSED, this.currentTask);
69 this.notificationService.success({ title: "tasks.actions.accept.title", message: "tasks.actions.accept.message" }); 88 this.notificationService.success({ title: "tasks.actions.accept.title", message: "tasks.actions.accept.message" });
70 }).finally(() => { 89 }).finally(() => {
71 this.cancel(); 90 this.cancel();
@@ -74,7 +93,7 @@ export class TaskListComponent { @@ -74,7 +93,7 @@ export class TaskListComponent {
74 93
75 callReject() { 94 callReject() {
76 this.taskService.cancelTask(this.confirmationTask).then(() => { 95 this.taskService.cancelTask(this.confirmationTask).then(() => {
77 - Arrays.remove(this.tasks, this.currentTask); 96 + this.eventsHubService.emitEvent(this.eventsNames.TASK_CLOSED, this.currentTask);
78 this.notificationService.success({ title: "tasks.actions.reject.title", message: "tasks.actions.reject.message" }); 97 this.notificationService.success({ title: "tasks.actions.reject.title", message: "tasks.actions.reject.message" });
79 }).finally(() => { 98 }).finally(() => {
80 this.cancel(); 99 this.cancel();
src/app/task/tasks-menu/tasks-menu.component.spec.ts
@@ -12,6 +12,7 @@ describe(&quot;Components&quot;, () =&gt; { @@ -12,6 +12,7 @@ describe(&quot;Components&quot;, () =&gt; {
12 let helper: ComponentTestHelper<TasksMenuComponent>; 12 let helper: ComponentTestHelper<TasksMenuComponent>;
13 let taskService = jasmine.createSpyObj("taskService", ["getAllPending"]); 13 let taskService = jasmine.createSpyObj("taskService", ["getAllPending"]);
14 let tasks = [{ id: 1 }, { id: 2 }]; 14 let tasks = [{ id: 1 }, { id: 2 }];
  15 + let eventsHubService = jasmine.createSpyObj("eventsHubService", ["subscribeToEvent", "emitEvent"]);
15 taskService.getAllPending = jasmine.createSpy("getAllPending").and.returnValue(Promise.resolve({ headers: () => { }, data: tasks })); 16 taskService.getAllPending = jasmine.createSpy("getAllPending").and.returnValue(Promise.resolve({ headers: () => { }, data: tasks }));
16 17
17 beforeEach(angular.mock.module("templates")); 18 beforeEach(angular.mock.module("templates"));
@@ -22,6 +23,7 @@ describe(&quot;Components&quot;, () =&gt; { @@ -22,6 +23,7 @@ describe(&quot;Components&quot;, () =&gt; {
22 directives: [TasksMenuComponent], 23 directives: [TasksMenuComponent],
23 providers: [ 24 providers: [
24 helpers.createProviderToValue("TaskService", taskService), 25 helpers.createProviderToValue("TaskService", taskService),
  26 + helpers.createProviderToValue("EventsHubService", eventsHubService),
25 helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({})) 27 helpers.createProviderToValue('SessionService', helpers.mocks.sessionWithCurrentUser({}))
26 ] 28 ]
27 }); 29 });
src/app/task/tasks-menu/tasks-menu.component.ts
1 import { Component, Inject } from "ng-forward"; 1 import { Component, Inject } from "ng-forward";
2 import { TaskService } from "../../../lib/ng-noosfero-api/http/task.service"; 2 import { TaskService } from "../../../lib/ng-noosfero-api/http/task.service";
3 import { AuthService, SessionService, AuthEvents } from "./../../login"; 3 import { AuthService, SessionService, AuthEvents } from "./../../login";
  4 +import { EventsHubService } from "../../shared/services/events-hub.service";
  5 +import { NoosferoKnownEvents } from "../../known-events";
4 6
5 @Component({ 7 @Component({
6 selector: "tasks-menu", 8 selector: "tasks-menu",
7 templateUrl: "app/task/tasks-menu/tasks-menu.html" 9 templateUrl: "app/task/tasks-menu/tasks-menu.html"
8 }) 10 })
9 -@Inject(TaskService, SessionService, AuthService) 11 +@Inject(TaskService, SessionService, AuthService, EventsHubService)
10 export class TasksMenuComponent { 12 export class TasksMenuComponent {
11 13
12 tasks: noosfero.Task[]; 14 tasks: noosfero.Task[];
13 total: number; 15 total: number;
14 perPage = 5; 16 perPage = 5;
15 person: noosfero.Person; 17 person: noosfero.Person;
  18 + eventsNames: NoosferoKnownEvents;
16 19
17 - constructor(private taskService: TaskService, private session: SessionService, private authService: AuthService) { } 20 + constructor(private taskService: TaskService,
  21 + private session: SessionService,
  22 + private authService: AuthService,
  23 + private eventsHubService: EventsHubService) {
  24 +
  25 + this.eventsNames = new NoosferoKnownEvents();
  26 + }
18 27
19 ngOnInit() { 28 ngOnInit() {
  29 + this.eventsHubService.subscribeToEvent(this.eventsNames.TASK_CLOSED, (task: noosfero.Task) => {
  30 + this.total--;
  31 + });
20 this.authService.subscribe(AuthEvents[AuthEvents.loginSuccess], () => { 32 this.authService.subscribe(AuthEvents[AuthEvents.loginSuccess], () => {
21 this.loadTasks(); 33 this.loadTasks();
22 }); 34 });
src/app/task/types/add-member/add-member-accept.html
1 <div class="add-member-details"> 1 <div class="add-member-details">
2 - <label>Select Roles:</label> 2 + <label>{{"tasks.add_member.accept.select_role" | translate}}</label>
3 <div class="form-group roles"> 3 <div class="form-group roles">
4 <div class="checkbox" ng-repeat="role in ctrl.roles"> 4 <div class="checkbox" ng-repeat="role in ctrl.roles">
5 <input type="checkbox" ng-click="ctrl.toggleSelection(role)"> {{role.name}} 5 <input type="checkbox" ng-click="ctrl.toggleSelection(role)"> {{role.name}}
src/languages/en.json
@@ -115,5 +115,6 @@ @@ -115,5 +115,6 @@
115 "tasks.actions.reject.title": "Good job!", 115 "tasks.actions.reject.title": "Good job!",
116 "tasks.actions.accept.message": "Task Accepted", 116 "tasks.actions.accept.message": "Task Accepted",
117 "tasks.actions.reject.message": "Task Rejected", 117 "tasks.actions.reject.message": "Task Rejected",
118 - "tasks.actions.reject.explanation.label": "Rejection explanation" 118 + "tasks.actions.reject.explanation.label": "Rejection explanation",
  119 + "tasks.add_member.accept.select_role": "Select Roles:"
119 } 120 }
src/languages/pt.json
@@ -115,5 +115,6 @@ @@ -115,5 +115,6 @@
115 "tasks.actions.reject.title": "Bom trabalho!", 115 "tasks.actions.reject.title": "Bom trabalho!",
116 "tasks.actions.accept.message": "Tarefa Aceita", 116 "tasks.actions.accept.message": "Tarefa Aceita",
117 "tasks.actions.reject.message": "Tarefa Rejeitada", 117 "tasks.actions.reject.message": "Tarefa Rejeitada",
118 - "tasks.actions.reject.explanation.label": "Motivo da rejeição" 118 + "tasks.actions.reject.explanation.label": "Motivo da rejeição",
  119 + "tasks.add_member.accept.select_role": "Selecionar papéis:"
119 } 120 }