Migrate appTitle to tgAppMetaService
parent
000f5b8722
commit
54b779ff48
|
@ -17,6 +17,7 @@
|
|||
- Activity timeline
|
||||
- Global user configuration
|
||||
- User contacts
|
||||
- Improve SEO, fix meta tags and added social meta tags
|
||||
|
||||
### Misc
|
||||
- Improve performance: remove some unnecessary calls to the api.
|
||||
|
|
|
@ -28,21 +28,26 @@ taiga.generateHash = (components=[]) ->
|
|||
components = _.map(components, (x) -> JSON.stringify(x))
|
||||
return hex_sha1(components.join(":"))
|
||||
|
||||
|
||||
taiga.generateUniqueSessionIdentifier = ->
|
||||
date = (new Date()).getTime()
|
||||
randomNumber = Math.floor(Math.random() * 0x9000000)
|
||||
return taiga.generateHash([date, randomNumber])
|
||||
|
||||
|
||||
taiga.sessionId = taiga.generateUniqueSessionIdentifier()
|
||||
|
||||
configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, $compileProvider, $translateProvider) ->
|
||||
|
||||
configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider,
|
||||
$compileProvider, $translateProvider) ->
|
||||
$routeProvider.when("/",
|
||||
{
|
||||
templateUrl: "home/home.html",
|
||||
access: {
|
||||
requiresLogin: true
|
||||
},
|
||||
title: "PROJECT.WELCOME",
|
||||
title: "HOME.PAGE_TITLE",
|
||||
description: "HOME.PAGE_DESCRIPTION",
|
||||
loader: true
|
||||
}
|
||||
)
|
||||
|
@ -53,7 +58,8 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
|
|||
access: {
|
||||
requiresLogin: true
|
||||
},
|
||||
title: "PROJECT.SECTION_PROJECTS",
|
||||
title: "PROJECTS.PAGE_TITLE",
|
||||
description: "PROJECTS.PAGE_DESCRIPTION",
|
||||
loader: true,
|
||||
controller: "ProjectsListing",
|
||||
controllerAs: "vm"
|
||||
|
@ -305,17 +311,47 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
|
|||
|
||||
# Auth
|
||||
$routeProvider.when("/login",
|
||||
{templateUrl: "auth/login.html"})
|
||||
{
|
||||
templateUrl: "auth/login.html",
|
||||
title: "LOGIN.PAGE_TITLE"
|
||||
description: "LOGIN.PAGE_DESCRIPTION"
|
||||
}
|
||||
)
|
||||
$routeProvider.when("/register",
|
||||
{templateUrl: "auth/register.html"})
|
||||
{
|
||||
templateUrl: "auth/register.html",
|
||||
title: "REGISTER.PAGE_TITLE",
|
||||
description: "REGISTER.PAGE_DESCRIPTION"
|
||||
}
|
||||
)
|
||||
$routeProvider.when("/forgot-password",
|
||||
{templateUrl: "auth/forgot-password.html"})
|
||||
{
|
||||
templateUrl: "auth/forgot-password.html",
|
||||
title: "FORGOT_PASSWORD.PAGE_TITLE",
|
||||
description: "FORGOT_PASSWORD.PAGE_DESCRIPTION"
|
||||
}
|
||||
)
|
||||
$routeProvider.when("/change-password",
|
||||
{templateUrl: "auth/change-password-from-recovery.html"})
|
||||
{
|
||||
templateUrl: "auth/change-password-from-recovery.html",
|
||||
title: "CHANGE_PASSWORD.PAGE_TITLE",
|
||||
description: "CHANGE_PASSWORD.PAGE_TITLE",
|
||||
}
|
||||
)
|
||||
$routeProvider.when("/change-password/:token",
|
||||
{templateUrl: "auth/change-password-from-recovery.html"})
|
||||
{
|
||||
templateUrl: "auth/change-password-from-recovery.html",
|
||||
title: "CHANGE_PASSWORD.PAGE_TITLE",
|
||||
description: "CHANGE_PASSWORD.PAGE_TITLE",
|
||||
}
|
||||
)
|
||||
$routeProvider.when("/invitation/:token",
|
||||
{templateUrl: "auth/invitation.html"})
|
||||
{
|
||||
templateUrl: "auth/invitation.html",
|
||||
title: "INVITATION.PAGE_TITLE",
|
||||
description: "INVITATION.PAGE_DESCRIPTION"
|
||||
}
|
||||
)
|
||||
|
||||
# Errors/Exceptions
|
||||
$routeProvider.when("/error",
|
||||
|
@ -482,7 +518,7 @@ i18nInit = (lang, $translate) ->
|
|||
checksley.updateMessages('default', messages)
|
||||
|
||||
|
||||
init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $navUrls, $appTitle, projectService, loaderService) ->
|
||||
init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $navUrls, appMetaService, projectService, loaderService) ->
|
||||
$log.debug("Initialize application")
|
||||
|
||||
# Taiga Plugins
|
||||
|
@ -517,8 +553,11 @@ init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $na
|
|||
else
|
||||
projectService.cleanProject()
|
||||
|
||||
if next.title
|
||||
$translate(next.title).then (text) => $appTitle.set(text)
|
||||
if next.title or next.description
|
||||
title = next.title or ""
|
||||
description = next.description or ""
|
||||
$translate([title, description]).then (translations) =>
|
||||
appMetaService.setAll(translations[title], translations[description])
|
||||
|
||||
if next.loader
|
||||
loaderService.startWithAutoClose()
|
||||
|
@ -592,7 +631,7 @@ module.run([
|
|||
"$translate",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"tgProjectService",
|
||||
"tgLoader",
|
||||
init
|
||||
|
|
|
@ -43,11 +43,12 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
|
|||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$tgAnalytics",
|
||||
"$appTitle"
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q,
|
||||
@location, @navUrls, @analytics, @appTitle) ->
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @analytics,
|
||||
@appMetaService, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.project = {}
|
||||
|
@ -56,7 +57,9 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then =>
|
||||
@appTitle.set("Membership - " + @scope.project.name)
|
||||
title = @translate.instant("ADMIN.MEMBERSHIPS.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
@ -378,7 +381,9 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
|
|||
$el.on "click", ".pending", (event) ->
|
||||
event.preventDefault()
|
||||
onSuccess = ->
|
||||
text = $translate.instant("ADMIN.MEMBERSHIP.SUCCESS_SEND_INVITATION", {email: $scope.member.email})
|
||||
text = $translate.instant("ADMIN.MEMBERSHIP.SUCCESS_SEND_INVITATION", {
|
||||
email: $scope.member.email
|
||||
})
|
||||
$confirm.notify("success", text)
|
||||
onError = ->
|
||||
text = $translate.instant("ADMIM.MEMBERSHIP.ERROR_SEND_INVITATION")
|
||||
|
@ -415,4 +420,5 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
|
|||
return {link: link}
|
||||
|
||||
|
||||
module.directive("tgMembershipsRowActions", ["$log", "$tgRepo", "$tgResources", "$tgConfirm", "$compile", "$translate", MembershipsRowActionsDirective])
|
||||
module.directive("tgMembershipsRowActions", ["$log", "$tgRepo", "$tgResources", "$tgConfirm", "$compile",
|
||||
"$translate", MembershipsRowActionsDirective])
|
||||
|
|
|
@ -47,28 +47,31 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle, @translate) ->
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
|
||||
@appMetaService, @translate) ->
|
||||
@scope.project = {}
|
||||
|
||||
promise = @.loadInitialData()
|
||||
|
||||
promise.then =>
|
||||
sectionName = @translate.instant( @scope.sectionName)
|
||||
appTitle = @translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", {
|
||||
title = @translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", {
|
||||
sectionName: sectionName, projectName: @scope.project.name})
|
||||
@appTitle.set(appTitle)
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
@scope.$on "project:loaded", =>
|
||||
sectionName = @translate.instant(@scope.sectionName)
|
||||
appTitle = @translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", {
|
||||
title = @translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", {
|
||||
sectionName: sectionName, projectName: @scope.project.name})
|
||||
@appTitle.set(appTitle)
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
loadProject: ->
|
||||
return @rs.projects.getBySlug(@params.pslug).then (project) =>
|
||||
|
@ -119,7 +122,9 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
|
|||
promise.then ->
|
||||
$loading.finish(submitButton)
|
||||
$confirm.notify("success")
|
||||
newUrl = $navurls.resolve("project-admin-project-profile-details", {project: $scope.project.slug})
|
||||
newUrl = $navurls.resolve("project-admin-project-profile-details", {
|
||||
project: $scope.project.slug
|
||||
})
|
||||
$location.path(newUrl)
|
||||
$scope.$emit("project:loaded", $scope.project)
|
||||
|
||||
|
@ -137,7 +142,9 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
|
|||
|
||||
return {link:link}
|
||||
|
||||
module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation", "tgProjectService", ProjectProfileDirective])
|
||||
module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation",
|
||||
"tgProjectService", ProjectProfileDirective])
|
||||
|
||||
|
||||
#############################################################################
|
||||
## Project Default Values Directive
|
||||
|
@ -224,7 +231,8 @@ ProjectModulesDirective = ($repo, $confirm, $loading, projectService) ->
|
|||
|
||||
return {link:link}
|
||||
|
||||
module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", "tgProjectService", ProjectModulesDirective])
|
||||
module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", "tgProjectService",
|
||||
ProjectModulesDirective])
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
|
|
@ -46,11 +46,12 @@ class ProjectValuesSectionController extends mixOf(taiga.Controller, taiga.PageM
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle, @translate) ->
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
|
||||
@appMetaService, @translate) ->
|
||||
@scope.project = {}
|
||||
|
||||
promise = @.loadInitialData()
|
||||
|
@ -58,12 +59,12 @@ class ProjectValuesSectionController extends mixOf(taiga.Controller, taiga.PageM
|
|||
promise.then () =>
|
||||
sectionName = @translate.instant(@scope.sectionName)
|
||||
|
||||
title = @translate.instant("ADMIN.PROJECT_VALUES.APP_TITLE", {
|
||||
title = @translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", {
|
||||
"sectionName": sectionName,
|
||||
"projectName": @scope.project.name
|
||||
})
|
||||
|
||||
@appTitle.set(title)
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
@ -383,15 +384,24 @@ class ProjectCustomAttributesController extends mixOf(taiga.Controller, taiga.Pa
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appTitle) ->
|
||||
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appMetaService,
|
||||
@translate) ->
|
||||
@scope.project = {}
|
||||
|
||||
@rootscope.$on "project:loaded", =>
|
||||
@.loadCustomAttributes()
|
||||
@appTitle.set("Project Custom Attributes - " + @scope.sectionName + " - " + @scope.project.name)
|
||||
|
||||
sectionName = @translate.instant(@scope.sectionName)
|
||||
title = @translate.instant("ADMIN.CUSTOM_ATTRIBUTES.PAGE_TITLE", {
|
||||
"sectionName": sectionName,
|
||||
"projectName": @scope.project.name
|
||||
})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
#########################
|
||||
# Custom Attribute
|
||||
|
@ -640,4 +650,5 @@ ProjectCustomAttributesDirective = ($log, $confirm, animationFrame, $translate)
|
|||
|
||||
return {link: link}
|
||||
|
||||
module.directive("tgProjectCustomAttributes", ["$log", "$tgConfirm", "animationFrame", "$translate", ProjectCustomAttributesDirective])
|
||||
module.directive("tgProjectCustomAttributes", ["$log", "$tgConfirm", "animationFrame", "$translate",
|
||||
ProjectCustomAttributesDirective])
|
||||
|
|
|
@ -44,12 +44,12 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle,
|
||||
@translate) ->
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
|
||||
@appMetaService, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.sectionName = "ADMIN.MENU.PERMISSIONS"
|
||||
|
@ -59,8 +59,9 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
title = @translate.instant("ADMIN.ROLES.SECTION_NAME", {projectName: @scope.project.name})
|
||||
@appTitle.set(title)
|
||||
title = @translate.instant("ADMIN.ROLES.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
|
|
@ -41,11 +41,11 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
|
|||
"$routeParams",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appTitle, @translate) ->
|
||||
constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appMetaService, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME"
|
||||
|
@ -54,8 +54,9 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
text = @translate.instant("ADMIN.WEBHOOKS.APP_TITLE", {"projectName": @scope.project.name})
|
||||
@appTitle.set(text)
|
||||
title = @translate.instant("ADMIN.WEBHOOKS.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
@ -292,11 +293,11 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
"$tgRepo",
|
||||
"$tgResources",
|
||||
"$routeParams",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @repo, @rs, @params, @appTitle, @translate) ->
|
||||
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME")
|
||||
|
@ -305,8 +306,9 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
title = @translate.instant("ADMIN.GITHUB.APP_TITLE", {projectName: @scope.project.name})
|
||||
@appTitle.set(title)
|
||||
title = @translate.instant("ADMIN.GITHUB.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
@ -339,11 +341,11 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
"$tgRepo",
|
||||
"$tgResources",
|
||||
"$routeParams",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @repo, @rs, @params, @appTitle, @translate) ->
|
||||
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.sectionName = @translate.instant("ADMIN.GITLAB.SECTION_NAME")
|
||||
|
@ -351,8 +353,9 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
title = @translate.instant("ADMIN.GITLAB.APP_TITLE", {projectName: @scope.project.name})
|
||||
@appTitle.set(title)
|
||||
title = @translate.instant("ADMIN.GITLAB.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
@ -388,11 +391,11 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
|||
"$tgRepo",
|
||||
"$tgResources",
|
||||
"$routeParams",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @repo, @rs, @params, @appTitle, @translate) ->
|
||||
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME")
|
||||
|
@ -400,8 +403,9 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
title = @translate.instant("ADMIN.BITBUCKET.APP_TITLE", {projectName: @scope.project.name})
|
||||
@appTitle.set(title)
|
||||
title = @translate.instant("ADMIN.BITBUCKET.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @scope.project.description
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
"$routeParams",
|
||||
"$q",
|
||||
"$tgLocation",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$tgEvents",
|
||||
"$tgAnalytics",
|
||||
|
@ -53,7 +53,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q,
|
||||
@location, @appTitle, @navUrls, @events, @analytics, @translate) ->
|
||||
@location, @appMetaService, @navUrls, @events, @analytics, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
@scope.sectionName = @translate.instant("BACKLOG.SECTION_NAME")
|
||||
|
@ -66,7 +66,12 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
|
||||
# On Success
|
||||
promise.then =>
|
||||
@appTitle.set("Backlog - " + @scope.project.name)
|
||||
title = @translate.instant("BACKLOG.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @translate.instant("BACKLOG.PAGE_DESCRIPTION", {
|
||||
projectName: @scope.project.name,
|
||||
projectDescription: @scope.project.description
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
if @rs.userstories.getShowTags(@scope.projectId)
|
||||
@showTags = true
|
||||
|
|
|
@ -22,9 +22,16 @@
|
|||
taigaContribPlugins = @.taigaContribPlugins = @.taigaContribPlugins or []
|
||||
|
||||
class ContribController extends taiga.Controller
|
||||
@.$inject = ["$rootScope", "$scope", "$routeParams", "$tgRepo", "$tgResources", "$tgConfirm", "$appTitle"]
|
||||
@.$inject = [
|
||||
"$rootScope",
|
||||
"$scope",
|
||||
"$routeParams",
|
||||
"$tgRepo",
|
||||
"$tgResources",
|
||||
"$tgConfirm"
|
||||
]
|
||||
|
||||
constructor: (@rootScope, @scope, @params, @repo, @rs, @confirm, @appTitle) ->
|
||||
constructor: (@rootScope, @scope, @params, @repo, @rs, @confirm) ->
|
||||
@scope.adminPlugins = _.where(@rootScope.contribPlugins, {"type": "admin"})
|
||||
@scope.currentPlugin = _.first(_.where(@scope.adminPlugins, {"slug": @params.plugin}))
|
||||
@scope.pluginTemplate = "contrib/#{@scope.currentPlugin.slug}"
|
||||
|
@ -32,9 +39,6 @@ class ContribController extends taiga.Controller
|
|||
|
||||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
@appTitle.set(@scope.project.name)
|
||||
|
||||
promise.then null, =>
|
||||
@confirm.notify("error")
|
||||
|
||||
|
|
|
@ -138,17 +138,6 @@ ToggleCommentDirective = () ->
|
|||
|
||||
module.directive("tgToggleComment", ToggleCommentDirective)
|
||||
|
||||
#############################################################################
|
||||
## Set the page title
|
||||
#############################################################################
|
||||
|
||||
AppTitle = () ->
|
||||
set = (text) ->
|
||||
$("title").text(text)
|
||||
|
||||
return {set: set}
|
||||
|
||||
module.factory("$appTitle", AppTitle)
|
||||
|
||||
#############################################################################
|
||||
## Get the appropiate section url for a project
|
||||
|
|
|
@ -44,14 +44,14 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$log",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgAnalytics",
|
||||
"$tgNavUrls",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location,
|
||||
@log, @appTitle, @analytics, @navUrls, @translate) ->
|
||||
@log, @appMetaService, @analytics, @navUrls, @translate) ->
|
||||
@scope.issueRef = @params.issueref
|
||||
@scope.sectionName = @translate.instant("ISSUES.SECTION_NAME")
|
||||
@.initializeEventHandlers()
|
||||
|
@ -60,12 +60,27 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
|
||||
# On Success
|
||||
promise.then =>
|
||||
@appTitle.set(@scope.issue.subject + " - " + @scope.project.name)
|
||||
@._setMeta()
|
||||
@.initializeOnDeleteGoToUrl()
|
||||
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
_setMeta: ->
|
||||
title = @translate.instant("ISSUE.PAGE_TITLE", {
|
||||
issueRef: "##{@scope.issue.ref}"
|
||||
issueSubject: @scope.issue.subject
|
||||
projectName: @scope.project.name
|
||||
})
|
||||
description = @translate.instant("ISSUE.PAGE_DESCRIPTION", {
|
||||
issueStatus: @scope.statusById[@scope.issue.status]?.name or "--"
|
||||
issueType: @scope.typeById[@scope.issue.type]?.name or "--"
|
||||
issueSeverity: @scope.severityById[@scope.issue.severity]?.name or "--"
|
||||
issuePriority: @scope.priorityById[@scope.issue.priority]?.name or "--"
|
||||
issueDescription: angular.element(@scope.issue.description_html or "").text()
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
initializeEventHandlers: ->
|
||||
@scope.$on "attachment:create", =>
|
||||
@rootscope.$broadcast("object:updated")
|
||||
|
|
|
@ -47,14 +47,15 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
"$routeParams",
|
||||
"$q",
|
||||
"$tgLocation",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$tgEvents",
|
||||
"$tgAnalytics"
|
||||
"$tgAnalytics",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @urls, @params, @q, @location, @appTitle,
|
||||
@navUrls, @events, @analytics) ->
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @urls, @params, @q, @location, @appMetaService,
|
||||
@navUrls, @events, @analytics, @translate) ->
|
||||
@scope.sectionName = "Issues"
|
||||
@scope.filters = {}
|
||||
|
||||
|
@ -69,7 +70,12 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
|
||||
# On Success
|
||||
promise.then =>
|
||||
@appTitle.set("Issues - " + @scope.project.name)
|
||||
title = @translate.instant("ISSUES.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @translate.instant("ISSUES.PAGE_DESCRIPTION", {
|
||||
projectName: @scope.project.name,
|
||||
projectDescription: @scope.project.description
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
|
|
@ -58,7 +58,7 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
"$routeParams",
|
||||
"$q",
|
||||
"$tgLocation",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$tgEvents",
|
||||
"$tgAnalytics",
|
||||
|
@ -66,7 +66,7 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location,
|
||||
@appTitle, @navUrls, @events, @analytics, @translate) ->
|
||||
@appMetaService, @navUrls, @events, @analytics, @translate) ->
|
||||
|
||||
bindMethods(@)
|
||||
|
||||
|
@ -78,7 +78,12 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
|
||||
# On Success
|
||||
promise.then =>
|
||||
@appTitle.set("Kanban - " + @scope.project.name)
|
||||
title = @translate.instant("KANBAN.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @translate.instant("KANBAN.PAGE_DESCRIPTION", {
|
||||
projectName: @scope.project.name,
|
||||
projectDescription: @scope.project.description
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
|
|
@ -43,17 +43,23 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$routeParams",
|
||||
"$q",
|
||||
"$tgLocation",
|
||||
"$appTitle",
|
||||
"$tgNavUrls"
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @repo, @rs, @params, @q, @location, @appTitle, @navUrls) ->
|
||||
constructor: (@scope, @repo, @rs, @params, @q, @location, @appMetaService, @navUrls, @translate) ->
|
||||
@scope.sectionName = "Search"
|
||||
|
||||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
@appTitle.set("Search")
|
||||
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)
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$tgResources",
|
||||
"$routeParams",
|
||||
"$q",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgLocation",
|
||||
"$tgNavUrls"
|
||||
"$tgEvents"
|
||||
|
@ -52,7 +52,7 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @appTitle, @location, @navUrls,
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @appMetaService, @location, @navUrls,
|
||||
@events, @analytics, @translate) ->
|
||||
bindMethods(@)
|
||||
|
||||
|
@ -62,12 +62,31 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
promise = @.loadInitialData()
|
||||
|
||||
# On Success
|
||||
promise.then =>
|
||||
@appTitle.set("Taskboard - " + @scope.project.name)
|
||||
|
||||
promise.then => @._setMeta()
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
_setMeta: ->
|
||||
prettyDate = @translate.instant("BACKLOG.SPRINTS.DATE")
|
||||
|
||||
title = @translate.instant("TASKBOARD.PAGE_TITLE", {
|
||||
projectName: @scope.project.name
|
||||
sprintName: @scope.sprint.name
|
||||
})
|
||||
description = @translate.instant("TASKBOARD.PAGE_DESCRIPTION", {
|
||||
projectName: @scope.project.name
|
||||
sprintName: @scope.sprint.name
|
||||
startDate: moment(@scope.sprint.estimated_start).format(prettyDate)
|
||||
endDate: moment(@scope.sprint.estimated_finish).format(prettyDate)
|
||||
completedPercentage: @scope.stats.completedPercentage or "0"
|
||||
completedPoints: @scope.stats.completedPointsSum or "--"
|
||||
totalPoints: @scope.stats.totalPointsSum or "--"
|
||||
openTasks: @scope.stats.openTasks or "--"
|
||||
totalTasks: @scope.stats.total_tasks or "--"
|
||||
})
|
||||
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
initializeEventHandlers: ->
|
||||
# TODO: Reload entire taskboard after create/edit tasks seems
|
||||
# a big overhead. It should be optimized in near future.
|
||||
|
@ -255,7 +274,7 @@ TaskboardDirective = ($rootscope) ->
|
|||
$el.on "click", ".toggle-analytics-visibility", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
target.toggleClass('active');
|
||||
target.toggleClass('active')
|
||||
$rootscope.$broadcast("taskboard:graph:toggle-visibility")
|
||||
|
||||
tableBodyDom = $el.find(".taskboard-table-body")
|
||||
|
|
|
@ -42,14 +42,14 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$log",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$tgAnalytics",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location,
|
||||
@log, @appTitle, @navUrls, @analytics, @translate) ->
|
||||
@log, @appMetaService, @navUrls, @analytics, @translate) ->
|
||||
@scope.taskRef = @params.taskref
|
||||
@scope.sectionName = @translate.instant("TASK.SECTION_NAME")
|
||||
@.initializeEventHandlers()
|
||||
|
@ -57,11 +57,23 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
promise = @.loadInitialData()
|
||||
|
||||
promise.then () =>
|
||||
@appTitle.set(@scope.task.subject + " - " + @scope.project.name)
|
||||
@._setMeta()
|
||||
@.initializeOnDeleteGoToUrl()
|
||||
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
_setMeta: ->
|
||||
title = @translate.instant("TASK.PAGE_TITLE", {
|
||||
taskRef: "##{@scope.task.ref}"
|
||||
taskSubject: @scope.task.subject
|
||||
projectName: @scope.project.name
|
||||
})
|
||||
description = @translate.instant("TASK.PAGE_DESCRIPTION", {
|
||||
taskStatus: @scope.statusById[@scope.task.status]?.name or "--"
|
||||
taskDescription: angular.element(@scope.task.description_html or "").text()
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
initializeEventHandlers: ->
|
||||
@scope.$on "attachment:create", =>
|
||||
@analytics.trackEvent("attachment", "create", "create attachment on task", 1)
|
||||
|
|
|
@ -39,21 +39,26 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$q",
|
||||
"$location",
|
||||
"$tgNavUrls",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgAuth",
|
||||
"$translate",
|
||||
"tgProjectService"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appTitle, @auth, @translate, @projectService) ->
|
||||
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appMetaService, @auth,
|
||||
@translate, @projectService) ->
|
||||
@scope.sectionName = "TEAM.SECTION_NAME"
|
||||
|
||||
promise = @.loadInitialData()
|
||||
|
||||
# On Success
|
||||
promise.then =>
|
||||
text = @translate.instant("TEAM.APP_TITLE", {"projectName": @scope.project.name})
|
||||
@appTitle.set(text)
|
||||
title = @translate.instant("TEAM.PAGE_TITLE", {projectName: @scope.project.name})
|
||||
description = @translate.instant("TEAM.PAGE_DESCRIPTION", {
|
||||
projectName: @scope.project.name,
|
||||
projectDescription: @scope.project.description
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
|
|
@ -42,14 +42,14 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$q",
|
||||
"$tgLocation",
|
||||
"$log",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$tgAnalytics",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location,
|
||||
@log, @appTitle, @navUrls, @analytics, @translate) ->
|
||||
@log, @appMetaService, @navUrls, @analytics, @translate) ->
|
||||
@scope.usRef = @params.usref
|
||||
@scope.sectionName = @translate.instant("US.SECTION_NAME")
|
||||
@.initializeEventHandlers()
|
||||
|
@ -58,12 +58,33 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
|
||||
# On Success
|
||||
promise.then =>
|
||||
@appTitle.set(@scope.us.subject + " - " + @scope.project.name)
|
||||
@._setMeta()
|
||||
@.initializeOnDeleteGoToUrl()
|
||||
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
_setMeta: ->
|
||||
totalTasks = @scope.tasks.length
|
||||
closedTasks = _.filter(@scope.tasks, (t) => @scope.taskStatusById[t.status].is_closed).length
|
||||
progressPercentage = if totalTasks > 0 then 100 * closedTasks / totalTasks else 0
|
||||
|
||||
title = @translate.instant("US.PAGE_TITLE", {
|
||||
userStoryRef: "##{@scope.us.ref}"
|
||||
userStorySubject: @scope.us.subject
|
||||
projectName: @scope.project.name
|
||||
})
|
||||
description = @translate.instant("US.PAGE_DESCRIPTION", {
|
||||
userStoryStatus: @scope.statusById[@scope.us.status]?.name or "--"
|
||||
userStoryPoints: @scope.us.total_points
|
||||
userStoryDescription: angular.element(@scope.us.description_html or "").text()
|
||||
userStoryClosedTasks: closedTasks
|
||||
userStoryTotalTasks: totalTasks
|
||||
userStoryProgressPercentage: progressPercentage
|
||||
})
|
||||
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
initializeEventHandlers: ->
|
||||
@scope.$on "related-tasks:update", =>
|
||||
@.loadUs()
|
||||
|
|
|
@ -46,14 +46,14 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
"$tgLocation",
|
||||
"$filter",
|
||||
"$log",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgNavUrls",
|
||||
"$tgAnalytics",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location,
|
||||
@filter, @log, @appTitle, @navUrls, @analytics, @translate) ->
|
||||
@filter, @log, @appMetaService, @navUrls, @analytics, @translate) ->
|
||||
@scope.projectSlug = @params.pslug
|
||||
@scope.wikiSlug = @params.slug
|
||||
@scope.sectionName = "Wiki"
|
||||
|
@ -61,12 +61,23 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
promise = @.loadInitialData()
|
||||
|
||||
# On Success
|
||||
promise.then () =>
|
||||
@appTitle.set("Wiki - " + @scope.project.name)
|
||||
promise.then () => @._setMeta()
|
||||
|
||||
# On Error
|
||||
promise.then null, @.onInitialDataError.bind(@)
|
||||
|
||||
_setMeta: ->
|
||||
title = @translate.instant("WIKI.PAGE_TITLE", {
|
||||
wikiPageName: @scope.wiki.slug
|
||||
projectName: unslugify(@scope.wiki.slug)
|
||||
})
|
||||
description = @translate.instant("WIKI.PAGE_DESCRIPTION", {
|
||||
wikiPageContent: angular.element(@scope.wiki.html or "").text()
|
||||
totalEditions: @scope.wiki.editions or 0
|
||||
lastModifiedDate: moment(@scope.wiki.modified_date).format(@translate.instant("WIKI.DATETIME"))
|
||||
})
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
loadProject: ->
|
||||
return @rs.projects.getBySlug(@params.pslug).then (project) =>
|
||||
if not project.is_wiki_activated
|
||||
|
|
|
@ -126,6 +126,19 @@ startswith = (str1, str2) ->
|
|||
return _.str.startsWith(str1, str2)
|
||||
|
||||
|
||||
truncate = (str, maxLength, suffix="...") ->
|
||||
return str if (typeof str != "string") and not (str instanceof String)
|
||||
|
||||
out = str.slice(0)
|
||||
|
||||
if out.length > maxLength
|
||||
out = out.substring(0, maxLength + 1)
|
||||
out = out.substring(0, Math.min(out.length, out.lastIndexOf(" ")))
|
||||
out = out + suffix
|
||||
|
||||
return out
|
||||
|
||||
|
||||
sizeFormat = (input, precision=1) ->
|
||||
if isNaN(parseFloat(input)) or not isFinite(input)
|
||||
return "-"
|
||||
|
@ -187,6 +200,7 @@ taiga.cancelTimeout = cancelTimeout
|
|||
taiga.scopeDefer = scopeDefer
|
||||
taiga.toString = toString
|
||||
taiga.joinStr = joinStr
|
||||
taiga.truncate = truncate
|
||||
taiga.debounce = debounce
|
||||
taiga.debounceLeading = debounceLeading
|
||||
taiga.startswith = startswith
|
||||
|
|
|
@ -3,10 +3,12 @@ html(lang="en")
|
|||
head
|
||||
meta(charset="utf-8")
|
||||
meta(http-equiv="content-type", content="text/html; charset=utf-8")
|
||||
meta(name="fragment", content="!")
|
||||
|
||||
// Main meta
|
||||
title Taiga
|
||||
meta(name="description", content="Taiga is a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable.")
|
||||
meta(name="keywords", content="agile, scrum, taiga, management, project, developer, designer, user experience")
|
||||
meta(name="fragment", content="!")
|
||||
//-meta(name="viewport", content="width=device-width, user-scalable=no")
|
||||
link(rel="stylesheet", href="/styles/main.css")
|
||||
link(rel="icon", type="image/png", href="/images/favicon.png")
|
||||
|
|
|
@ -236,20 +236,105 @@
|
|||
"ADD_WIKI_LINKS": "Add wiki links",
|
||||
"DELETE_WIKI_LINKS": "Delete wiki links"
|
||||
}
|
||||
},
|
||||
"META": {
|
||||
"PAGE_TITLE": "Taiga",
|
||||
"PAGE_DESCRIPTION": "Taiga is a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable."
|
||||
}
|
||||
},
|
||||
"LOGIN": {
|
||||
"PAGE_TITLE": "Login - Taiga",
|
||||
"PAGE_DESCRIPTION": "Logging in to Taiga, a project management platform for startups and agile developers & designers who want a simple, beautif ul tool that makes work truly enjoyable."
|
||||
},
|
||||
"AUTH": {
|
||||
"INVITED_YOU": "has invited you to join the project",
|
||||
"NOT_REGISTERED_YET": "Not registered yet?",
|
||||
"REGISTER": "Register",
|
||||
"CREATE_ACCOUNT": "create your free account here"
|
||||
},
|
||||
"LOGIN_COMMON": {
|
||||
"HEADER": "I already have a Taiga login",
|
||||
"PLACEHOLDER_AUTH_NAME": "Username or email (case sensitive)",
|
||||
"LINK_FORGOT_PASSWORD": "Forgot it?",
|
||||
"TITLE_LINK_FORGOT_PASSWORD": "Did you forgot your password?",
|
||||
"ACTION_ENTER": "Enter",
|
||||
"ACTION_SIGN_IN": "Sign in",
|
||||
"PLACEHOLDER_AUTH_PASSWORD": "Password (case sensitive)"
|
||||
},
|
||||
"LOGIN_FORM": {
|
||||
"ERROR_AUTH_INCORRECT": "According to our Oompa Loompas, your username/email or password are incorrect.",
|
||||
"ERROR_GENERIC": "According to our Oompa Loompas there was an error.",
|
||||
"SUCCESS": "Our Oompa Loompas are happy, welcome to Taiga."
|
||||
},
|
||||
"REGISTER": {
|
||||
"PAGE_TITLE": "Register - Taiga",
|
||||
"PAGE_DESCRIPTION": "Create your account in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautif ul tool that makes work truly enjoyable."
|
||||
},
|
||||
"REGISTER_FORM": {
|
||||
"TITLE": "Register a new Taiga account (free)",
|
||||
"PLACEHOLDER_NAME": "Pick a username (case sensitive)",
|
||||
"PLACEHOLDER_FULL_NAME": "Pick your full name",
|
||||
"PLACEHOLDER_EMAIL": "Your email",
|
||||
"PLACEHOLDER_PASSWORD": "Set a password (case sensitive)",
|
||||
"ACTION_SIGN_UP": "Sign up",
|
||||
"TITLE_LINK_LOGIN": "Log in",
|
||||
"LINK_LOGIN": "Are you already registered? Log in"
|
||||
},
|
||||
"FORGOT_PASSWORD": {
|
||||
"PAGE_TITLE": "Forgot password - Taiga",
|
||||
"PAGE_DESCRIPTION": "Enter your username or email to get a new password and you can access to Taiga again."
|
||||
},
|
||||
"FORGOT_PASSWORD_FORM": {
|
||||
"TITLE": "Oops, did you forget your password?",
|
||||
"SUBTITLE": "Enter your username or email to get a new one",
|
||||
"PLACEHOLDER_FIELD": "Username or email",
|
||||
"ACTION_RESET_PASSWORD": "Reset Password",
|
||||
"LINK_CANCEL": "Nah, take me back. I think I remember it.",
|
||||
"SUCCESS": "<strong>Check your inbox!</strong><br />We have sent you an email with the instructions to set a new password",
|
||||
"ERROR": "According to our Oompa Loompas, your are not registered yet."
|
||||
},
|
||||
"CHANGE_PASSWORD": {
|
||||
"PAGE_TITLE": "Change you password - Taiga",
|
||||
"PAGE_DESCRIPTION": "Set a new passoword for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P",
|
||||
"SECTION_NAME": "Change password",
|
||||
"FIELD_CURRENT_PASSWORD": "Current password",
|
||||
"PLACEHOLDER_CURRENT_PASSWORD": "Your current password (or empty if you have no password yet)",
|
||||
"FIELD_NEW_PASSWORD": "New password",
|
||||
"PLACEHOLDER_NEW_PASSWORD": "Type a new password",
|
||||
"FIELD_RETYPE_PASSWORD": "Retype new password",
|
||||
"PLACEHOLDER_RETYPE_PASSWORD": "Retype the new password",
|
||||
"ERROR_PASSWORD_MATCH": "The passwords doesn't match"
|
||||
},
|
||||
"CHANGE_PASSWORD_RECOVERY_FORM": {
|
||||
"TITLE": "Create a new Taiga pass",
|
||||
"SUBTITLE": "And hey, you may want to eat some more iron-rich food, it's good for your brain :P",
|
||||
"PLACEHOLDER_RECOVER_PASSWORD_TOKEN": "Recover password token",
|
||||
"LINK_NEED_TOKEN": "Need one?",
|
||||
"TITLE_LINK_NEED_TOKEN": "Did you need a token to recover your password because you forgot it?",
|
||||
"PLACEHOLDER_NEW_PASSWORD": "New password",
|
||||
"PLACEHOLDER_RE_TYPE_NEW_PASSWORD": "Re-type new password",
|
||||
"ACTION_RESET_PASSWORD": "Reset Password",
|
||||
"SUCCESS": "Our Oompa Loompas saved your new password.<br /> Try to <strong>sign in</strong> with it."
|
||||
},
|
||||
"INVITATION": {
|
||||
"PAGE_TITLE": "Invitation acceptance - Taiga",
|
||||
"PAGE_DESCRIPTION": "Accept the invitation to join a project in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautif ul tool that makes work truly enjoyable."
|
||||
},
|
||||
"INVITATION_LOGIN_FORM": {
|
||||
"NOT_FOUND": "<strong>Ooops, we have a problem</strong><br />Our Oompa Loompas can't find your invitation.",
|
||||
"SUCCESS": "You've successfully joined this project, Welcome to {{project_name}}",
|
||||
"ERROR": "According to our Oompa Loompas, your are not registered yet or typed an invalid password."
|
||||
},
|
||||
"HOME": {
|
||||
"PAGE_TITLE": "Home - Taiga",
|
||||
"PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues",
|
||||
"EMPTY_WATCHING": "<strong>Follow</strong> the projects, User Stories, Tasks, Issues... that you want to know about :)",
|
||||
"WORKING_ON_SECTION": "Working on",
|
||||
"WATCHING_SECTION": "Watching"
|
||||
},
|
||||
"PROJECTS": {
|
||||
"PAGE_TITLE": "My projects - Taiga",
|
||||
"PAGE_DESCRIPTION": "A list with all your projects, you can reorder or create a new one.",
|
||||
"MY_PROJECTS": "My projects"
|
||||
},
|
||||
"ATTACHMENT": {
|
||||
|
@ -289,6 +374,7 @@
|
|||
},
|
||||
"MEMBERSHIPS": {
|
||||
"TITLE": "Manage members",
|
||||
"PAGE_TITLE": "Memberships - {{projectName}}",
|
||||
"ADD_BUTTON": "+ New member",
|
||||
"ADD_BUTTON_TITLE": "Add new member"
|
||||
},
|
||||
|
@ -324,7 +410,7 @@
|
|||
"SALT_CHAT_ROOM": "If you want you can append a salt code to the name of the chat room"
|
||||
},
|
||||
"PROJECT_PROFILE": {
|
||||
"PAGE_TITLE": "Project profile - {{sectionName}} - {{projectName}}",
|
||||
"PAGE_TITLE": "{{sectionName}} - Project profile - {{projectName}}",
|
||||
"PROJECT_DETAILS": "Project details",
|
||||
"PROJECT_NAME": "Project name",
|
||||
"PROJECT_SLUG": "Project slug",
|
||||
|
@ -365,23 +451,26 @@
|
|||
"ISSUE_ADD": "Add a custom field in issues"
|
||||
},
|
||||
"PROJECT_VALUES": {
|
||||
"APP_TITLE": "Project values - {{sectionName}} - {{projectName}}",
|
||||
"PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}",
|
||||
"REPLACEMENT": "All items with this value will be changed to",
|
||||
"ERROR_DELETE_ALL": "You can't delete all values."
|
||||
},
|
||||
"PROJECT_VALUES_POINTS": {
|
||||
"TITLE": "Us points",
|
||||
"TITLE": "Points",
|
||||
"SUBTITLE": "Specify the points your user stories could be estimated to",
|
||||
"US_TITLE": "US points",
|
||||
"ACTION_ADD": "Add new point"
|
||||
},
|
||||
"PROJECT_VALUES_PRIORITIES": {
|
||||
"TITLE": "Issue priorities",
|
||||
"TITLE": "Priorities",
|
||||
"SUBTITLE": "Specify the priorities your issues will have",
|
||||
"ISSUE_TITLE": "Issue priorities",
|
||||
"ACTION_ADD": "Add new priority"
|
||||
},
|
||||
"PROJECT_VALUES_SEVERITIES": {
|
||||
"TITLE": "Issue severities",
|
||||
"TITLE": "Severities",
|
||||
"SUBTITLE": "Specify the severities your issues will have",
|
||||
"ISSUE_TITLE": "Issue severities",
|
||||
"ACTION_ADD": "Add new severity"
|
||||
},
|
||||
"PROJECT_VALUES_STATUS": {
|
||||
|
@ -398,7 +487,7 @@
|
|||
"ACTION_ADD": "Add new {{objName}}"
|
||||
},
|
||||
"ROLES": {
|
||||
"SECTION_NAME": "Roles - {{projectName}}",
|
||||
"PAGE_TITLE": "Roles - {{projectName}}",
|
||||
"WARNING_NO_ROLE": "Be careful, no role in your project will be able to estimate the point value for user stories",
|
||||
"HELP_ROLE_ENABLED": "When enabled, members assigned to this role will be able to estimate the point value for user stories",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} members with this role",
|
||||
|
@ -415,20 +504,20 @@
|
|||
},
|
||||
"BITBUCKET": {
|
||||
"SECTION_NAME": "Bitbucket",
|
||||
"APP_TITLE": "Bitbucket - {{projectName}}",
|
||||
"PAGE_TITLE": "Bitbucket - {{projectName}}",
|
||||
"INFO_VERIFYING_IP": "Bitbucket requests are not signed so the best way of verifying the origin is by IP. If the field is empty there will be no IP validation."
|
||||
},
|
||||
"GITLAB": {
|
||||
"SECTION_NAME": "Gitlab",
|
||||
"APP_TITLE": "Gitlab - {{projectName}}",
|
||||
"PAGE_TITLE": "Gitlab - {{projectName}}",
|
||||
"INFO_VERIFYING_IP": "Gitlab requests are not signed so the best way of verifying the origin is by IP. If the field is empty there will be no IP validation."
|
||||
},
|
||||
"GITHUB": {
|
||||
"SECTION_NAME": "Github",
|
||||
"APP_TITLE": "Github - {{projectName}}"
|
||||
"PAGE_TITLE": "Github - {{projectName}}"
|
||||
},
|
||||
"WEBHOOKS": {
|
||||
"APP_TITLE": "Webhooks - {{projectName}}",
|
||||
"PAGE_TITLE": "Webhooks - {{projectName}}",
|
||||
"SECTION_NAME": "Webhooks",
|
||||
"SUBTITLE": "Webhooks notify external services about events in Taiga, like comments, user stories....",
|
||||
"ADD_NEW": "Add a New Webhook",
|
||||
|
@ -454,6 +543,7 @@
|
|||
"WEBHOOK_NAME": "Webhook '{{name}}'"
|
||||
},
|
||||
"CUSTOM_ATTRIBUTES": {
|
||||
"PAGE_TITLE": "{{sectionName}} - Custom Attributes - {{projectName}}",
|
||||
"ADD": "Add custom field",
|
||||
"EDIT": "Edit Custom Field",
|
||||
"DELETE": "Delete Custom Field",
|
||||
|
@ -533,6 +623,7 @@
|
|||
},
|
||||
"USER": {
|
||||
"PROFILE": {
|
||||
"PAGE_TITLE": "{{userFullName}} (@{{userUsername}})",
|
||||
"EDIT": "Edit profile",
|
||||
"FOLLOW": "Follow",
|
||||
"PROJECTS": "Projects",
|
||||
|
@ -555,6 +646,7 @@
|
|||
}
|
||||
},
|
||||
"PROJECT": {
|
||||
"PAGE_TITLE": "{{projectName}}",
|
||||
"WELCOME": "Welcome",
|
||||
"SECTION_PROJECTS": "Projects",
|
||||
"HELP": "Reorder your projects to set in the top the most used ones.<br/> The top 10 projects will appear in the top navigation bar project list",
|
||||
|
@ -685,6 +777,9 @@
|
|||
}
|
||||
},
|
||||
"US": {
|
||||
"PAGE_TITLE": "{{userStorySubject}} - User Story {{userStoryRef}} - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Completed {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} of {{userStoryTotalTasks}} tasks closed). Points: {{userStoryPoints}}. Description: {{userStoryDescription}}",
|
||||
|
||||
"SECTION_NAME": "User story details",
|
||||
"LINK_TASKBOARD": "Taskboard",
|
||||
"TITLE_LINK_TASKBOARD": "Go to the taskboard",
|
||||
|
@ -772,6 +867,8 @@
|
|||
}
|
||||
},
|
||||
"BACKLOG": {
|
||||
"PAGE_TITLE": "Backlog - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "The backlog panel, with user stories and sprints of the project {{projectName}}: {{projectDescription}}",
|
||||
"SECTION_NAME": "Backlog",
|
||||
"MOVE_US_TO_CURRENT_SPRINT": "Move to Current Sprint",
|
||||
"SHOW_FILTERS": "Show filters",
|
||||
|
@ -852,6 +949,8 @@
|
|||
"VERSION_ERROR": "Someone inside Taiga has changed this before and our Oompa Loompas cannot apply your changes. Please reload and apply your changes again (they will be lost)."
|
||||
},
|
||||
"TASKBOARD": {
|
||||
"PAGE_TITLE": "{{sprintName}} - Sprint taskboard - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "Sprint {{sprintName}} (from {{startDate}} to {{endDate}}) of {{projectName}}. Completed {{completedPercentage}}% ({{completedPoints}} of {{totalPoints}} points). {{openTasks}} opened tasks of {{totalTasks}}." ,
|
||||
"SECTION_NAME": "Taskboard",
|
||||
"TITLE_ACTION_ADD": "Add a new Task",
|
||||
"TITLE_ACTION_ADD_BULK": "Add some new Tasks in bulk",
|
||||
|
@ -875,6 +974,8 @@
|
|||
}
|
||||
},
|
||||
"TASK": {
|
||||
"PAGE_TITLE": "{{taskSubject}} - Task {{taskRef}} - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "Status: {{taskStatus }}. Description: {{taskDescription}}",
|
||||
"SECTION_NAME": "Task details",
|
||||
"LINK_TASKBOARD": "Taskboard",
|
||||
"TITLE_LINK_TASKBOARD": "Go to the taskboard",
|
||||
|
@ -920,56 +1021,9 @@
|
|||
"ACTION_CHANGE_EMAIL": "Change email",
|
||||
"SUCCESS": "Our Oompa Loompas updated your email"
|
||||
},
|
||||
"CHANGE_PASSWORD_RECOVERY_FORM": {
|
||||
"TITLE": "Create a new Taiga pass",
|
||||
"SUBTITLE": "And hey, you may want to eat some more iron-rich food, it's good for your brain :P",
|
||||
"PLACEHOLDER_RECOVER_PASSWORD_TOKEN": "Recover password token",
|
||||
"LINK_NEED_TOKEN": "Need one?",
|
||||
"TITLE_LINK_NEED_TOKEN": "Did you need a token to recover your password because you forgot it?",
|
||||
"PLACEHOLDER_NEW_PASSWORD": "New password",
|
||||
"PLACEHOLDER_RE_TYPE_NEW_PASSWORD": "Re-type new password",
|
||||
"ACTION_RESET_PASSWORD": "Reset Password",
|
||||
"SUCCESS": "Our Oompa Loompas saved your new password.<br /> Try to <strong>sign in</strong> with it."
|
||||
},
|
||||
"FORGOT_PASSWORD_FORM": {
|
||||
"TITLE": "Oops, did you forget your password?",
|
||||
"SUBTITLE": "Enter your username or email to get a new one",
|
||||
"PLACEHOLDER_FIELD": "Username or email",
|
||||
"ACTION_RESET_PASSWORD": "Reset Password",
|
||||
"LINK_CANCEL": "Nah, take me back. I think I remember it.",
|
||||
"SUCCESS": "<strong>Check your inbox!</strong><br />We have sent you an email with the instructions to set a new password",
|
||||
"ERROR": "According to our Oompa Loompas, your are not registered yet."
|
||||
},
|
||||
"LOGIN_COMMON": {
|
||||
"HEADER": "I already have a Taiga login",
|
||||
"PLACEHOLDER_AUTH_NAME": "Username or email (case sensitive)",
|
||||
"LINK_FORGOT_PASSWORD": "Forgot it?",
|
||||
"TITLE_LINK_FORGOT_PASSWORD": "Did you forgot your password?",
|
||||
"ACTION_ENTER": "Enter",
|
||||
"ACTION_SIGN_IN": "Sign in",
|
||||
"PLACEHOLDER_AUTH_PASSWORD": "Password (case sensitive)"
|
||||
},
|
||||
"LOGIN_FORM": {
|
||||
"ERROR_AUTH_INCORRECT": "According to our Oompa Loompas, your username/email or password are incorrect.",
|
||||
"ERROR_GENERIC": "According to our Oompa Loompas there was an error.",
|
||||
"SUCCESS": "Our Oompa Loompas are happy, welcome to Taiga."
|
||||
},
|
||||
"INVITATION_LOGIN_FORM": {
|
||||
"NOT_FOUND": "<strong>Ooops, we have a problem</strong><br />Our Oompa Loompas can't find your invitation.",
|
||||
"SUCCESS": "You've successfully joined this project, Welcome to {{project_name}}",
|
||||
"ERROR": "According to our Oompa Loompas, your are not registered yet or typed an invalid password."
|
||||
},
|
||||
"REGISTER_FORM": {
|
||||
"TITLE": "Register a new Taiga account (free)",
|
||||
"PLACEHOLDER_NAME": "Pick a username (case sensitive)",
|
||||
"PLACEHOLDER_FULL_NAME": "Pick your full name",
|
||||
"PLACEHOLDER_EMAIL": "Your email",
|
||||
"PLACEHOLDER_PASSWORD": "Set a password (case sensitive)",
|
||||
"ACTION_SIGN_UP": "Sign up",
|
||||
"TITLE_LINK_LOGIN": "Log in",
|
||||
"LINK_LOGIN": "Are you already registered? Log in"
|
||||
},
|
||||
"ISSUES": {
|
||||
"PAGE_TITLE": "Issues - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "The issues list panel of the project {{projectName}}: {{projectDescription}}",
|
||||
"LIST_SECTION_NAME": "Issues",
|
||||
"SECTION_NAME": "Issue details",
|
||||
"ACTION_NEW_ISSUE": "+ NEW ISSUE",
|
||||
|
@ -1033,7 +1087,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ISSUE": {
|
||||
"PAGE_TITLE": "{{issueSubject}} - Issue {{issueRef}} - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priority: {{issuePriority}}. Severity: {{issueSeverity}}. Description: {{issueDescription}}"
|
||||
},
|
||||
"KANBAN": {
|
||||
"PAGE_TITLE": "Kanban - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "The kanban panel, with user stories of the project {{projectName}}: {{projectDescription}}",
|
||||
"SECTION_NAME": "Kanban",
|
||||
"TITLE_ACTION_FOLD": "Fold column",
|
||||
"TITLE_ACTION_UNFOLD": "Unfold column",
|
||||
|
@ -1048,6 +1108,8 @@
|
|||
"UNDO_ARCHIVED": "Drag & drop again to undo"
|
||||
},
|
||||
"SEARCH": {
|
||||
"PAGE_TITLE": "Search - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "Search anything, user stories, issues, tasks or wiki pages, in the project {{projectName}}: {{projectDescription}}",
|
||||
"FILTER_USER_STORIES": "User Stories",
|
||||
"FILTER_ISSUES": "Issues",
|
||||
"FILTER_TASKS": "Tasks",
|
||||
|
@ -1058,6 +1120,8 @@
|
|||
"EMPTY_DESCRIPTION": "Maybe try one of the tabs above or search again"
|
||||
},
|
||||
"TEAM": {
|
||||
"PAGE_TITLE": "Team - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "The team panel to show all the members of the project {{projectName}}: {{projectDescription}}",
|
||||
"SECTION_NAME": "Team",
|
||||
"APP_TITLE": "TEAM - {{projectName}}",
|
||||
"PLACEHOLDER_INPUT_SEARCH": "Search by full name...",
|
||||
|
@ -1078,16 +1142,6 @@
|
|||
"CONFIRM_LEAVE_PROJECT": "Are you sure you want to leave the project?",
|
||||
"ACTION_LEAVE_PROJECT": "Leave this project"
|
||||
},
|
||||
"CHANGE_PASSWORD": {
|
||||
"SECTION_NAME": "Change password",
|
||||
"FIELD_CURRENT_PASSWORD": "Current password",
|
||||
"PLACEHOLDER_CURRENT_PASSWORD": "Your current password (or empty if you have no password yet)",
|
||||
"FIELD_NEW_PASSWORD": "New password",
|
||||
"PLACEHOLDER_NEW_PASSWORD": "Type a new password",
|
||||
"FIELD_RETYPE_PASSWORD": "Retype new password",
|
||||
"PLACEHOLDER_RETYPE_PASSWORD": "Retype the new password",
|
||||
"ERROR_PASSWORD_MATCH": "The passwords doesn't match"
|
||||
},
|
||||
"USER_SETTINGS": {
|
||||
"AVATAR_MAX_SIZE": "[Max. size: {{maxFileSize}}]",
|
||||
"MENU": {
|
||||
|
@ -1141,6 +1195,8 @@
|
|||
"PROGRESS_NAME_DESCRIPTION": "Name and description"
|
||||
},
|
||||
"WIKI": {
|
||||
"PAGE_TITLE": "{{wikiPageName}} - Wiki - {{projectName}}",
|
||||
"PAGE_DESCRIPTION": "Last edition on {{lastModifiedDate}} ({{totalEditions}} editions in total) Content: {{ wikiPageContent }}",
|
||||
"DATETIME": "DD MMM YYYY HH:mm",
|
||||
"PLACEHOLDER_PAGE": "Write your wiki page",
|
||||
"REMOVE": "Remove this wiki page",
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
class ProfileController
|
||||
@.$inject = [
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"tgCurrentUserService",
|
||||
"$routeParams",
|
||||
"tgUserService",
|
||||
"tgXhrErrorService"
|
||||
"tgXhrErrorService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@appTitle, @currentUserService, @routeParams, @userService, @xhrError) ->
|
||||
constructor: (@appMetaService, @currentUserService, @routeParams, @userService, @xhrError, @translate) ->
|
||||
@.isCurrentUser = false
|
||||
|
||||
if @routeParams.slug
|
||||
|
@ -16,13 +17,21 @@ class ProfileController
|
|||
.then (user) =>
|
||||
@.user = user
|
||||
@.isCurrentUser = false
|
||||
@appTitle.set(@.user.get('full_name'))
|
||||
@._setMeta(@.user)
|
||||
.catch (xhr) =>
|
||||
@xhrError.response(xhr)
|
||||
|
||||
else
|
||||
@.user = @currentUserService.getUser()
|
||||
@.isCurrentUser = true
|
||||
@appTitle.set(@.user.get('full_name_display'))
|
||||
@._setMeta(@.user)
|
||||
|
||||
_setMeta: (user) ->
|
||||
title = @translate.instant("USER.PROFILE.PAGE_TITLE", {
|
||||
userFullName: user.get("full_name_display"),
|
||||
userUsername: user.get("username")
|
||||
})
|
||||
description = user.get("bio")
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
angular.module("taigaProfile").controller("Profile", ProfileController)
|
||||
|
|
|
@ -10,18 +10,21 @@ describe "ProfileController", ->
|
|||
{id: 3}
|
||||
])
|
||||
|
||||
_mockAppTitle = () ->
|
||||
stub = sinon.stub()
|
||||
|
||||
mocks.appTitle = {
|
||||
set: sinon.spy()
|
||||
_mockTranslate = () ->
|
||||
mocks.translate = {
|
||||
instant: sinon.stub()
|
||||
}
|
||||
|
||||
provide.value "$appTitle", mocks.appTitle
|
||||
provide.value "$translate", mocks.translate
|
||||
|
||||
_mockAppMetaService = () ->
|
||||
mocks.appMetaService = {
|
||||
setAll: sinon.spy()
|
||||
}
|
||||
|
||||
provide.value "tgAppMetaService", mocks.appMetaService
|
||||
|
||||
_mockCurrentUser = () ->
|
||||
stub = sinon.stub()
|
||||
|
||||
mocks.currentUser = {
|
||||
getUser: sinon.stub()
|
||||
}
|
||||
|
@ -29,8 +32,6 @@ describe "ProfileController", ->
|
|||
provide.value "tgCurrentUserService", mocks.currentUser
|
||||
|
||||
_mockUserService = () ->
|
||||
stub = sinon.stub()
|
||||
|
||||
mocks.userService = {
|
||||
getUserByUserName: sinon.stub()
|
||||
}
|
||||
|
@ -38,15 +39,11 @@ describe "ProfileController", ->
|
|||
provide.value "tgUserService", mocks.userService
|
||||
|
||||
_mockRouteParams = () ->
|
||||
stub = sinon.stub()
|
||||
|
||||
mocks.routeParams = {}
|
||||
|
||||
provide.value "$routeParams", mocks.routeParams
|
||||
|
||||
_mockXhrErrorService = () ->
|
||||
stub = sinon.stub()
|
||||
|
||||
mocks.xhrErrorService = {
|
||||
response: sinon.spy()
|
||||
}
|
||||
|
@ -56,12 +53,12 @@ describe "ProfileController", ->
|
|||
_mocks = () ->
|
||||
module ($provide) ->
|
||||
provide = $provide
|
||||
_mockAppTitle()
|
||||
_mockTranslate()
|
||||
_mockAppMetaService()
|
||||
_mockCurrentUser()
|
||||
_mockRouteParams()
|
||||
_mockUserService()
|
||||
_mockXhrErrorService()
|
||||
|
||||
return null
|
||||
|
||||
_inject = (callback) ->
|
||||
|
@ -81,9 +78,18 @@ describe "ProfileController", ->
|
|||
mocks.routeParams.slug = "user-slug"
|
||||
|
||||
user = Immutable.fromJS({
|
||||
full_name: "full-name"
|
||||
username: "username"
|
||||
full_name_display: "full-name-display"
|
||||
bio: "bio"
|
||||
})
|
||||
|
||||
mocks.translate.instant
|
||||
.withArgs('USER.PROFILE.PAGE_TITLE', {
|
||||
userFullName: user.get("full_name_display"),
|
||||
userUsername: user.get("username")
|
||||
})
|
||||
.returns('user-profile-page-title')
|
||||
|
||||
mocks.userService.getUserByUserName.withArgs(mocks.routeParams.slug).promise().resolve(user)
|
||||
|
||||
ctrl = $controller("Profile")
|
||||
|
@ -91,8 +97,7 @@ describe "ProfileController", ->
|
|||
setTimeout ( ->
|
||||
expect(ctrl.user).to.be.equal(user)
|
||||
expect(ctrl.isCurrentUser).to.be.false
|
||||
expect(mocks.appTitle.set.calledWithExactly("full-name")).to.be.true
|
||||
|
||||
expect(mocks.appMetaService.setAll.calledWithExactly("user-profile-page-title", "bio")).to.be.true
|
||||
done()
|
||||
)
|
||||
|
||||
|
@ -111,7 +116,6 @@ describe "ProfileController", ->
|
|||
|
||||
setTimeout ( ->
|
||||
expect(mocks.xhrErrorService.response.withArgs(xhr)).to.be.calledOnce
|
||||
|
||||
done()
|
||||
)
|
||||
|
||||
|
@ -119,13 +123,22 @@ describe "ProfileController", ->
|
|||
$scope = $rootScope.$new()
|
||||
|
||||
user = Immutable.fromJS({
|
||||
username: "username"
|
||||
full_name_display: "full-name-display"
|
||||
bio: "bio"
|
||||
})
|
||||
|
||||
mocks.translate.instant
|
||||
.withArgs('USER.PROFILE.PAGE_TITLE', {
|
||||
userFullName: user.get("full_name_display"),
|
||||
userUsername: user.get("username")
|
||||
})
|
||||
.returns('user-profile-page-title')
|
||||
|
||||
mocks.currentUser.getUser.returns(user)
|
||||
|
||||
ctrl = $controller("Profile")
|
||||
|
||||
expect(ctrl.user).to.be.equal(user)
|
||||
expect(ctrl.isCurrentUser).to.be.true
|
||||
expect(mocks.appTitle.set.calledWithExactly("full-name-display")).to.be.true
|
||||
expect(mocks.appMetaService.setAll.withArgs("user-profile-page-title", "bio")).to.be.calledOnce
|
||||
|
|
|
@ -2,22 +2,28 @@ class ProjectController
|
|||
@.$inject = [
|
||||
"tgProjectsService",
|
||||
"$routeParams",
|
||||
"$appTitle",
|
||||
"tgAppMetaService",
|
||||
"$tgAuth",
|
||||
"tgXhrErrorService"
|
||||
"tgXhrErrorService",
|
||||
"$translate"
|
||||
]
|
||||
|
||||
constructor: (@projectsService, @routeParams, @appTitle, @auth, @xhrError) ->
|
||||
constructor: (@projectsService, @routeParams, @appMetaService, @auth, @xhrError, @translate) ->
|
||||
projectSlug = @routeParams.pslug
|
||||
@.user = @auth.userData
|
||||
|
||||
@projectsService
|
||||
.getProjectBySlug(projectSlug)
|
||||
.then (project) =>
|
||||
@appTitle.set(project.get("name"))
|
||||
|
||||
@.project = project
|
||||
@._setMeta(@.project)
|
||||
|
||||
.catch (xhr) =>
|
||||
@xhrError.response(xhr)
|
||||
|
||||
_setMeta: (project)->
|
||||
title = @translate.instant("PROJECT.PAGE_TITLE", {projectName: project.get("name")})
|
||||
description = project.get("description")
|
||||
@appMetaService.setAll(title, description)
|
||||
|
||||
angular.module("taigaProjects").controller("Project", ProjectController)
|
||||
|
|
|
@ -12,12 +12,12 @@ describe "ProjectController", ->
|
|||
|
||||
provide.value "tgProjectsService", mocks.projectService
|
||||
|
||||
_mockAppTitle = () ->
|
||||
mocks.appTitle = {
|
||||
set: sinon.stub()
|
||||
_mockAppMetaService = () ->
|
||||
mocks.appMetaService = {
|
||||
setAll: sinon.stub()
|
||||
}
|
||||
|
||||
provide.value "$appTitle", mocks.appTitle
|
||||
provide.value "tgAppMetaService", mocks.appMetaService
|
||||
|
||||
_mockAuth = () ->
|
||||
mocks.auth = {
|
||||
|
@ -38,15 +38,22 @@ describe "ProjectController", ->
|
|||
|
||||
provide.value "tgXhrErrorService", mocks.xhrErrorService
|
||||
|
||||
_mockTranslate = () ->
|
||||
mocks.translate = {
|
||||
instant: sinon.stub()
|
||||
}
|
||||
|
||||
provide.value "$translate", mocks.translate
|
||||
|
||||
_mocks = () ->
|
||||
module ($provide) ->
|
||||
provide = $provide
|
||||
_mockProjectsService()
|
||||
_mockRouteParams()
|
||||
_mockAppTitle()
|
||||
_mockAppMetaService()
|
||||
_mockAuth()
|
||||
_mockXhrErrorService()
|
||||
|
||||
_mockTranslate()
|
||||
return null
|
||||
|
||||
_inject = (callback) ->
|
||||
|
@ -73,16 +80,24 @@ describe "ProjectController", ->
|
|||
expect(ctrl.user).to.be.equal(mocks.auth.userData)
|
||||
|
||||
it "set page title", (done) ->
|
||||
$scope = $rootScope.$new()
|
||||
project = Immutable.fromJS({
|
||||
name: "projectName"
|
||||
description: "projectDescription"
|
||||
})
|
||||
|
||||
mocks.translate.instant
|
||||
.withArgs('PROJECT.PAGE_TITLE', {
|
||||
projectName: project.get("name")
|
||||
})
|
||||
.returns('projectTitle')
|
||||
|
||||
mocks.projectService.getProjectBySlug.withArgs("project-slug").promise().resolve(project)
|
||||
|
||||
ctrl = $controller("Project")
|
||||
|
||||
setTimeout ( ->
|
||||
expect(mocks.appTitle.set.withArgs("projectName")).to.be.calledOnce
|
||||
expect(mocks.appMetaService.setAll.calledWithExactly("projectTitle", "projectDescription")).to.be.true
|
||||
done()
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
taiga = @.taiga
|
||||
|
||||
truncate = taiga.truncate
|
||||
|
||||
|
||||
class AppMetaService extends taiga.Service = ->
|
||||
_set: (key, value) ->
|
||||
return if not key
|
||||
|
||||
if key == "title"
|
||||
meta = $("title")
|
||||
|
||||
if meta.length == 0
|
||||
meta = $("<title></title>")
|
||||
$("head").append(meta)
|
||||
|
||||
meta.text(value or "")
|
||||
if key.indexOf("og:") == 0
|
||||
meta = $("meta[property='#{key}']")
|
||||
|
||||
if meta.length == 0
|
||||
meta = $("<meta property='#{key}'/>")
|
||||
$("head").append(meta)
|
||||
|
||||
meta.attr("content", value or "")
|
||||
else
|
||||
meta = $("meta[name='#{key}']")
|
||||
|
||||
if meta.length == 0
|
||||
meta = $("<meta name='#{key}'/>")
|
||||
$("head").append(meta)
|
||||
|
||||
meta.attr("content", value or "")
|
||||
|
||||
setTitle: (title) ->
|
||||
@._set('title', title)
|
||||
|
||||
setDescription: (description) ->
|
||||
@._set("description", truncate(description, 250))
|
||||
|
||||
setTwitterMetas: (title, description) ->
|
||||
@._set("twitter:card", "summary")
|
||||
@._set("twitter:site", "@taigaio")
|
||||
@._set("twitter:title", title)
|
||||
@._set("twitter:description", truncate(description, 250))
|
||||
@._set("twitter:image", "#{window.location.origin}/images/favicon.png")
|
||||
|
||||
setOpenGraphMetas: (title, description) ->
|
||||
@._set("og:type", "object")
|
||||
@._set("og:site_name", "Taiga - Love your projects")
|
||||
@._set("og:title", title)
|
||||
@._set("og:description", truncate(description, 250))
|
||||
@._set("og:image", "#{window.location.origin}/images/favicon.png")
|
||||
@._set("og:url", window.location.href)
|
||||
|
||||
setAll: (title, description) ->
|
||||
@.setTitle(title)
|
||||
@.setDescription(description)
|
||||
@.setTwitterMetas(title, description)
|
||||
@.setOpenGraphMetas(title, description)
|
||||
|
||||
|
||||
angular.module("taigaCommon").service("tgAppMetaService", AppMetaService)
|
|
@ -0,0 +1,55 @@
|
|||
describe "AppMetaService", ->
|
||||
appMetaService = null
|
||||
data = {
|
||||
title: "--title--",
|
||||
description: "--description--"
|
||||
}
|
||||
|
||||
_inject = () ->
|
||||
inject (_tgAppMetaService_) ->
|
||||
appMetaService = _tgAppMetaService_
|
||||
|
||||
beforeEach ->
|
||||
module "taigaCommon"
|
||||
_inject()
|
||||
|
||||
it "set meta title", () ->
|
||||
appMetaService.setTitle(data.title)
|
||||
expect($("title")).to.have.text(data.title)
|
||||
|
||||
it "set meta description", () ->
|
||||
appMetaService.setDescription(data.description)
|
||||
expect($("meta[name='description']")).to.have.attr("content", data.description)
|
||||
|
||||
it "set meta for twitter", () ->
|
||||
appMetaService.setTwitterMetas(data.title, data.description)
|
||||
expect($("meta[name='twitter:card']")).to.have.attr("content", "summary")
|
||||
expect($("meta[name='twitter:site']")).to.have.attr("content", "@taigaio")
|
||||
expect($("meta[name='twitter:title']")).to.have.attr("content", data.title)
|
||||
expect($("meta[name='twitter:description']")).to.have.attr("content", data.description)
|
||||
expect($("meta[name='twitter:image']")).to.have.attr("content", "#{window.location.origin}/images/favicon.png")
|
||||
|
||||
it "set meta for open graph", () ->
|
||||
appMetaService.setOpenGraphMetas(data.title, data.description)
|
||||
expect($("meta[property='og:type']")).to.have.attr("content", "object")
|
||||
expect($("meta[property='og:site_name']")).to.have.attr("content", "Taiga - Love your projects")
|
||||
expect($("meta[property='og:title']")).to.have.attr("content", data.title)
|
||||
expect($("meta[property='og:description']")).to.have.attr("content", data.description)
|
||||
expect($("meta[property='og:image']")).to.have.attr("content", "#{window.location.origin}/images/favicon.png")
|
||||
expect($("meta[property='og:url']")).to.have.attr("content", window.location.href)
|
||||
|
||||
it "set all meta", () ->
|
||||
appMetaService.setAll(data.title, data.description)
|
||||
expect($("title")).to.have.text(data.title)
|
||||
expect($("meta[name='description']")).to.have.attr("content", data.description)
|
||||
expect($("meta[name='twitter:card']")).to.have.attr("content", "summary")
|
||||
expect($("meta[name='twitter:site']")).to.have.attr("content", "@taigaio")
|
||||
expect($("meta[name='twitter:title']")).to.have.attr("content", data.title)
|
||||
expect($("meta[name='twitter:description']")).to.have.attr("content", data.description)
|
||||
expect($("meta[name='twitter:image']")).to.have.attr("content", "#{window.location.origin}/images/favicon.png")
|
||||
expect($("meta[property='og:type']")).to.have.attr("content", "object")
|
||||
expect($("meta[property='og:site_name']")).to.have.attr("content", "Taiga - Love your projects")
|
||||
expect($("meta[property='og:title']")).to.have.attr("content", data.title)
|
||||
expect($("meta[property='og:description']")).to.have.attr("content", data.description)
|
||||
expect($("meta[property='og:image']")).to.have.attr("content", "#{window.location.origin}/images/favicon.png")
|
||||
expect($("meta[property='og:url']")).to.have.attr("content", window.location.href)
|
|
@ -1,6 +1,7 @@
|
|||
doctype html
|
||||
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController")
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController",
|
||||
ng-init="sectionName='ADMIN.PROJECT_VALUES_POINTS.TITLE'")
|
||||
|
||||
tg-project-menu
|
||||
|
||||
|
@ -15,7 +16,7 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
|
|||
p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_POINTS.SUBTITLE")
|
||||
|
||||
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
|
||||
ng-init="section='admin'; resource='userstories'; type='points'; sectionName='ADMIN.PROJECT_VALUES_POINTS.TITLE'",
|
||||
ng-init="section='admin'; resource='userstories'; type='points'; sectionName='ADMIN.PROJECT_VALUES_POINTS.US_TITLE'",
|
||||
objName="points",
|
||||
type="points")
|
||||
include ../includes/modules/admin/project-points
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
doctype html
|
||||
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController")
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController",
|
||||
ng-init="sectionName='ADMIN.PROJECT_VALUES_PRIORITIES.TITLE'")
|
||||
|
||||
tg-project-menu
|
||||
|
||||
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
|
||||
|
@ -14,7 +16,7 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
|
|||
p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_PRIORITIES.SUBTITLE")
|
||||
|
||||
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
|
||||
ng-init="section='admin'; resource='issues'; type='priorities'; sectionName='ADMIN.PROJECT_VALUES_PRIORITIES.TITLE';",
|
||||
ng-init="section='admin'; resource='issues'; type='priorities'; sectionName='ADMIN.PROJECT_VALUES_PRIORITIES.ISSUE_TITLE';",
|
||||
objName="priorities",
|
||||
type="priorities")
|
||||
include ../includes/modules/admin/project-types
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
doctype html
|
||||
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController")
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController",
|
||||
ng-init="sectionName='ADMIN.PROJECT_VALUES_SEVERITIES.TITLE'")
|
||||
|
||||
tg-project-menu
|
||||
|
||||
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
|
||||
|
@ -14,7 +16,7 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
|
|||
p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_SEVERITIES.SUBTITLE")
|
||||
|
||||
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
|
||||
ng-init="section='admin'; resource='issues'; type='severities'; sectionName='ADMIN.PROJECT_VALUES_SEVERITIES.TITLE';",
|
||||
ng-init="section='admin'; resource='issues'; type='severities'; sectionName='ADMIN.PROJECT_VALUES_SEVERITIES.ISSUE_TITLE';",
|
||||
objName="severities",
|
||||
type="severities")
|
||||
include ../includes/modules/admin/project-types
|
||||
|
|
|
@ -2,6 +2,7 @@ doctype html
|
|||
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController",
|
||||
ng-init="section='admin'; sectionName='ADMIN.PROJECT_VALUES_STATUS.TITLE'")
|
||||
|
||||
tg-project-menu
|
||||
|
||||
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
|
||||
|
|
|
@ -2,6 +2,7 @@ doctype html
|
|||
|
||||
div.wrapper(ng-controller="ProjectValuesSectionController"
|
||||
ng-init="sectionName='ADMIN.PROJECT_VALUES_TYPES.TITLE'")
|
||||
|
||||
tg-project-menu
|
||||
|
||||
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
.view-wiki-content
|
||||
section.wysiwyg(tg-bind-html='wiki.html')
|
||||
span.edit.icon.icon-edit(title="{{'COMMON.EDIT' | translate}}", ng-if="wiki")
|
||||
|
||||
.edit-wiki-content(style='display: none;')
|
||||
textarea(ng-attr-placeholder="{{'WIKI.PLACEHOLDER_PAGE' | translate}}", ng-model='wiki.content', tg-markitup='tg-markitup')
|
||||
a.help-markdown(href='https://taiga.io/support/taiga-markdown-syntax/', target='_blank', title="{{'COMMON.WYSIWYG.MARKDOWN_HELP' | translate}}")
|
||||
span.icon.icon-help
|
||||
span(translate="COMMON.WYSIWYG.MARKDOWN_HELP")
|
||||
span.action-container
|
||||
a.save.icon.icon-floppy(href='', title="{{'COMMON.SAVE' | translate}}")
|
||||
a.cancel.icon.icon-delete(href='', title="{{'COMMON.CANCEL' | translate}}")
|
||||
textarea(ng-attr-placeholder="{{'WIKI.PLACEHOLDER_PAGE' | translate}}",
|
||||
ng-model='wiki.content', tg-markitup='tg-markitup')
|
||||
|
||||
a.help-markdown(href='https://taiga.io/support/taiga-markdown-syntax/', target='_blank',
|
||||
title="{{'COMMON.WYSIWYG.MARKDOWN_HELP' | translate}}")
|
||||
span.icon.icon-help
|
||||
span(translate="COMMON.WYSIWYG.MARKDOWN_HELP")
|
||||
|
||||
span.action-container
|
||||
a.save.icon.icon-floppy(href='', title="{{'COMMON.SAVE' | translate}}")
|
||||
a.cancel.icon.icon-delete(href='', title="{{'COMMON.CANCEL' | translate}}")
|
||||
|
|
Loading…
Reference in New Issue