diff --git a/app/coffee/modules/admin/memberships.coffee b/app/coffee/modules/admin/memberships.coffee index 1ab6c54f..ba2b294a 100644 --- a/app/coffee/modules/admin/memberships.coffee +++ b/app/coffee/modules/admin/memberships.coffee @@ -50,11 +50,12 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai "$translate", "$tgAuth", "tgLightboxFactory", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @analytics, - @appMetaService, @translate, @auth, @lightboxFactory, @errorHandlingService) -> + @appMetaService, @translate, @auth, @lightboxFactory, @errorHandlingService, @projectService) -> bindMethods(@) @scope.project = {} @@ -74,17 +75,18 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai @analytics.trackEvent("membership", "create", "create memberships on admin", 1) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.i_am_admin - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project + if not project.i_am_admin + @errorHandlingService.permissionDenied() - @scope.canAddUsers = project.max_memberships == null || project.max_memberships > project.total_memberships + @scope.projectId = project.id + @scope.project = project - @scope.$emit('project:loaded', project) - return project + @scope.canAddUsers = project.max_memberships == null || project.max_memberships > project.total_memberships + + @scope.$emit('project:loaded', project) + return project loadMembers: -> httpFilters = @.getUrlFilters() @@ -99,11 +101,12 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai return data loadInitialData: -> - return @.loadProject().then () => - return @q.all([ - @.loadMembers(), - @auth.refresh() - ]) + @.loadProject() + + return @q.all([ + @.loadMembers(), + @auth.refresh() + ]) getUrlFilters: -> filters = _.pick(@location.search(), "page") diff --git a/app/coffee/modules/admin/project-profile.coffee b/app/coffee/modules/admin/project-profile.coffee index 65eb759c..61161508 100644 --- a/app/coffee/modules/admin/project-profile.coffee +++ b/app/coffee/modules/admin/project-profile.coffee @@ -54,15 +54,17 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin) "$translate", "$tgAuth", "tgCurrentUserService", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService", + "$tgModel" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, - @appMetaService, @translate, @tgAuth, @currentUserService, @errorHandlingService) -> + @appMetaService, @translate, @tgAuth, @currentUserService, @errorHandlingService, @projectService, @model) -> @scope.project = {} - promise = @.loadInitialData() @scope.projectTags = [] + promise = @.loadInitialData() promise.then => sectionName = @translate.instant( @scope.sectionName) @@ -83,32 +85,33 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin) @appMetaService.setAll(title, description) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.i_am_admin - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() + project = @model.make_model("projects", project) - @scope.projectId = project.id - @scope.project = project - @scope.epicStatusList = _.sortBy(project.epic_statuses, "order") - @scope.usStatusList = _.sortBy(project.us_statuses, "order") - @scope.pointsList = _.sortBy(project.points, "order") - @scope.taskStatusList = _.sortBy(project.task_statuses, "order") - @scope.issueTypesList = _.sortBy(project.issue_types, "order") - @scope.issueStatusList = _.sortBy(project.issue_statuses, "order") - @scope.prioritiesList = _.sortBy(project.priorities, "order") - @scope.severitiesList = _.sortBy(project.severities, "order") - @scope.$emit('project:loaded', project) + if not project.i_am_admin + @errorHandlingService.permissionDenied() - @scope.projectTags = _.map @scope.project.tags, (it) => - return [it, @scope.project.tags_colors[it]] + @scope.projectId = project.id + @scope.project = project + @scope.epicStatusList = _.sortBy(project.epic_statuses, "order") + @scope.usStatusList = _.sortBy(project.us_statuses, "order") + @scope.pointsList = _.sortBy(project.points, "order") + @scope.taskStatusList = _.sortBy(project.task_statuses, "order") + @scope.issueTypesList = _.sortBy(project.issue_types, "order") + @scope.issueStatusList = _.sortBy(project.issue_statuses, "order") + @scope.prioritiesList = _.sortBy(project.priorities, "order") + @scope.severitiesList = _.sortBy(project.severities, "order") + @scope.$emit('project:loaded', project) - return project + @scope.projectTags = _.map @scope.project.tags, (it) => + return [it, @scope.project.tags_colors[it]] + + return project loadInitialData: -> - return @q.all([ - @.loadProject(), - @tgAuth.refresh() - ]) + @.loadProject() + + return @tgAuth.refresh() openDeleteLightbox: -> @rootscope.$broadcast("deletelightbox:new", @scope.project) @@ -158,9 +161,9 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje }) $location.path(newUrl) - $ctrl.loadInitialData() + projectService.fetchProject().then () => + $ctrl.loadInitialData() - projectService.fetchProject() currentUserService.loadProjects() promise.then null, (data) -> diff --git a/app/coffee/modules/admin/project-values.coffee b/app/coffee/modules/admin/project-values.coffee index 9d0413aa..80d26c82 100644 --- a/app/coffee/modules/admin/project-values.coffee +++ b/app/coffee/modules/admin/project-values.coffee @@ -53,36 +53,36 @@ class ProjectValuesSectionController extends mixOf(taiga.Controller, taiga.PageM "$tgNavUrls", "tgAppMetaService", "$translate", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, - @appMetaService, @translate, @errorHandlingService) -> + @appMetaService, @translate, @errorHandlingService, @projectService) -> @scope.project = {} - promise = @.loadInitialData() + @.loadInitialData() - promise.then () => - sectionName = @translate.instant(@scope.sectionName) + sectionName = @translate.instant(@scope.sectionName) - title = @translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", { - "sectionName": sectionName, - "projectName": @scope.project.name - }) - description = @scope.project.description - @appMetaService.setAll(title, description) + title = @translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", { + "sectionName": sectionName, + "projectName": @scope.project.name + }) - promise.then null, @.onInitialDataError.bind(@) + description = @scope.project.description + @appMetaService.setAll(title, description) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.i_am_admin - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + if not project.i_am_admin + @errorHandlingService.permissionDenied() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadInitialData: -> promise = @.loadProject() @@ -106,8 +106,11 @@ class ProjectValuesController extends taiga.Controller constructor: (@scope, @rootscope, @repo, @confirm, @rs) -> @scope.$on("admin:project-values:move", @.moveValue) - @rootscope.$on("project:loaded", @.loadValues) + unwatch = @scope.$watch "resource", (resource) => + if resource + @.loadValues() + unwatch() loadValues: => return @rs[@scope.resource].listValues(@scope.projectId, @scope.type).then (values) => @scope.values = values diff --git a/app/coffee/modules/admin/roles.coffee b/app/coffee/modules/admin/roles.coffee index e60daa13..9d4348cb 100644 --- a/app/coffee/modules/admin/roles.coffee +++ b/app/coffee/modules/admin/roles.coffee @@ -49,11 +49,12 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil "$tgNavUrls", "tgAppMetaService", "$translate", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, - @appMetaService, @translate, @errorHandlingService) -> + @appMetaService, @translate, @errorHandlingService, @projectService) -> bindMethods(@) @scope.sectionName = "ADMIN.MENU.PERMISSIONS" @@ -70,17 +71,18 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil promise.then null, @.onInitialDataError.bind(@) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.i_am_admin - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project + if not project.i_am_admin + @errorHandlingService.permissionDenied() - @scope.$emit('project:loaded', project) - @scope.anyComputableRole = _.some(_.map(project.roles, (point) -> point.computable)) + @scope.projectId = project.id + @scope.project = project - return project + @scope.$emit('project:loaded', project) + @scope.anyComputableRole = _.some(_.map(project.roles, (point) -> point.computable)) + + return project loadRoles: -> return @rs.roles.list(@scope.projectId).then (roles) => @@ -103,9 +105,12 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil return roles loadInitialData: -> - promise = @.loadProject() - promise.then(=> @.loadRoles()) - return promise + @.loadProject() + return @.loadRoles() + + forceLoadProject: () -> + @projectService.fetchProject () => + @.loadProject() setRole: (role) -> @scope.role = role @@ -126,7 +131,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil warning = @translate.instant("ADMIN.ROLES.WARNING_DELETE_ROLE") return @confirm.askChoice(title, subtitle, choices, replacement, warning).then (response) => onSuccess = => - @.loadProject() + @.forceLoadProject() @.loadRoles().finally => response.finish() onError = => @@ -137,7 +142,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil _enableComputable: => onSuccess = => @confirm.notify("success") - @.loadProject() + @.forceLoadProject() onError = => @confirm.notify("error") @@ -150,7 +155,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil onSuccess = => response.finish() @confirm.notify("success") - @.loadProject() + @.forceLoadProject() onError = => response.finish() @confirm.notify("error") @@ -264,7 +269,7 @@ NewRoleDirective = ($tgrepo, $confirm) -> $scope.roles.splice(insertPosition, 0, role) $ctrl.setRole(role) $el.find(".add-button").show() - $ctrl.loadProject() + $ctrl.forceLoadProject() onError = -> $confirm.notify("error") @@ -474,7 +479,7 @@ RolePermissionsDirective = ($rootscope, $repo, $confirm, $compile) -> renderResume(target.parents(".category-config"), categories[categoryId]) $rootscope.$broadcast("projects:reload") $confirm.notify("success") - $ctrl.loadProject() + $ctrl.forceLoadProject() onError = -> $confirm.notify("error") diff --git a/app/coffee/modules/admin/third-parties.coffee b/app/coffee/modules/admin/third-parties.coffee index 74ea9ed7..7b250d24 100644 --- a/app/coffee/modules/admin/third-parties.coffee +++ b/app/coffee/modules/admin/third-parties.coffee @@ -46,10 +46,11 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga. "$tgNavUrls", "tgAppMetaService", "$translate", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] - constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appMetaService, @translate, @errorHandlingService) -> + constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appMetaService, @translate, @errorHandlingService, @projectService) -> bindMethods(@) @scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME" @@ -71,21 +72,20 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga. @scope.webhooks = webhooks loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.i_am_admin - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + if not project.i_am_admin + @errorHandlingService.permissionDenied() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadInitialData: -> - promise = @.loadProject() - promise.then => - @.loadWebhooks() + @.loadProject() - return promise + return @.loadWebhooks() module.controller("WebhooksController", WebhooksController) @@ -309,10 +309,11 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi "$tgResources", "$routeParams", "tgAppMetaService", - "$translate" + "$translate", + "tgProjectService" ] - constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> + constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) -> bindMethods(@) @scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME") @@ -332,16 +333,16 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @scope.github = github loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadInitialData: -> promise = @.loadProject() - promise.then(=> @.loadModules()) - return promise + return @.loadModules() module.controller("GithubController", GithubController) @@ -357,10 +358,11 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi "$tgResources", "$routeParams", "tgAppMetaService", - "$translate" + "$translate", + "tgProjectService" ] - constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> + constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) -> bindMethods(@) @scope.sectionName = @translate.instant("ADMIN.GITLAB.SECTION_NAME") @@ -382,16 +384,16 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @scope.gitlab = gitlab loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadInitialData: -> - promise = @.loadProject() - promise.then(=> @.loadModules()) - return promise + @.loadProject() + return @.loadModules() module.controller("GitlabController", GitlabController) @@ -407,10 +409,11 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga "$tgResources", "$routeParams", "tgAppMetaService", - "$translate" + "$translate", + "tgProjectService" ] - constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> + constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) -> bindMethods(@) @scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME") @@ -432,16 +435,16 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga @scope.bitbucket = bitbucket loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadInitialData: -> - promise = @.loadProject() - promise.then(=> @.loadModules()) - return promise + @.loadProject() + return @.loadModules() module.controller("BitbucketController", BitbucketController) @@ -598,10 +601,11 @@ class GogsController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Filt "$tgResources", "$routeParams", "tgAppMetaService", - "$translate" + "$translate", + "tgProjectService" ] - constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> + constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) -> bindMethods(@) @scope.sectionName = @translate.instant("ADMIN.GOGS.SECTION_NAME") @@ -621,15 +625,15 @@ class GogsController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Filt @scope.gogs = gogs loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadInitialData: -> - promise = @.loadProject() - promise.then(=> @.loadModules()) - return promise + @.loadProject() + return @.loadModules() module.controller("GogsController", GogsController) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 6099a528..4c783cd4 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -59,7 +59,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F "$tgQueueModelTransformation", "tgErrorHandlingService", "$tgStorage", - "tgFilterRemoteStorageService" + "tgFilterRemoteStorageService", + "tgProjectService" ] storeCustomFiltersName: 'backlog-custom-filters' @@ -69,7 +70,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @appMetaService, @navUrls, @events, @analytics, @translate, @loading, @rs2, @modelTransform, @errorHandlingService, - @storage, @filterRemoteStorageService) -> + @storage, @filterRemoteStorageService, @projectService) -> bindMethods(@) @.backlogOrder = {} @@ -341,28 +342,29 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F break loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.is_backlog_activated - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.closedMilestones = !!project.total_closed_milestones - @scope.$emit('project:loaded', project) - @scope.points = _.sortBy(project.points, "order") - @scope.pointsById = groupBy(project.points, (x) -> x.id) - @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) - @scope.usStatusList = _.sortBy(project.us_statuses, "id") - return project + if not project.is_backlog_activated + @errorHandlingService.permissionDenied() + + @scope.projectId = project.id + @scope.project = project + @scope.closedMilestones = !!project.total_closed_milestones + @scope.$emit('project:loaded', project) + @scope.points = _.sortBy(project.points, "order") + @scope.pointsById = groupBy(project.points, (x) -> x.id) + @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) + @scope.usStatusList = _.sortBy(project.us_statuses, "id") + + return project loadInitialData: -> - promise = @.loadProject() - promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.initializeSubscription() + project = @.loadProject() - return promise - .then(=> @.loadBacklog()) + @.fillUsersAndRoles(project.members, project.roles) + @.initializeSubscription() + + return @.loadBacklog() .then(=> @.generateFilters()) .then(=> @scope.$emit("backlog:loaded")) diff --git a/app/coffee/modules/base/contrib.coffee b/app/coffee/modules/base/contrib.coffee index e8607fef..ec0b40b9 100644 --- a/app/coffee/modules/base/contrib.coffee +++ b/app/coffee/modules/base/contrib.coffee @@ -32,25 +32,24 @@ class ContribController extends taiga.Controller "$routeParams", "$tgRepo", "$tgResources", - "$tgConfirm" + "$tgConfirm", + "tgProjectService" ] - constructor: (@rootScope, @scope, @params, @repo, @rs, @confirm) -> + constructor: (@rootScope, @scope, @params, @repo, @rs, @confirm, @projectService) -> @scope.currentPlugin = _.head(_.filter(@rootScope.adminPlugins, {"slug": @params.plugin})) @scope.projectSlug = @params.pslug - promise = @.loadInitialData() - - promise.then null, => - @confirm.notify("error") + @.loadInitialData() loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - @scope.$broadcast('project:loaded', project) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + @scope.$broadcast('project:loaded', project) + return project loadInitialData: -> return @.loadProject() diff --git a/app/coffee/modules/epics/detail.coffee b/app/coffee/modules/epics/detail.coffee index f5a35849..71512182 100644 --- a/app/coffee/modules/epics/detail.coffee +++ b/app/coffee/modules/epics/detail.coffee @@ -54,11 +54,12 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin) "$tgNavUrls", "$translate", "$tgQueueModelTransformation", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location, - @log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService) -> + @log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService, @projectService) -> bindMethods(@) @scope.epicRef = @params.epicref @@ -102,14 +103,15 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.onDeleteGoToUrl = @navUrls.resolve("project-epics", ctx) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.immutableProject = Immutable.fromJS(project._attrs) - @scope.$emit('project:loaded', project) - @scope.statusList = project.epic_statuses - @scope.statusById = groupBy(project.epic_statuses, (x) -> x.id) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.immutableProject = @projectService.project + @scope.$emit('project:loaded', project) + @scope.statusList = project.epic_statuses + @scope.statusById = groupBy(project.epic_statuses, (x) -> x.id) + return project loadEpic: -> return @rs.epics.getByRef(@scope.projectId, @params.epicref).then (epic) => @@ -139,10 +141,10 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.userstories = data loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.loadEpic().then(=> @.loadUserstories()) + project = @.loadProject() + + @.fillUsersAndRoles(project.members, project.roles) + @.loadEpic().then(=> @.loadUserstories()) ### # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. diff --git a/app/coffee/modules/issues/detail.coffee b/app/coffee/modules/issues/detail.coffee index bb65f413..20a7fc69 100644 --- a/app/coffee/modules/issues/detail.coffee +++ b/app/coffee/modules/issues/detail.coffee @@ -53,11 +53,12 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) "$tgNavUrls", "$translate", "$tgQueueModelTransformation", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, - @log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService) -> + @log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService, @projectService) -> bindMethods(@) @scope.issueRef = @params.issueref @@ -112,19 +113,20 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.onDeleteGoToUrl = @navUrls.resolve("project", ctx) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - @scope.statusList = project.issue_statuses - @scope.statusById = groupBy(project.issue_statuses, (x) -> x.id) - @scope.typeById = groupBy(project.issue_types, (x) -> x.id) - @scope.typeList = _.sortBy(project.issue_types, "order") - @scope.severityList = project.severities - @scope.severityById = groupBy(project.severities, (x) -> x.id) - @scope.priorityList = project.priorities - @scope.priorityById = groupBy(project.priorities, (x) -> x.id) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + @scope.statusList = project.issue_statuses + @scope.statusById = groupBy(project.issue_statuses, (x) -> x.id) + @scope.typeById = groupBy(project.issue_types, (x) -> x.id) + @scope.typeList = _.sortBy(project.issue_types, "order") + @scope.severityList = project.severities + @scope.severityById = groupBy(project.severities, (x) -> x.id) + @scope.priorityList = project.priorities + @scope.priorityById = groupBy(project.priorities, (x) -> x.id) + return project loadIssue: -> return @rs.issues.getByRef(@scope.projectId, @params.issueref).then (issue) => @@ -149,10 +151,11 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.nextUrl = @navUrls.resolve("project-issues-detail", ctx) loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.loadIssue() + project = @.loadProject() + + @.fillUsersAndRoles(project.members, project.roles) + + return @.loadIssue() ### # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. diff --git a/app/coffee/modules/issues/list.coffee b/app/coffee/modules/issues/list.coffee index 9a53e14e..0f149666 100644 --- a/app/coffee/modules/issues/list.coffee +++ b/app/coffee/modules/issues/list.coffee @@ -58,14 +58,16 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi "$translate", "tgErrorHandlingService", "$tgStorage", - "tgFilterRemoteStorageService" + "tgFilterRemoteStorageService", + "tgProjectService", + "tgUserActivityService" ] filtersHashSuffix: "issues-filters" myFiltersHashSuffix: "issues-my-filters" constructor: (@scope, @rootscope, @repo, @confirm, @rs, @urls, @params, @q, @location, @appMetaService, - @navUrls, @events, @analytics, @translate, @errorHandlingService, @storage, @filterRemoteStorageService) -> + @navUrls, @events, @analytics, @translate, @errorHandlingService, @storage, @filterRemoteStorageService, @projectService) -> bindMethods(@) @scope.sectionName = "Issues" @@ -286,24 +288,25 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.is_issues_activated - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) + if not project.is_issues_activated + @errorHandlingService.permissionDenied() - @scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id) - @scope.issueStatusList = _.sortBy(project.issue_statuses, "order") - @scope.severityById = groupBy(project.severities, (x) -> x.id) - @scope.severityList = _.sortBy(project.severities, "order") - @scope.priorityById = groupBy(project.priorities, (x) -> x.id) - @scope.priorityList = _.sortBy(project.priorities, "order") - @scope.issueTypes = _.sortBy(project.issue_types, "order") - @scope.issueTypeById = groupBy(project.issue_types, (x) -> x.id) + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) - return project + @scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id) + @scope.issueStatusList = _.sortBy(project.issue_statuses, "order") + @scope.severityById = groupBy(project.severities, (x) -> x.id) + @scope.severityList = _.sortBy(project.severities, "order") + @scope.priorityById = groupBy(project.priorities, (x) -> x.id) + @scope.priorityList = _.sortBy(project.priorities, "order") + @scope.issueTypes = _.sortBy(project.issue_types, "order") + @scope.issueTypeById = groupBy(project.issue_types, (x) -> x.id) + + return project # We need to guarantee that the last petition done here is the finally used # When searching by text loadIssues can be called fastly with different parameters and @@ -328,13 +331,13 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi return promise loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.initializeSubscription() - @.generateFilters() + project = @.loadProject() - return @.loadIssues() + @.fillUsersAndRoles(project.members, project.roles) + @.initializeSubscription() + @.generateFilters() + + return @.loadIssues() # Functions used from templates addNewIssue: -> diff --git a/app/coffee/modules/kanban/main.coffee b/app/coffee/modules/kanban/main.coffee index 643472f5..be2a2ab2 100644 --- a/app/coffee/modules/kanban/main.coffee +++ b/app/coffee/modules/kanban/main.coffee @@ -58,7 +58,8 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi "$tgModel", "tgKanbanUserstories", "$tgStorage", - "tgFilterRemoteStorageService" + "tgFilterRemoteStorageService", + "tgProjectService" ] storeCustomFiltersName: 'kanban-custom-filters' @@ -66,7 +67,7 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location, @appMetaService, @navUrls, @events, @analytics, @translate, @errorHandlingService, - @model, @kanbanUserstoriesService, @storage, @filterRemoteStorageService) -> + @model, @kanbanUserstoriesService, @storage, @filterRemoteStorageService, @projectService) -> bindMethods(@) @kanbanUserstoriesService.reset() @.openFilter = false @@ -237,20 +238,21 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi ]) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.is_kanban_activated - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.projectId = project.id - @scope.points = _.sortBy(project.points, "order") - @scope.pointsById = groupBy(project.points, (x) -> x.id) - @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) - @scope.usStatusList = _.sortBy(project.us_statuses, "order") + if not project.is_kanban_activated + @errorHandlingService.permissionDenied() - @scope.$emit("project:loaded", project) - return project + @scope.projectId = project.id + @scope.project = project + @scope.projectId = project.id + @scope.points = _.sortBy(project.points, "order") + @scope.pointsById = groupBy(project.points, (x) -> x.id) + @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) + @scope.usStatusList = _.sortBy(project.us_statuses, "order") + + @scope.$emit("project:loaded", project) + return project initializeSubscription: -> routingKey1 = "changes.project.#{@scope.projectId}.userstories" @@ -258,12 +260,12 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @.loadUserstories() loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.initializeSubscription() - @.loadKanban() - @.generateFilters() + project = @.loadProject() + + @.fillUsersAndRoles(project.members, project.roles) + @.initializeSubscription() + @.loadKanban() + @.generateFilters() # Utils methods diff --git a/app/coffee/modules/search.coffee b/app/coffee/modules/search.coffee index 37cf51bc..5eb43aa8 100644 --- a/app/coffee/modules/search.coffee +++ b/app/coffee/modules/search.coffee @@ -49,23 +49,22 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin) "tgAppMetaService", "$tgNavUrls", "$translate", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] - constructor: (@scope, @repo, @rs, @params, @q, @location, @appMetaService, @navUrls, @translate, @errorHandlingService) -> + constructor: (@scope, @repo, @rs, @params, @q, @location, @appMetaService, @navUrls, @translate, @errorHandlingService, @projectService) -> @scope.sectionName = "Search" - promise = @.loadInitialData() + @.loadInitialData() - promise.then () => - title = @translate.instant("SEARCH.PAGE_TITLE", {projectName: @scope.project.name}) - description = @translate.instant("SEARCH.PAGE_DESCRIPTION", { - projectName: @scope.project.name, - projectDescription: @scope.project.description - }) - @appMetaService.setAll(title, description) + title = @translate.instant("SEARCH.PAGE_TITLE", {projectName: @scope.project.name}) + description = @translate.instant("SEARCH.PAGE_DESCRIPTION", { + projectName: @scope.project.name, + projectDescription: @scope.project.description + }) - promise.then null, @.onInitialDataError.bind(@) + @appMetaService.setAll(title, description) # Search input watcher @scope.searchTerm = null @@ -85,17 +84,18 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin) return defered.promise loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.project = project - @scope.$emit('project:loaded', project) + project = @projectService.project.toJS() - @scope.epicStatusById = groupBy(project.epic_statuses, (x) -> x.id) - @scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id) - @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id) - @scope.severityById = groupBy(project.severities, (x) -> x.id) - @scope.priorityById = groupBy(project.priorities, (x) -> x.id) - @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) - return project + @scope.project = project + @scope.$emit('project:loaded', project) + + @scope.epicStatusById = groupBy(project.epic_statuses, (x) -> x.id) + @scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id) + @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id) + @scope.severityById = groupBy(project.severities, (x) -> x.id) + @scope.priorityById = groupBy(project.priorities, (x) -> x.id) + @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) + return project loadSearchData: (term = "") -> @scope.loading = true @@ -112,9 +112,10 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin) return @._promise loadInitialData: -> - return @.loadProject().then (project) => - @scope.projectId = project.id - @.fillUsersAndRoles(project.members, project.roles) + project = @.loadProject() + + @scope.projectId = project.id + @.fillUsersAndRoles(project.members, project.roles) module.controller("SearchController", SearchController) diff --git a/app/coffee/modules/tasks/detail.coffee b/app/coffee/modules/tasks/detail.coffee index 2e9ae523..c3cc8339 100644 --- a/app/coffee/modules/tasks/detail.coffee +++ b/app/coffee/modules/tasks/detail.coffee @@ -51,11 +51,12 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) "$tgAnalytics", "$translate", "$tgQueueModelTransformation", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, - @log, @appMetaService, @navUrls, @analytics, @translate, @modelTransform, @errorHandlingService) -> + @log, @appMetaService, @navUrls, @analytics, @translate, @modelTransform, @errorHandlingService, @projectService) -> bindMethods(@) @scope.taskRef = @params.taskref @@ -106,13 +107,14 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.onDeleteGoToUrl = @navUrls.resolve("project-userstories-detail", ctx) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - @scope.statusList = project.task_statuses - @scope.statusById = groupBy(project.task_statuses, (x) -> x.id) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + @scope.statusList = project.task_statuses + @scope.statusById = groupBy(project.task_statuses, (x) -> x.id) + return project loadTask: -> return @rs.tasks.getByRef(@scope.projectId, @params.taskref).then (task) => @@ -150,10 +152,10 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) return us loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.loadTask().then(=> @q.all([@.loadSprint(), @.loadUserStory()])) + project = @.loadProject() + + @.fillUsersAndRoles(project.members, project.roles) + return @.loadTask().then(=> @q.all([@.loadSprint(), @.loadUserStory()])) ### # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. diff --git a/app/coffee/modules/team/main.coffee b/app/coffee/modules/team/main.coffee index e11a4769..becdf04a 100644 --- a/app/coffee/modules/team/main.coffee +++ b/app/coffee/modules/team/main.coffee @@ -88,17 +88,18 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.memberships = _.reject(@scope.activeUsers, {id: user?.id}) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) + project = @projectService.project.toJS() - @scope.issuesEnabled = project.is_issues_activated - @scope.tasksEnabled = project.is_kanban_activated or project.is_backlog_activated - @scope.wikiEnabled = project.is_wiki_activated - @scope.owner = project.owner.id + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) - return project + @scope.issuesEnabled = project.is_issues_activated + @scope.tasksEnabled = project.is_kanban_activated or project.is_backlog_activated + @scope.wikiEnabled = project.is_wiki_activated + @scope.owner = project.owner.id + + return project loadMemberStats: -> return @rs.projects.memberStats(@scope.projectId).then (stats) => @@ -132,16 +133,16 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) return stats loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.loadMembers() + project = @.loadProject() - userRoles = _.map @scope.users, (user) -> user.role + @.fillUsersAndRoles(project.members, project.roles) + @.loadMembers() - @scope.roles = _.filter @scope.roles, (role) -> userRoles.indexOf(role.id) != -1 + userRoles = _.map @scope.users, (user) -> user.role - return @.loadMemberStats() + @scope.roles = _.filter @scope.roles, (role) -> userRoles.indexOf(role.id) != -1 + + return @.loadMemberStats() module.controller("TeamController", TeamController) diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index 950185df..b75a10e0 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -52,11 +52,12 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) "$translate", "$tgQueueModelTransformation", "tgErrorHandlingService", - "$tgConfig" + "$tgConfig", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, - @log, @appMetaService, @navUrls, @analytics, @translate, @modelTransform, @errorHandlingService, @configService) -> + @log, @appMetaService, @navUrls, @analytics, @translate, @modelTransform, @errorHandlingService, @configService, @projectService) -> bindMethods(@) @scope.usRef = @params.usref @@ -123,16 +124,17 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.onDeleteGoToUrl = @navUrls.resolve("project-kanban", ctx) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - @scope.statusList = project.us_statuses - @scope.statusById = groupBy(project.us_statuses, (x) -> x.id) - @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id) - @scope.pointsList = _.sortBy(project.points, "order") - @scope.pointsById = groupBy(@scope.pointsList, (e) -> e.id) - return project + project = @projectService.project.toJS() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + @scope.statusList = project.us_statuses + @scope.statusById = groupBy(project.us_statuses, (x) -> x.id) + @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id) + @scope.pointsList = _.sortBy(project.points, "order") + @scope.pointsById = groupBy(@scope.pointsList, (e) -> e.id) + return project loadUs: -> httpParams = _.pick(@location.search(), "milestone", "no-milestone", "kanban-status") @@ -180,10 +182,9 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) return tasks loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @.loadUs().then(=> @q.all([@.loadSprint(), @.loadTasks()])) + project = @.loadProject() + @.fillUsersAndRoles(project.members, project.roles) + @.loadUs().then(=> @q.all([@.loadSprint(), @.loadTasks()])) ### # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 4100a233..daee9ada 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -52,11 +52,12 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) "$tgNavUrls", "$tgAnalytics", "$translate", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location, - @filter, @log, @appMetaService, @navUrls, @analytics, @translate, @errorHandlingService) -> + @filter, @log, @appMetaService, @navUrls, @analytics, @translate, @errorHandlingService, @projectService) -> @scope.$on("wiki:links:move", @.moveLink) @scope.projectSlug = @params.pslug @scope.wikiSlug = @params.slug @@ -86,14 +87,15 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @appMetaService.setAll(title, description) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.is_wiki_activated - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + if not project.is_wiki_activated + @errorHandlingService.permissionDenied() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + return project loadWiki: -> promise = @rs.wiki.getBySlug(@scope.projectId, @params.slug) @@ -130,10 +132,10 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.wikiTitle = selectedWikiLink.title if selectedWikiLink? loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @q.all([@.loadWikiLinks(), @.loadWiki()]).then @.checkLinksPerms.bind(this) + project = @.loadProject() + + @.fillUsersAndRoles(project.members, project.roles) + @q.all([@.loadWikiLinks(), @.loadWiki()]).then @.checkLinksPerms.bind(this) checkLinksPerms: -> if @scope.project.my_permissions.indexOf("add_wiki_link") != -1 || diff --git a/app/coffee/modules/wiki/pages-list.coffee b/app/coffee/modules/wiki/pages-list.coffee index 5aaddb8c..ea85317f 100644 --- a/app/coffee/modules/wiki/pages-list.coffee +++ b/app/coffee/modules/wiki/pages-list.coffee @@ -43,11 +43,12 @@ class WikiPagesListController extends mixOf(taiga.Controller, taiga.PageMixin) "$routeParams", "$q", "$tgNavUrls", - "tgErrorHandlingService" + "tgErrorHandlingService", + "tgProjectService" ] constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, - @navUrls, @errorHandlingService) -> + @navUrls, @errorHandlingService, @projectService) -> @scope.projectSlug = @params.pslug @scope.wikiSlug = @params.slug @scope.wikiTitle = @scope.wikiSlug @@ -60,14 +61,16 @@ class WikiPagesListController extends mixOf(taiga.Controller, taiga.PageMixin) promise.then null, @.onInitialDataError.bind(@) loadProject: -> - return @rs.projects.getBySlug(@params.pslug).then (project) => - if not project.is_wiki_activated - @errorHandlingService.permissionDenied() + project = @projectService.project.toJS() - @scope.projectId = project.id - @scope.project = project - @scope.$emit('project:loaded', project) - return project + if not project.is_wiki_activated + @errorHandlingService.permissionDenied() + + @scope.projectId = project.id + @scope.project = project + @scope.$emit('project:loaded', project) + + return project loadWikiPages: -> promise = @rs.wiki.list(@scope.projectId).then (wikipages) => @@ -87,10 +90,11 @@ class WikiPagesListController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.wikiTitle = selectedWikiLink.title if selectedWikiLink? loadInitialData: -> - promise = @.loadProject() - return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) - @q.all([@.loadWikiLinks(), @.loadWikiPages()]).then @.checkLinksPerms.bind(this) + project = @.loadProject() + + @.fillUsersAndRoles(project.members, project.roles) + + @q.all([@.loadWikiLinks(), @.loadWikiPages()]).then(@.checkLinksPerms.bind(this)) checkLinksPerms: -> if @scope.project.my_permissions.indexOf("add_wiki_link") != -1 || diff --git a/app/modules/services/project.service.coffee b/app/modules/services/project.service.coffee index 649147b4..8e2e1906 100644 --- a/app/modules/services/project.service.coffee +++ b/app/modules/services/project.service.coffee @@ -22,10 +22,12 @@ taiga = @.taiga class ProjectService @.$inject = [ "tgProjectsService", - "tgXhrErrorService" + "tgXhrErrorService", + "tgUserActivityService", + "$interval" ] - constructor: (@projectsService, @xhrError) -> + constructor: (@projectsService, @xhrError, @userActivityService, @interval) -> @._project = null @._section = null @._sectionsBreadcrumb = Immutable.List() @@ -36,12 +38,24 @@ class ProjectService taiga.defineImmutableProperty @, "sectionsBreadcrumb", () => return @._sectionsBreadcrumb taiga.defineImmutableProperty @, "activeMembers", () => return @._activeMembers + @.autoRefresh() + cleanProject: () -> @._project = null @._activeMembers = Immutable.List() @._section = null @._sectionsBreadcrumb = Immutable.List() + autoRefresh: () -> + intervalId = @interval () => + @.fetchProject() + , 60 * 10 * 1000 + + @userActivityService.onInactive () => @interval.cancel(intervalId) + @userActivityService.onActive () => + @.fetchProject() + @.autoRefresh() + setSection: (section) -> @._section = section @@ -68,6 +82,8 @@ class ProjectService else resolve() fetchProject: () -> + return if !@.project + pslug = @.project.get('slug') return @projectsService.getProjectBySlug(pslug).then (project) => @.setProject(project) diff --git a/app/modules/services/project.service.spec.coffee b/app/modules/services/project.service.spec.coffee index 20f529d1..52480b05 100644 --- a/app/modules/services/project.service.spec.coffee +++ b/app/modules/services/project.service.spec.coffee @@ -19,6 +19,7 @@ describe "tgProjectService", -> $provide = null + $interval = null mocks = {} projectService = null @@ -29,6 +30,14 @@ describe "tgProjectService", -> $provide.value "tgProjectsService", mocks.projectsService + _mockUserActivityService = () -> + mocks.userActivityService = { + onInactive: sinon.stub(), + onActive: sinon.stub() + } + + $provide.value "tgUserActivityService", mocks.userActivityService + _mockXhrErrorService = () -> mocks.xhrErrorService = { response: sinon.stub() @@ -42,6 +51,7 @@ describe "tgProjectService", -> _mockProjectsService() _mockXhrErrorService() + _mockUserActivityService() return null @@ -49,8 +59,9 @@ describe "tgProjectService", -> _mocks() _inject = () -> - inject (_tgProjectService_) -> + inject (_tgProjectService_, _$interval_) -> projectService = _tgProjectService_ + $interval = _$interval_ beforeEach -> module "taigaCommon" @@ -157,3 +168,35 @@ describe "tgProjectService", -> expect(perm1).to.be.true expect(perm2).to.be.false + + it "autorefresh project interval", () -> + projectService.fetchProject = sinon.spy() + + expect(projectService.fetchProject).not.to.have.been.called + + $interval.flush(60 * 11 * 1000) + + expect(projectService.fetchProject).to.have.been.called + + it "cancel interval on user inactivity", () -> + $interval.cancel = sinon.spy() + + projectService.fetchProject = sinon.spy() + + expect($interval.cancel).not.to.have.been.called + + mocks.userActivityService.onInactive.callArg(0) + + expect($interval.cancel).to.have.been.called + + it "fech project if the user restars the activity", () -> + projectService.fetchProject = sinon.spy() + projectService.autoRefresh = sinon.spy() + + expect(projectService.fetchProject).not.to.have.been.called + expect(projectService.autoRefresh).not.to.have.been.called + + mocks.userActivityService.onActive.callArg(0) + + expect(projectService.fetchProject).to.have.been.called + expect(projectService.autoRefresh).to.have.been.called diff --git a/app/modules/services/user-activity.service.coffee b/app/modules/services/user-activity.service.coffee new file mode 100644 index 00000000..07e4afd6 --- /dev/null +++ b/app/modules/services/user-activity.service.coffee @@ -0,0 +1,77 @@ +### +# Copyright (C) 2014-2016 Taiga Agile LLC +# +# 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: user-activity.service.coffee +### + +taiga = @.taiga + +groupBy = @.taiga.groupBy + +class UserActivityService + @.$inject = ['$timeout'] + + idleTimeout: 60 * 5 * 1000 + + constructor: (@timeout) -> + window.addEventListener('mousemove', @.resetTimer.bind(this), false) + window.addEventListener('mousedown', @.resetTimer.bind(this), false) + window.addEventListener('keypress', @.resetTimer.bind(this), false) + window.addEventListener('mousewheel', @.resetTimer.bind(this), false) + window.addEventListener('touchmove', @.resetTimer.bind(this), false) + + @.subscriptionsActive = [] + @.subscriptionsInactive = [] + @.isActive = true + + @.startTimer() + + startTimer: () -> + @.timerId = @timeout(@._fireInactive.bind(this), @.idleTimeout) + + resetTimer: () -> + if !@.isActive + @._fireActive() + + @timeout.cancel(@.timerId) + @.startTimer() + + @.isActive = true + + onActive: (cb) -> + @.subscriptionsActive.push(cb) + + return @._unSubscriptionsActive.bind(this, cb) + + onInactive: (cb) -> + @.subscriptionsInactive.push(cb) + + return @._unSubscriptionsInactive.bind(this, cb) + + _fireActive: () -> + @.subscriptionsActive.forEach (it) -> it() + + _fireInactive: () -> + @.isActive = false + @.subscriptionsInactive.forEach (it) -> it() + + _unSubscriptionsActive: (cb) -> + @.subscriptionsActive = @.subscriptionsActive.filter (fn) -> fn != cb + + _unSubscriptionsInactive: (cb) -> + @.subscriptionsInactive = @.subscriptionsInactive.filter (fn) -> fn != cb + +angular.module("taigaCommon").service("tgUserActivityService", UserActivityService) diff --git a/app/modules/services/user-activity.service.spec.coffee b/app/modules/services/user-activity.service.spec.coffee new file mode 100644 index 00000000..7b4309e4 --- /dev/null +++ b/app/modules/services/user-activity.service.spec.coffee @@ -0,0 +1,79 @@ +### +# Copyright (C) 2014-2016 Taiga Agile LLC +# +# 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: app-meta.service.spec.coffee +### + +angular.module("taigaCommon").provider("$exceptionHandler", angular.mock.$ExceptionHandlerProvider) + +describe "UserActivityService", -> + userActivityService = null + $timeout = null + + _inject = () -> + inject (_tgUserActivityService_, _$timeout_) -> + userActivityService = _tgUserActivityService_ + $timeout = _$timeout_ + + beforeEach -> + module "taigaCommon" + _inject() + + it "inactive", (done) -> + active = sinon.spy() + userActivityService.onInactive () -> + expect(active).not.to.have.been.called; + done() + + userActivityService.onActive(active) + + $timeout.flush() + + it "unsubscribe inactive", (done) -> + unsubscribe = userActivityService.onInactive () -> + unsubscribe() + + expect(userActivityService.subscriptionsInactive).to.have.length(0) + + done() + + expect(userActivityService.subscriptionsInactive).to.have.length(1) + + $timeout.flush() + + it "active", (done) -> + inactive = sinon.spy() + userActivityService.onInactive(inactive) + + userActivityService.onActive () -> + expect(inactive).to.have.been.called; + done() + + $timeout.flush() + userActivityService.resetTimer() + + it "unsubscribe active", (done) -> + unsubscribe = userActivityService.onActive () -> + unsubscribe() + + expect(userActivityService.subscriptionsActive).to.have.length(0) + + done() + + expect(userActivityService.subscriptionsActive).to.have.length(1) + + $timeout.flush() + userActivityService.resetTimer()