only call api project every x minutes or when the user restarts their activity

stable
Juanfran 2016-11-17 14:46:26 +01:00 committed by Alejandro Alonso
parent 6fe028001e
commit 82b0323c4f
21 changed files with 592 additions and 337 deletions

View File

@ -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")

View File

@ -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) ->

View File

@ -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

View File

@ -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")

View File

@ -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)

View File

@ -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"))

View File

@ -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()

View File

@ -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.

View File

@ -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.

View File

@ -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: ->

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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 ||

View File

@ -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 ||

View File

@ -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)

View File

@ -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

View File

@ -0,0 +1,77 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# 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 <http://www.gnu.org/licenses/>.
#
# 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)

View File

@ -0,0 +1,79 @@
###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io>
#
# 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 <http://www.gnu.org/licenses/>.
#
# 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()