From 4ae492996df657bef710582f7c74d1586930c95f Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 7 May 2015 12:11:59 +0200 Subject: [PATCH] user service to get contacts --- app/coffee/modules/resources.coffee | 4 + app/coffee/modules/resources/timeline.coffee | 6 +- app/coffee/modules/resources/users.coffee | 47 ++++++++++ .../profile-projects.controller.coffee | 20 ++++ .../profile-projects.controller.spec.coffee | 72 ++++++++++++++ .../profile-projects.directive.coffee | 21 ++--- .../profile-tab/profile-tab.directive.coffee | 28 +++--- .../profile/profile-tabs/profile-tabs.jade | 2 +- .../profile-timeline-item.controller.coffee | 1 - .../profile-timeline/profile-timeline.jade | 2 +- app/modules/services/user.service.coffee | 24 +++++ app/modules/services/user.service.spec.coffee | 93 +++++++++++++++++++ 12 files changed, 292 insertions(+), 28 deletions(-) create mode 100644 app/coffee/modules/resources/users.coffee create mode 100644 app/modules/profile/profile-projects/profile-projects.controller.coffee create mode 100644 app/modules/profile/profile-projects/profile-projects.controller.spec.coffee create mode 100644 app/modules/services/user.service.coffee create mode 100644 app/modules/services/user.service.spec.coffee diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index 820d90a7..8d2b5e0f 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -145,6 +145,9 @@ urls = { # locales "locales": "/locales" + + # user + "contacts": "/users/%s/contacts" } # Initialize api urls service @@ -192,5 +195,6 @@ module.run([ "$tgWebhookLogsResourcesProvider", "$tgLocalesResourcesProvider", "$tgTimelineResourcesProvider", + "$tgUsersResourcesProvider", initResources ]) diff --git a/app/coffee/modules/resources/timeline.coffee b/app/coffee/modules/resources/timeline.coffee index 61c91805..31529120 100644 --- a/app/coffee/modules/resources/timeline.coffee +++ b/app/coffee/modules/resources/timeline.coffee @@ -24,7 +24,11 @@ taiga = @.taiga resourceProvider = ($repo) -> service = {} - service.profile = (userId, params) -> + service.profile = (userId, page) -> + params = { + page: page + } + return $repo.queryOnePaginatedRaw("timeline-profile", userId, params) return (instance) -> diff --git a/app/coffee/modules/resources/users.coffee b/app/coffee/modules/resources/users.coffee new file mode 100644 index 00000000..3db62b96 --- /dev/null +++ b/app/coffee/modules/resources/users.coffee @@ -0,0 +1,47 @@ +### +# Copyright (C) 2014 Andrey Antukh +# Copyright (C) 2014 Jesús Espino Garcia +# Copyright (C) 2014 David Barragán Merino +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# File: modules/resources/user.coffee +### + + +taiga = @.taiga +sizeFormat = @.taiga.sizeFormat + + +resourceProvider = ($http, $urls) -> + service = {} + + service.contacts = (userId, options={}) -> + url = $urls.resolve("contacts", userId) + httpOptions = {headers: {}} + + if not options.enablePagination + httpOptions.headers["x-disable-pagination"] = "1" + + return $http.get(url, {}, httpOptions) + .then (result) -> + return result.data + + return (instance) -> + instance.users = service + + +module = angular.module("taigaResources") +module.factory("$tgUsersResourcesProvider", ["$tgHttp", "$tgUrls", "$q", + resourceProvider]) diff --git a/app/modules/profile/profile-projects/profile-projects.controller.coffee b/app/modules/profile/profile-projects/profile-projects.controller.coffee new file mode 100644 index 00000000..f18a32af --- /dev/null +++ b/app/modules/profile/profile-projects/profile-projects.controller.coffee @@ -0,0 +1,20 @@ +class ProfileProjectsController + @.$inject = [ + "tgUserService", + "$tgAuth" + ] + + constructor: (@userService, @auth) -> + + loadProjects: () -> + userId = @auth.getUser().id + + @userService.getProjects(userId) + .then (projects) => + return @userService.attachUserContactsToProjects(userId, projects) + .then (projects) => + @.projects = projects + + +angular.module("taigaProfile") + .controller("ProfileProjects", ProfileProjectsController) diff --git a/app/modules/profile/profile-projects/profile-projects.controller.spec.coffee b/app/modules/profile/profile-projects/profile-projects.controller.spec.coffee new file mode 100644 index 00000000..ab8988c4 --- /dev/null +++ b/app/modules/profile/profile-projects/profile-projects.controller.spec.coffee @@ -0,0 +1,72 @@ +describe "ProfileProjects", -> + $controller = null + $q = null + provide = null + $rootScope = null + mocks = {} + + _mockUserService = () -> + mocks.userService = { + getProjects: sinon.stub(), + attachUserContactsToProjects: sinon.stub() + } + + provide.value "tgUserService", mocks.userService + + _mockAuthService = () -> + stub = sinon.stub() + + stub.returns({id: 2}) + + provide.value "$tgAuth", { + getUser: stub + } + + _mocks = () -> + module ($provide) -> + provide = $provide + _mockUserService() + _mockAuthService() + + return null + + _inject = (callback) -> + inject (_$controller_, _$q_, _$rootScope_) -> + $q = _$q_ + $rootScope = _$rootScope_ + $controller = _$controller_ + + beforeEach -> + module "taigaProfile" + _mocks() + _inject() + + it "load projects with contacts attached", (done) -> + userId = 2 + projects = [ + {id: 1}, + {id: 2}, + {id: 3} + ] + + projectsWithContacts = [ + {id: 1, contacts: "fake"}, + {id: 2, contacts: "fake"}, + {id: 3, contacts: "fake"} + ] + + mocks.userService.getProjects = (userId) -> + expect(userId).to.be.equal(userId) + + return $q (resolve, reject) -> + resolve(projects) + + mocks.userService.attachUserContactsToProjects.withArgs(userId, projects).returns(projectsWithContacts) + + ctrl = $controller("ProfileProjects") + + ctrl.loadProjects().then () -> + expect(ctrl.projects).to.be.equal(projectsWithContacts) + done() + + $rootScope.$apply() diff --git a/app/modules/profile/profile-projects/profile-projects.directive.coffee b/app/modules/profile/profile-projects/profile-projects.directive.coffee index bb9c2f71..72cf4472 100644 --- a/app/modules/profile/profile-projects/profile-projects.directive.coffee +++ b/app/modules/profile/profile-projects/profile-projects.directive.coffee @@ -1,17 +1,14 @@ -ProfileProjectsDirective = (projectsService) -> - link = (scope, el, attrs, ctrl) -> - scope.vm = {} - taiga.defineImmutableProperty(scope.vm, "projects", () -> projectsService.currentUserProjects.get("all")) +ProfileProjectsDirective = () -> + link = (scope, elm, attr, ctrl) -> + ctrl.loadProjects() - directive = { - templateUrl: "profile/profile-projects/profile-projects.html" - scope: {} + return { + templateUrl: "profile/profile-projects/profile-projects.html", + scope: {}, link: link + bindToController: true, + controllerAs: "vm", + controller: "ProfileProjects" } - return directive - - -ProfileProjectsDirective.$inject = ["tgProjectsService"] - angular.module("taigaProfile").directive("tgProfileProjects", ProfileProjectsDirective) diff --git a/app/modules/profile/profile-tab/profile-tab.directive.coffee b/app/modules/profile/profile-tab/profile-tab.directive.coffee index ed6859e1..ca6f3e59 100644 --- a/app/modules/profile/profile-tab/profile-tab.directive.coffee +++ b/app/modules/profile/profile-tab/profile-tab.directive.coffee @@ -1,13 +1,22 @@ ProfileTabDirective = () -> - link = ($scope, $el, $attrs, $ctrl) -> - $scope.tab = {} + link = (scope, element, attrs, ctrl, transclude) -> + scope.tab = {} - $scope.tab.name = $attrs.tgProfileTab - $scope.tab.title = $attrs.tabTitle - $scope.tab.icon = $attrs.tabIcon - $scope.tab.active = !!$attrs.tabActive + scope.tab.name = attrs.tgProfileTab + scope.tab.title = attrs.tabTitle + scope.tab.icon = attrs.tabIcon + scope.tab.active = !!attrs.tabActive - $ctrl.addTab($scope.tab) + ctrl.addTab(scope.tab) + + scope.$watch "tab.active", (active) -> + if active + transclude scope, (clone, scope) -> + element.append(clone) + else + element.children().each (idx, elm) -> + scope.$$childHead.$destroy() + elm.remove() return { scope: {} @@ -15,11 +24,6 @@ ProfileTabDirective = () -> link: link transclude: true replace: true - template: """ -
- -
- """ } angular.module("taigaProfile") diff --git a/app/modules/profile/profile-tabs/profile-tabs.jade b/app/modules/profile/profile-tabs/profile-tabs.jade index 727a4d3e..beb2d776 100644 --- a/app/modules/profile/profile-tabs/profile-tabs.jade +++ b/app/modules/profile/profile-tabs/profile-tabs.jade @@ -1,6 +1,6 @@ div nav.profile-content-tabs - a.tab(ng-repeat="tab in vm.tabs", href="", title="{{::tab.title}}", ng-class="{active: tab.active}" ng-click="vm.toggleTab(tab)") + a.tab(ng-repeat="tab in ::vm.tabs", href="", title="{{::tab.title}}", ng-class="{active: tab.active}" ng-click="vm.toggleTab(tab)") span.icon(ng-class="::tab.icon") span {{::tab.name}} diff --git a/app/modules/profile/profile-timeline-item/profile-timeline-item.controller.coffee b/app/modules/profile/profile-timeline-item/profile-timeline-item.controller.coffee index 7ab2901c..8145dd74 100644 --- a/app/modules/profile/profile-timeline-item/profile-timeline-item.controller.coffee +++ b/app/modules/profile/profile-timeline-item/profile-timeline-item.controller.coffee @@ -17,7 +17,6 @@ class ProfileTimelineItemController @.activity.sprint = timeline.data.milestone @.activity.title = @profileTimelineItemTitle.getTitle(timeline, event, type) @.activity.created_formated = moment(timeline.created).fromNow() - #test @.activity.obj = @.getObject(timeline, event) if type.description diff --git a/app/modules/profile/profile-timeline/profile-timeline.jade b/app/modules/profile/profile-timeline/profile-timeline.jade index 20b6fdb5..6901f624 100644 --- a/app/modules/profile/profile-timeline/profile-timeline.jade +++ b/app/modules/profile/profile-timeline/profile-timeline.jade @@ -1,3 +1,3 @@ section.profile-timeline - div(infinite-scroll="vm.loadTimeline()", infinite-scroll-distance="3", infinite-scroll-disabled='vm.loadingData') + div(infinite-scroll="vm.loadTimeline()", infinite-scroll-distance="3", infinite-scroll-disabled="vm.loadingData") div(tg-repeat="timeline in vm.timelineList", tg-profile-timeline-item="timeline") diff --git a/app/modules/services/user.service.coffee b/app/modules/services/user.service.coffee new file mode 100644 index 00000000..67b9ae65 --- /dev/null +++ b/app/modules/services/user.service.coffee @@ -0,0 +1,24 @@ +taiga = @.taiga + +class UserService extends taiga.Service + @.$inject = ["$tgResources"] + + constructor: (@rs) -> + + getProjects: (userId) -> + return @rs.projects.listByMember(userId) + .then (projects) -> return Immutable.fromJS(projects) + + attachUserContactsToProjects: (userId, projects) -> + return @rs.users.contacts(userId) + .then (contacts) -> return Immutable.fromJS(contacts) + .then (contacts) -> + projects = projects.map (project) -> + project.contacts = contacts.filter (contact) -> + return project.members.indexOf(contact.id) != -1 + + return project + + return projects + +angular.module("taigaCommon").service("tgUserService", UserService) diff --git a/app/modules/services/user.service.spec.coffee b/app/modules/services/user.service.spec.coffee new file mode 100644 index 00000000..e7c671ae --- /dev/null +++ b/app/modules/services/user.service.spec.coffee @@ -0,0 +1,93 @@ +# pending new resouercees + +describe.skip "UserService", -> + userService = null + $q = null + provide = null + $rootScope = null + mocks = {} + + _mockResources = () -> + mocks.resources = {} + mocks.resources.projects = { + listByMember: sinon.stub() + } + + mocks.resources.users = { + contacts: sinon.stub() + } + + provide.value "$tgResources", mocks.resources + + _mocks = () -> + module ($provide) -> + provide = $provide + _mockResources() + + return null + + _inject = (callback) -> + inject (_tgUserService_, _$q_, _$rootScope_) -> + userService = _tgUserService_ + $q = _$q_ + $rootScope = _$rootScope_ + + beforeEach -> + module "taigaCommon" + _mocks() + _inject() + + it "get user projects", (done) -> + userId = 2 + + projects = [ + {id: 1}, + {id: 2}, + {id: 3} + ] + + mocks.resources.projects.listByMember = (userId) -> + expect(userId).to.be.equal(userId) + + return $q (resolve, reject) -> + resolve(projects) + + userService.getProjects(userId).then (_projects_) -> + expect(_projects_.toJS()).to.be.eql(projects) + done() + + $rootScope.$apply() + + it "attach user contacts to projects", (done) -> + userId = 2 + + class Project + constructor: (@id, @members) -> + + projects = Immutable.fromJS([ + new Project(1, [1, 2, 3]), + new Project(1, [2, 3]), + new Project(1, [1]) + ]) + + contacts = Immutable.fromJS([ + {id: 1, name: "fake1"}, + {id: 2, name: "fake2"}, + {id: 3, name: "fake3"} + ]) + + mocks.resources.users.contacts = (userId) -> + expect(userId).to.be.equal(userId) + + return $q (resolve, reject) -> + resolve(contacts) + + userService.attachUserContactsToProjects(userId, projects).then (_projects_) -> + contacts = _projects_.get(0).contacts + + console.log _projects_.get(0) + + expect(contacts[0]).to.be.equal('fake1') + done() + + $rootScope.$apply()