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", "$translate",
"$tgAuth", "$tgAuth",
"tgLightboxFactory", "tgLightboxFactory",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @analytics, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @analytics,
@appMetaService, @translate, @auth, @lightboxFactory, @errorHandlingService) -> @appMetaService, @translate, @auth, @lightboxFactory, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.project = {} @scope.project = {}
@ -74,7 +75,8 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
@analytics.trackEvent("membership", "create", "create memberships on admin", 1) @analytics.trackEvent("membership", "create", "create memberships on admin", 1)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin if not project.i_am_admin
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -99,7 +101,8 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
return data return data
loadInitialData: -> loadInitialData: ->
return @.loadProject().then () => @.loadProject()
return @q.all([ return @q.all([
@.loadMembers(), @.loadMembers(),
@auth.refresh() @auth.refresh()

View File

@ -54,15 +54,17 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
"$translate", "$translate",
"$tgAuth", "$tgAuth",
"tgCurrentUserService", "tgCurrentUserService",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService",
"$tgModel"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
@appMetaService, @translate, @tgAuth, @currentUserService, @errorHandlingService) -> @appMetaService, @translate, @tgAuth, @currentUserService, @errorHandlingService, @projectService, @model) ->
@scope.project = {} @scope.project = {}
promise = @.loadInitialData()
@scope.projectTags = [] @scope.projectTags = []
promise = @.loadInitialData()
promise.then => promise.then =>
sectionName = @translate.instant( @scope.sectionName) sectionName = @translate.instant( @scope.sectionName)
@ -83,7 +85,9 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
@appMetaService.setAll(title, description) @appMetaService.setAll(title, description)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
project = @model.make_model("projects", project)
if not project.i_am_admin if not project.i_am_admin
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -105,10 +109,9 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
return project return project
loadInitialData: -> loadInitialData: ->
return @q.all([ @.loadProject()
@.loadProject(),
@tgAuth.refresh() return @tgAuth.refresh()
])
openDeleteLightbox: -> openDeleteLightbox: ->
@rootscope.$broadcast("deletelightbox:new", @scope.project) @rootscope.$broadcast("deletelightbox:new", @scope.project)
@ -158,9 +161,9 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
}) })
$location.path(newUrl) $location.path(newUrl)
projectService.fetchProject().then () =>
$ctrl.loadInitialData() $ctrl.loadInitialData()
projectService.fetchProject()
currentUserService.loadProjects() currentUserService.loadProjects()
promise.then null, (data) -> promise.then null, (data) ->

View File

@ -53,29 +53,29 @@ class ProjectValuesSectionController extends mixOf(taiga.Controller, taiga.PageM
"$tgNavUrls", "$tgNavUrls",
"tgAppMetaService", "tgAppMetaService",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
@appMetaService, @translate, @errorHandlingService) -> @appMetaService, @translate, @errorHandlingService, @projectService) ->
@scope.project = {} @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", { title = @translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", {
"sectionName": sectionName, "sectionName": sectionName,
"projectName": @scope.project.name "projectName": @scope.project.name
}) })
description = @scope.project.description description = @scope.project.description
@appMetaService.setAll(title, description) @appMetaService.setAll(title, description)
promise.then null, @.onInitialDataError.bind(@)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin if not project.i_am_admin
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -106,8 +106,11 @@ class ProjectValuesController extends taiga.Controller
constructor: (@scope, @rootscope, @repo, @confirm, @rs) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs) ->
@scope.$on("admin:project-values:move", @.moveValue) @scope.$on("admin:project-values:move", @.moveValue)
@rootscope.$on("project:loaded", @.loadValues)
unwatch = @scope.$watch "resource", (resource) =>
if resource
@.loadValues()
unwatch()
loadValues: => loadValues: =>
return @rs[@scope.resource].listValues(@scope.projectId, @scope.type).then (values) => return @rs[@scope.resource].listValues(@scope.projectId, @scope.type).then (values) =>
@scope.values = values @scope.values = values

View File

@ -49,11 +49,12 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
"$tgNavUrls", "$tgNavUrls",
"tgAppMetaService", "tgAppMetaService",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
@appMetaService, @translate, @errorHandlingService) -> @appMetaService, @translate, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "ADMIN.MENU.PERMISSIONS" @scope.sectionName = "ADMIN.MENU.PERMISSIONS"
@ -70,7 +71,8 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin if not project.i_am_admin
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -103,9 +105,12 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
return roles return roles
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadRoles()) return @.loadRoles()
return promise
forceLoadProject: () ->
@projectService.fetchProject () =>
@.loadProject()
setRole: (role) -> setRole: (role) ->
@scope.role = 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") warning = @translate.instant("ADMIN.ROLES.WARNING_DELETE_ROLE")
return @confirm.askChoice(title, subtitle, choices, replacement, warning).then (response) => return @confirm.askChoice(title, subtitle, choices, replacement, warning).then (response) =>
onSuccess = => onSuccess = =>
@.loadProject() @.forceLoadProject()
@.loadRoles().finally => @.loadRoles().finally =>
response.finish() response.finish()
onError = => onError = =>
@ -137,7 +142,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
_enableComputable: => _enableComputable: =>
onSuccess = => onSuccess = =>
@confirm.notify("success") @confirm.notify("success")
@.loadProject() @.forceLoadProject()
onError = => onError = =>
@confirm.notify("error") @confirm.notify("error")
@ -150,7 +155,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
onSuccess = => onSuccess = =>
response.finish() response.finish()
@confirm.notify("success") @confirm.notify("success")
@.loadProject() @.forceLoadProject()
onError = => onError = =>
response.finish() response.finish()
@confirm.notify("error") @confirm.notify("error")
@ -264,7 +269,7 @@ NewRoleDirective = ($tgrepo, $confirm) ->
$scope.roles.splice(insertPosition, 0, role) $scope.roles.splice(insertPosition, 0, role)
$ctrl.setRole(role) $ctrl.setRole(role)
$el.find(".add-button").show() $el.find(".add-button").show()
$ctrl.loadProject() $ctrl.forceLoadProject()
onError = -> onError = ->
$confirm.notify("error") $confirm.notify("error")
@ -474,7 +479,7 @@ RolePermissionsDirective = ($rootscope, $repo, $confirm, $compile) ->
renderResume(target.parents(".category-config"), categories[categoryId]) renderResume(target.parents(".category-config"), categories[categoryId])
$rootscope.$broadcast("projects:reload") $rootscope.$broadcast("projects:reload")
$confirm.notify("success") $confirm.notify("success")
$ctrl.loadProject() $ctrl.forceLoadProject()
onError = -> onError = ->
$confirm.notify("error") $confirm.notify("error")

View File

@ -46,10 +46,11 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
"$tgNavUrls", "$tgNavUrls",
"tgAppMetaService", "tgAppMetaService",
"$translate", "$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(@) bindMethods(@)
@scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME" @scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME"
@ -71,7 +72,8 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
@scope.webhooks = webhooks @scope.webhooks = webhooks
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin if not project.i_am_admin
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -81,11 +83,9 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
return project return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then =>
@.loadWebhooks()
return promise return @.loadWebhooks()
module.controller("WebhooksController", WebhooksController) module.controller("WebhooksController", WebhooksController)
@ -309,10 +309,11 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME") @scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME")
@ -332,7 +333,8 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.github = github @scope.github = github
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -340,8 +342,7 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() promise = @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("GithubController", GithubController) module.controller("GithubController", GithubController)
@ -357,10 +358,11 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.GITLAB.SECTION_NAME") @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 @scope.gitlab = gitlab
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
return project return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("GitlabController", GitlabController) module.controller("GitlabController", GitlabController)
@ -407,10 +409,11 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME") @scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME")
@ -432,16 +435,16 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
@scope.bitbucket = bitbucket @scope.bitbucket = bitbucket
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
return project return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("BitbucketController", BitbucketController) module.controller("BitbucketController", BitbucketController)
@ -598,10 +601,11 @@ class GogsController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Filt
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.GOGS.SECTION_NAME") @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 @scope.gogs = gogs
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
return project return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("GogsController", GogsController) module.controller("GogsController", GogsController)

View File

@ -59,7 +59,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService", "tgErrorHandlingService",
"$tgStorage", "$tgStorage",
"tgFilterRemoteStorageService" "tgFilterRemoteStorageService",
"tgProjectService"
] ]
storeCustomFiltersName: 'backlog-custom-filters' 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, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @appMetaService, @navUrls,
@events, @analytics, @translate, @loading, @rs2, @modelTransform, @errorHandlingService, @events, @analytics, @translate, @loading, @rs2, @modelTransform, @errorHandlingService,
@storage, @filterRemoteStorageService) -> @storage, @filterRemoteStorageService, @projectService) ->
bindMethods(@) bindMethods(@)
@.backlogOrder = {} @.backlogOrder = {}
@ -341,7 +342,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
break break
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_backlog_activated if not project.is_backlog_activated
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -353,16 +355,16 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@scope.pointsById = groupBy(project.points, (x) -> x.id) @scope.pointsById = groupBy(project.points, (x) -> x.id)
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id)
@scope.usStatusList = _.sortBy(project.us_statuses, "id") @scope.usStatusList = _.sortBy(project.us_statuses, "id")
return project return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription() @.initializeSubscription()
return promise return @.loadBacklog()
.then(=> @.loadBacklog())
.then(=> @.generateFilters()) .then(=> @.generateFilters())
.then(=> @scope.$emit("backlog:loaded")) .then(=> @scope.$emit("backlog:loaded"))

View File

@ -32,20 +32,19 @@ class ContribController extends taiga.Controller
"$routeParams", "$routeParams",
"$tgRepo", "$tgRepo",
"$tgResources", "$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.currentPlugin = _.head(_.filter(@rootScope.adminPlugins, {"slug": @params.plugin}))
@scope.projectSlug = @params.pslug @scope.projectSlug = @params.pslug
promise = @.loadInitialData() @.loadInitialData()
promise.then null, =>
@confirm.notify("error")
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)

View File

@ -54,11 +54,12 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgNavUrls", "$tgNavUrls",
"$translate", "$translate",
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location, 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(@) bindMethods(@)
@scope.epicRef = @params.epicref @scope.epicRef = @params.epicref
@ -102,10 +103,11 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.onDeleteGoToUrl = @navUrls.resolve("project-epics", ctx) @scope.onDeleteGoToUrl = @navUrls.resolve("project-epics", ctx)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.immutableProject = Immutable.fromJS(project._attrs) @scope.immutableProject = @projectService.project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@scope.statusList = project.epic_statuses @scope.statusList = project.epic_statuses
@scope.statusById = groupBy(project.epic_statuses, (x) -> x.id) @scope.statusById = groupBy(project.epic_statuses, (x) -> x.id)
@ -139,8 +141,8 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.userstories = data @scope.userstories = data
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadEpic().then(=> @.loadUserstories()) @.loadEpic().then(=> @.loadUserstories())

View File

@ -53,11 +53,12 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgNavUrls", "$tgNavUrls",
"$translate", "$translate",
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, 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(@) bindMethods(@)
@scope.issueRef = @params.issueref @scope.issueRef = @params.issueref
@ -112,7 +113,8 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.onDeleteGoToUrl = @navUrls.resolve("project", ctx) @scope.onDeleteGoToUrl = @navUrls.resolve("project", ctx)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -149,10 +151,11 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.nextUrl = @navUrls.resolve("project-issues-detail", ctx) @scope.nextUrl = @navUrls.resolve("project-issues-detail", ctx)
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadIssue()
return @.loadIssue()
### ###
# Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. # 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", "$translate",
"tgErrorHandlingService", "tgErrorHandlingService",
"$tgStorage", "$tgStorage",
"tgFilterRemoteStorageService" "tgFilterRemoteStorageService",
"tgProjectService",
"tgUserActivityService"
] ]
filtersHashSuffix: "issues-filters" filtersHashSuffix: "issues-filters"
myFiltersHashSuffix: "issues-my-filters" myFiltersHashSuffix: "issues-my-filters"
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @urls, @params, @q, @location, @appMetaService, 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(@) bindMethods(@)
@scope.sectionName = "Issues" @scope.sectionName = "Issues"
@ -286,7 +288,8 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_issues_activated if not project.is_issues_activated
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -328,8 +331,8 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
return promise return promise
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription() @.initializeSubscription()
@.generateFilters() @.generateFilters()

View File

@ -58,7 +58,8 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgModel", "$tgModel",
"tgKanbanUserstories", "tgKanbanUserstories",
"$tgStorage", "$tgStorage",
"tgFilterRemoteStorageService" "tgFilterRemoteStorageService",
"tgProjectService"
] ]
storeCustomFiltersName: 'kanban-custom-filters' 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, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location,
@appMetaService, @navUrls, @events, @analytics, @translate, @errorHandlingService, @appMetaService, @navUrls, @events, @analytics, @translate, @errorHandlingService,
@model, @kanbanUserstoriesService, @storage, @filterRemoteStorageService) -> @model, @kanbanUserstoriesService, @storage, @filterRemoteStorageService, @projectService) ->
bindMethods(@) bindMethods(@)
@kanbanUserstoriesService.reset() @kanbanUserstoriesService.reset()
@.openFilter = false @.openFilter = false
@ -237,7 +238,8 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
]) ])
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_kanban_activated if not project.is_kanban_activated
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -258,8 +260,8 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@.loadUserstories() @.loadUserstories()
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription() @.initializeSubscription()
@.loadKanban() @.loadKanban()

View File

@ -49,23 +49,22 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
"tgAppMetaService", "tgAppMetaService",
"$tgNavUrls", "$tgNavUrls",
"$translate", "$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" @scope.sectionName = "Search"
promise = @.loadInitialData() @.loadInitialData()
promise.then () =>
title = @translate.instant("SEARCH.PAGE_TITLE", {projectName: @scope.project.name}) title = @translate.instant("SEARCH.PAGE_TITLE", {projectName: @scope.project.name})
description = @translate.instant("SEARCH.PAGE_DESCRIPTION", { description = @translate.instant("SEARCH.PAGE_DESCRIPTION", {
projectName: @scope.project.name, projectName: @scope.project.name,
projectDescription: @scope.project.description projectDescription: @scope.project.description
}) })
@appMetaService.setAll(title, description)
promise.then null, @.onInitialDataError.bind(@) @appMetaService.setAll(title, description)
# Search input watcher # Search input watcher
@scope.searchTerm = null @scope.searchTerm = null
@ -85,7 +84,8 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
return defered.promise return defered.promise
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -112,7 +112,8 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
return @._promise return @._promise
loadInitialData: -> loadInitialData: ->
return @.loadProject().then (project) => project = @.loadProject()
@scope.projectId = project.id @scope.projectId = project.id
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)

View File

@ -51,11 +51,12 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgAnalytics", "$tgAnalytics",
"$translate", "$translate",
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, 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(@) bindMethods(@)
@scope.taskRef = @params.taskref @scope.taskRef = @params.taskref
@ -106,7 +107,8 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.onDeleteGoToUrl = @navUrls.resolve("project-userstories-detail", ctx) @scope.onDeleteGoToUrl = @navUrls.resolve("project-userstories-detail", ctx)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -150,10 +152,10 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
return us return us
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadTask().then(=> @q.all([@.loadSprint(), @.loadUserStory()])) return @.loadTask().then(=> @q.all([@.loadSprint(), @.loadUserStory()]))
### ###
# Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button.

View File

@ -88,7 +88,8 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.memberships = _.reject(@scope.activeUsers, {id: user?.id}) @scope.memberships = _.reject(@scope.activeUsers, {id: user?.id})
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -132,8 +133,8 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin)
return stats return stats
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadMembers() @.loadMembers()

View File

@ -52,11 +52,12 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$translate", "$translate",
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService", "tgErrorHandlingService",
"$tgConfig" "$tgConfig",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, 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(@) bindMethods(@)
@scope.usRef = @params.usref @scope.usRef = @params.usref
@ -123,7 +124,8 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.onDeleteGoToUrl = @navUrls.resolve("project-kanban", ctx) @scope.onDeleteGoToUrl = @navUrls.resolve("project-kanban", ctx)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -180,8 +182,7 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
return tasks return tasks
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadUs().then(=> @q.all([@.loadSprint(), @.loadTasks()])) @.loadUs().then(=> @q.all([@.loadSprint(), @.loadTasks()]))

View File

@ -52,11 +52,12 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgNavUrls", "$tgNavUrls",
"$tgAnalytics", "$tgAnalytics",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location, 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.$on("wiki:links:move", @.moveLink)
@scope.projectSlug = @params.pslug @scope.projectSlug = @params.pslug
@scope.wikiSlug = @params.slug @scope.wikiSlug = @params.slug
@ -86,7 +87,8 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@appMetaService.setAll(title, description) @appMetaService.setAll(title, description)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_wiki_activated if not project.is_wiki_activated
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@ -130,8 +132,8 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.wikiTitle = selectedWikiLink.title if selectedWikiLink? @scope.wikiTitle = selectedWikiLink.title if selectedWikiLink?
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@q.all([@.loadWikiLinks(), @.loadWiki()]).then @.checkLinksPerms.bind(this) @q.all([@.loadWikiLinks(), @.loadWiki()]).then @.checkLinksPerms.bind(this)

View File

@ -43,11 +43,12 @@ class WikiPagesListController extends mixOf(taiga.Controller, taiga.PageMixin)
"$routeParams", "$routeParams",
"$q", "$q",
"$tgNavUrls", "$tgNavUrls",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q,
@navUrls, @errorHandlingService) -> @navUrls, @errorHandlingService, @projectService) ->
@scope.projectSlug = @params.pslug @scope.projectSlug = @params.pslug
@scope.wikiSlug = @params.slug @scope.wikiSlug = @params.slug
@scope.wikiTitle = @scope.wikiSlug @scope.wikiTitle = @scope.wikiSlug
@ -60,13 +61,15 @@ class WikiPagesListController extends mixOf(taiga.Controller, taiga.PageMixin)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_wiki_activated if not project.is_wiki_activated
@errorHandlingService.permissionDenied() @errorHandlingService.permissionDenied()
@scope.projectId = project.id @scope.projectId = project.id
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
return project return project
loadWikiPages: -> loadWikiPages: ->
@ -87,10 +90,11 @@ class WikiPagesListController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.wikiTitle = selectedWikiLink.title if selectedWikiLink? @scope.wikiTitle = selectedWikiLink.title if selectedWikiLink?
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@q.all([@.loadWikiLinks(), @.loadWikiPages()]).then @.checkLinksPerms.bind(this)
@q.all([@.loadWikiLinks(), @.loadWikiPages()]).then(@.checkLinksPerms.bind(this))
checkLinksPerms: -> checkLinksPerms: ->
if @scope.project.my_permissions.indexOf("add_wiki_link") != -1 || if @scope.project.my_permissions.indexOf("add_wiki_link") != -1 ||

View File

@ -22,10 +22,12 @@ taiga = @.taiga
class ProjectService class ProjectService
@.$inject = [ @.$inject = [
"tgProjectsService", "tgProjectsService",
"tgXhrErrorService" "tgXhrErrorService",
"tgUserActivityService",
"$interval"
] ]
constructor: (@projectsService, @xhrError) -> constructor: (@projectsService, @xhrError, @userActivityService, @interval) ->
@._project = null @._project = null
@._section = null @._section = null
@._sectionsBreadcrumb = Immutable.List() @._sectionsBreadcrumb = Immutable.List()
@ -36,12 +38,24 @@ class ProjectService
taiga.defineImmutableProperty @, "sectionsBreadcrumb", () => return @._sectionsBreadcrumb taiga.defineImmutableProperty @, "sectionsBreadcrumb", () => return @._sectionsBreadcrumb
taiga.defineImmutableProperty @, "activeMembers", () => return @._activeMembers taiga.defineImmutableProperty @, "activeMembers", () => return @._activeMembers
@.autoRefresh()
cleanProject: () -> cleanProject: () ->
@._project = null @._project = null
@._activeMembers = Immutable.List() @._activeMembers = Immutable.List()
@._section = null @._section = null
@._sectionsBreadcrumb = Immutable.List() @._sectionsBreadcrumb = Immutable.List()
autoRefresh: () ->
intervalId = @interval () =>
@.fetchProject()
, 60 * 10 * 1000
@userActivityService.onInactive () => @interval.cancel(intervalId)
@userActivityService.onActive () =>
@.fetchProject()
@.autoRefresh()
setSection: (section) -> setSection: (section) ->
@._section = section @._section = section
@ -68,6 +82,8 @@ class ProjectService
else resolve() else resolve()
fetchProject: () -> fetchProject: () ->
return if !@.project
pslug = @.project.get('slug') pslug = @.project.get('slug')
return @projectsService.getProjectBySlug(pslug).then (project) => @.setProject(project) return @projectsService.getProjectBySlug(pslug).then (project) => @.setProject(project)

View File

@ -19,6 +19,7 @@
describe "tgProjectService", -> describe "tgProjectService", ->
$provide = null $provide = null
$interval = null
mocks = {} mocks = {}
projectService = null projectService = null
@ -29,6 +30,14 @@ describe "tgProjectService", ->
$provide.value "tgProjectsService", mocks.projectsService $provide.value "tgProjectsService", mocks.projectsService
_mockUserActivityService = () ->
mocks.userActivityService = {
onInactive: sinon.stub(),
onActive: sinon.stub()
}
$provide.value "tgUserActivityService", mocks.userActivityService
_mockXhrErrorService = () -> _mockXhrErrorService = () ->
mocks.xhrErrorService = { mocks.xhrErrorService = {
response: sinon.stub() response: sinon.stub()
@ -42,6 +51,7 @@ describe "tgProjectService", ->
_mockProjectsService() _mockProjectsService()
_mockXhrErrorService() _mockXhrErrorService()
_mockUserActivityService()
return null return null
@ -49,8 +59,9 @@ describe "tgProjectService", ->
_mocks() _mocks()
_inject = () -> _inject = () ->
inject (_tgProjectService_) -> inject (_tgProjectService_, _$interval_) ->
projectService = _tgProjectService_ projectService = _tgProjectService_
$interval = _$interval_
beforeEach -> beforeEach ->
module "taigaCommon" module "taigaCommon"
@ -157,3 +168,35 @@ describe "tgProjectService", ->
expect(perm1).to.be.true expect(perm1).to.be.true
expect(perm2).to.be.false 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()