Merge pull request #429 from taigaio/us/1475/internationalization

taiga internationalization
stable
Alejandro 2015-04-09 11:28:08 +02:00
commit eb9483e8c3
245 changed files with 2877 additions and 1916 deletions

View File

@ -36,7 +36,7 @@ taiga.generateUniqueSessionIdentifier = ->
taiga.sessionId = taiga.generateUniqueSessionIdentifier() taiga.sessionId = taiga.generateUniqueSessionIdentifier()
configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, tgLoaderProvider, $compileProvider) -> configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, tgLoaderProvider, $compileProvider, $translateProvider) ->
$routeProvider.when("/", $routeProvider.when("/",
{templateUrl: "project/projects.html", resolve: {loader: tgLoaderProvider.add()}}) {templateUrl: "project/projects.html", resolve: {loader: tgLoaderProvider.add()}})
@ -236,23 +236,33 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
$compileProvider.debugInfoEnabled(window.taigaConfig.debugInfo || false) $compileProvider.debugInfoEnabled(window.taigaConfig.debugInfo || false)
init = ($log, $i18n, $config, $rootscope, $auth, $events, $analytics) -> $translateProvider.useStaticFilesLoader({
$i18n.initialize($config.get("defaultLanguage")) prefix: '/locales/locale-',
suffix: '.json'
})
$translateProvider.preferredLanguage('en')
init = ($log, $config, $rootscope, $auth, $events, $analytics, $translate) ->
$log.debug("Initialize application") $log.debug("Initialize application")
$rootscope.contribPlugins = @.taigaContribPlugins $rootscope.contribPlugins = @.taigaContribPlugins
if $auth.isAuthenticated() if $auth.isAuthenticated()
$events.setupConnection() $events.setupConnection()
user = $auth.getUser()
$translate.use(user.lang) if user.lang
$analytics.initialize() $analytics.initialize()
modules = [ modules = [
# Main Global Modules # Main Global Modules
"taigaBase", "taigaBase",
"taigaCommon", "taigaCommon",
"taigaResources", "taigaResources",
"taigaLocales",
"taigaAuth", "taigaAuth",
"taigaEvents", "taigaEvents",
@ -281,6 +291,7 @@ modules = [
# Vendor modules # Vendor modules
"ngRoute", "ngRoute",
"ngAnimate", "ngAnimate",
"pascalprecht.translate"
].concat(_.map(@.taigaContribPlugins, (plugin) -> plugin.module)) ].concat(_.map(@.taigaContribPlugins, (plugin) -> plugin.module))
# Main module definition # Main module definition
@ -294,16 +305,17 @@ module.config([
"$tgEventsProvider", "$tgEventsProvider",
"tgLoaderProvider", "tgLoaderProvider",
"$compileProvider", "$compileProvider",
"$translateProvider",
configure configure
]) ])
module.run([ module.run([
"$log", "$log",
"$tgI18n",
"$tgConfig", "$tgConfig",
"$rootScope", "$rootScope",
"$tgAuth", "$tgAuth",
"$tgEvents", "$tgEvents",
"$tgAnalytics", "$tgAnalytics",
"$translate"
init init
]) ])

View File

@ -30,10 +30,10 @@ MAX_MEMBERSHIP_FIELDSETS = 4
## Create Members Lightbox Directive ## Create Members Lightbox Directive
############################################################################# #############################################################################
CreateMembersDirective = ($rs, $rootScope, $confirm, $loading ,lightboxService) -> CreateMembersDirective = ($rs, $rootScope, $confirm, $loading ,lightboxService, $compile) ->
extraTextTemplate = """ extraTextTemplate = """
<fieldset class="extra-text"> <fieldset class="extra-text">
<textarea placeholder="(Optional) Add a personalized text to the invitation. Tell something lovely to your new members ;-)" <textarea placeholder="{{'LIGHTBOX.CREATE_MEMBER.PLACEHOLDER_INVITATION_TEXT' | translate}}"
maxlength="255"> maxlength="255">
</textarea> </textarea>
</fieldset> </fieldset>
@ -42,7 +42,7 @@ CreateMembersDirective = ($rs, $rootScope, $confirm, $loading ,lightboxService)
template = _.template(""" template = _.template("""
<div class="add-member-wrapper"> <div class="add-member-wrapper">
<fieldset> <fieldset>
<input type="email" placeholder="Type an Email" <% if(required) { %> data-required="true" <% } %> data-type="email" /> <input type="email" placeholder="{{'LIGHTBOX.CREATE_MEMBER.PLACEHOLDER_TYPE_EMAIL'}}" <% if(required) { %> data-required="true" <% } %> data-type="email" />
</fieldset> </fieldset>
<fieldset> <fieldset>
<select <% if(required) { %> data-required="true" <% } %> data-required="true"> <select <% if(required) { %> data-required="true" <% } %> data-required="true">
@ -53,19 +53,19 @@ CreateMembersDirective = ($rs, $rootScope, $confirm, $loading ,lightboxService)
<a class="icon icon-plus add-fieldset" href=""></a> <a class="icon icon-plus add-fieldset" href=""></a>
</fieldset> </fieldset>
</div> </div>
""") # i18n """)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
createFieldSet = (required = true)-> createFieldSet = (required = true)->
ctx = {roleList: $scope.roles, required: required} ctx = {roleList: $scope.roles, required: required}
return template(ctx) return $compile(template(ctx))($scope)
resetForm = -> resetForm = ->
$el.find("form textarea").remove("") $el.find("form textarea").remove("")
$el.find("form .add-member-wrapper").remove() $el.find("form .add-member-wrapper").remove()
invitations = $el.find(".add-member-forms") invitations = $el.find(".add-member-forms")
invitations.html(extraTextTemplate) invitations.html($compile(extraTextTemplate)($scope))
fieldSet = createFieldSet() fieldSet = createFieldSet()
invitations.prepend(fieldSet) invitations.prepend(fieldSet)
@ -155,5 +155,5 @@ CreateMembersDirective = ($rs, $rootScope, $confirm, $loading ,lightboxService)
return {link: link} return {link: link}
module.directive("tgLbCreateMembers", ["$tgResources", "$rootScope", "$tgConfirm", "$tgLoading", "lightboxService", module.directive("tgLbCreateMembers", ["$tgResources", "$rootScope", "$tgConfirm", "$tgLoading", "lightboxService", "$compile",
CreateMembersDirective]) CreateMembersDirective])

View File

@ -50,7 +50,6 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
@location, @navUrls, @analytics, @appTitle) -> @location, @navUrls, @analytics, @appTitle) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Manage Members" #i18n
@scope.project = {} @scope.project = {}
@scope.filters = {} @scope.filters = {}
@ -338,32 +337,31 @@ module.directive("tgMembershipsRowRoleSelector", ["$log", "$tgRepo", "$tgConfirm
## Member Actions Directive ## Member Actions Directive
############################################################################# #############################################################################
MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm) -> MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $translate) ->
activedTemplate = _.template(""" activedTemplate = """
<div class="active"> <div class="active", translate="ADMIN.MEMBERSHIP.STATUS_ACTIVE">
Active
</div> </div>
<a class="delete" href=""> <a class="delete" href="">
<span class="icon icon-delete"></span> <span class="icon icon-delete"></span>
</a> </a>
""") # TODO: i18n """
pendingTemplate = _.template(""" pendingTemplate = """
<a class="pending" href=""> <a class="pending" href="">
Pending {{'ADMIN.MEMBERSHIP.STATUS_PENDING' | translate}}
<span class="icon icon-reload"></span> <span class="icon icon-reload"></span>
</a> </a>
<a class="delete" href="" title="Delete"> <a class="delete" href="">
<span class="icon icon-delete"></span> <span class="icon icon-delete"></span>
</a> </a>
""") # TODO: i18n """
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
render = (member) -> render = (member) ->
if member.user if member.user
html = activedTemplate() html = $compile(activedTemplate)($scope)
else else
html = pendingTemplate() html = $compile(pendingTemplate)($scope)
$el.html(html) $el.html(html)
@ -377,29 +375,34 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm) ->
$el.on "click", ".pending", (event) -> $el.on "click", ".pending", (event) ->
event.preventDefault() event.preventDefault()
onSuccess = -> onSuccess = ->
# TODO: i18n text = $translate.instant("ADMIN.MEMBERSHIP.SUCCESS_SEND_INVITATION", {email: $scope.member.email})
$confirm.notify("success", "We've sent the invitationi again to '#{$scope.member.email}'.") $confirm.notify("success", text)
onError = -> onError = ->
$confirm.notify("error", "We haven't sent the invitation.") # TODO: i18n text = $translate.instant("ADMIM.MEMBERSHIP.ERROR_SEND_INVITATION")
$confirm.notify("error", text)
$rs.memberships.resendInvitation($scope.member.id).then(onSuccess, onError) $rs.memberships.resendInvitation($scope.member.id).then(onSuccess, onError)
$el.on "click", ".delete", (event) -> $el.on "click", ".delete", (event) ->
event.preventDefault() event.preventDefault()
title = "Delete member" # TODO: i18n title = $translate.instant("ADMIN.MEMBERSHIP.DELETE_MEMBER")
message = if member.user then member.full_name else "the invitation to #{member.email}" # TODO: i18n defaultMsg = $translate.instant("ADMIN.MEMBERSHIP.DEFAULT_DELETE_MESSAGE")
message = if member.user then member.full_name else defaultMsg
$confirm.askOnDelete(title, message).then (finish) -> $confirm.askOnDelete(title, message).then (finish) ->
onSuccess = -> onSuccess = ->
finish() finish()
$ctrl.loadMembers() $ctrl.loadMembers()
$confirm.notify("success", null, "We've deleted #{message}.") # TODO: i18n
text = $translate.instant("ADMIN.MEMBERSHIP.SUCCESS_DELETE")
$confirm.notify("success", null, text)
onError = -> onError = ->
finish(false) finish(false)
# TODO: i18in
$confirm.notify("error", null, "We have not been able to delete #{message}.") text = $translate.instant("ADMIN.MEMBERSHIP.ERROR_DELETE", {message: message})
$confirm.notify("error", null, text)
$repo.remove(member).then(onSuccess, onError) $repo.remove(member).then(onSuccess, onError)
@ -409,5 +412,4 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm) ->
return {link: link} return {link: link}
module.directive("tgMembershipsRowActions", ["$log", "$tgRepo", "$tgResources", "$tgConfirm", module.directive("tgMembershipsRowActions", ["$log", "$tgRepo", "$tgResources", "$tgConfirm", "$compile", "$translate", MembershipsRowActionsDirective])
MembershipsRowActionsDirective])

View File

@ -47,21 +47,26 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
"$q", "$q",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle, @translate) ->
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then => promise.then =>
@appTitle.set("Project profile - " + @scope.sectionName + " - " + @scope.project.name) sectionName = @translate.instant( @scope.sectionName)
appTitle = @translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", {sectionName: sectionName, projectName: @scope.project.name})
@appTitle.set(appTitle)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@scope.$on "project:loaded", => @scope.$on "project:loaded", =>
@appTitle.set("Project profile - " + @scope.sectionName + " - " + @scope.project.name) sectionName = @translate.instant( @scope.sectionName)
appTitle = @translate.instant("ADMIN.PROJECT_PROFILE.PAGE_TITLE", {sectionName: sectionName, projectName: @scope.project.name})
@appTitle.set(appTitle)
loadProject: -> loadProject: ->
return @rs.projects.get(@scope.projectId).then (project) => return @rs.projects.get(@scope.projectId).then (project) =>
@ -217,7 +222,7 @@ module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", Pro
## Project Export Directive ## Project Export Directive
############################################################################# #############################################################################
ProjectExportDirective = ($window, $rs, $confirm) -> ProjectExportDirective = ($window, $rs, $confirm, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
buttonsEl = $el.find(".admin-project-export-buttons") buttonsEl = $el.find(".admin-project-export-buttons")
showButtons = -> buttonsEl.removeClass("hidden") showButtons = -> buttonsEl.removeClass("hidden")
@ -232,16 +237,22 @@ ProjectExportDirective = ($window, $rs, $confirm) ->
hideSpinner = -> spinnerEl.addClass("hidden") hideSpinner = -> spinnerEl.addClass("hidden")
resultTitleEl = $el.find(".result-title") resultTitleEl = $el.find(".result-title")
setLoadingTitle = -> resultTitleEl.html("We are generating your dump file") # TODO: i18n
setAsyncTitle = -> resultTitleEl.html("We are generating your dump file") # TODO: i18n
setSyncTitle = -> resultTitleEl.html("Your dump file is ready!") # TODO: i18n loading_title = $translate.instant("ADMIN.PROJECT_EXPORT.LOADING_TITLE")
loading_msg = $translate.instant("ADMIN.PROJECT_EXPORT.LOADING_MESSAGE")
dump_ready_text = -> resultTitleEl.html("ADMIN.PROJECT_EXPORT.DUMP_READY")
asyn_message = -> resultTitleEl.html("ADMIN.PROJECT_EXPORT.ASYN_MESSAGE")
syn_message = -> resultTitleEl.html("ADMIN.PROJECT_EXPORT.SYNC_MESSAGE", {url: url})
setLoadingTitle = -> resultTitleEl.html(loading_text)
setAsyncTitle = -> resultTitleEl.html(loading_text)
setSyncTitle = -> resultTitleEl.html(dump_ready_text)
resultMessageEl = $el.find(".result-message ") resultMessageEl = $el.find(".result-message ")
setLoadingMessage = -> resultMessageEl.html("Please don't close this page.") # TODO: i18n setLoadingMessage = -> resultMessageEl.html(loading_msg)
setAsyncMessage = -> resultMessageEl.html("We will send you an email when ready.") # TODO: i18n setAsyncMessage = -> resultMessageEl.html(asyn_message)
setSyncMessage = (url) -> resultMessageEl.html("If the download doesn't start automatically click setSyncMessage = (url) -> resultMessageEl.html(syn_message)
<a href='#{url}' download title='Download
the dump file'>here.") # TODO: i18n
showLoadingMode = -> showLoadingMode = ->
showSpinner() showSpinner()
@ -279,15 +290,12 @@ ProjectExportDirective = ($window, $rs, $confirm) ->
onError = (result) => onError = (result) =>
showErrorMode() showErrorMode()
errorMsg = "Our oompa loompas have some problems generasting your dump. errorMsg = $translate.instant("ADMIN.PROJECT_PROFILE.ERROR")
Please try again. " # TODO: i18n
if result.status == 429 # TOO MANY REQUESTS if result.status == 429 # TOO MANY REQUESTS
errorMsg = "Sorry, our oompa loompas are very busy right now. errorMsg = $translate.instant("ADMIN.PROJECT_PROFILE.ERROR_BUSY")
Please try again in a few minutes. " # TODO: i18n
else if result.data?._error_message else if result.data?._error_message
errorMsg = "Our oompa loompas have some problems generasting your dump: errorMsg = $translate.instant("ADMIN.PROJECT_PROFILE.ERROR_BUSY", {message: result.data._error_message})
#{result.data._error_message}" # TODO: i18n
$confirm.notify("error", errorMsg) $confirm.notify("error", errorMsg)
@ -296,7 +304,7 @@ ProjectExportDirective = ($window, $rs, $confirm) ->
return {link:link} return {link:link}
module.directive("tgProjectExport", ["$window", "$tgResources", "$tgConfirm", ProjectExportDirective]) module.directive("tgProjectExport", ["$window", "$tgResources", "$tgConfirm", "$translate", ProjectExportDirective])
############################################################################# #############################################################################
@ -310,9 +318,10 @@ class CsvExporterController extends taiga.Controller
"$tgUrls", "$tgUrls",
"$tgConfirm", "$tgConfirm",
"$tgResources", "$tgResources",
"$translate"
] ]
constructor: (@scope, @rootscope, @urls, @confirm, @rs) -> constructor: (@scope, @rootscope, @urls, @confirm, @rs, @translate) ->
@rootscope.$on("project:loaded", @.setCsvUuid) @rootscope.$on("project:loaded", @.setCsvUuid)
@scope.$watch "csvUuid", (value) => @scope.$watch "csvUuid", (value) =>
if value if value
@ -337,10 +346,10 @@ class CsvExporterController extends taiga.Controller
return promise return promise
regenerateUuid: -> regenerateUuid: ->
#TODO: i18n
if @scope.csvUuid if @scope.csvUuid
title = "Change URL" title = @translate.instant("ADMIN.REPORTS.REGENERATE_TITLE")
subtitle = "You going to change the CSV data access url. The previous url will be disabled. Are you sure?" subtitle = @translate.instant("ADMIN.REPORTS.REGENERATE_SUBTITLE")
@confirm.ask(title, subtitle).then @._generateUuid @confirm.ask(title, subtitle).then @._generateUuid
else else
@._generateUuid(_.identity) @._generateUuid(_.identity)
@ -361,3 +370,48 @@ class CsvExporterIssuesController extends CsvExporterController
module.controller("CsvExporterUserstoriesController", CsvExporterUserstoriesController) module.controller("CsvExporterUserstoriesController", CsvExporterUserstoriesController)
module.controller("CsvExporterTasksController", CsvExporterTasksController) module.controller("CsvExporterTasksController", CsvExporterTasksController)
module.controller("CsvExporterIssuesController", CsvExporterIssuesController) module.controller("CsvExporterIssuesController", CsvExporterIssuesController)
#############################################################################
## CSV Directive
#############################################################################
CsvUsDirective = () ->
link = ($scope) ->
$scope.csvType = "US"
return {
controller: "CsvExporterUserstoriesController",
templateUrl: "admin/project-csv.html",
link: link,
scope: true
}
module.directive("tgCsvUs", [CsvUsDirective])
CsvTaskDirective = () ->
link = ($scope) ->
$scope.csvType = "Task"
return {
controller: "CsvExporterTasksController",
templateUrl: "admin/project-csv.html",
link: link,
scope: true
}
module.directive("tgCsvTask", [CsvTaskDirective])
CsvIssueDirective = () ->
link = ($scope) ->
$scope.csvType = "Issues"
return {
controller: "CsvExporterIssuesController",
templateUrl: "admin/project-csv.html",
link: link,
scope: true
}
module.directive("tgCsvIssue", [CsvIssueDirective])

View File

@ -46,16 +46,24 @@ class ProjectValuesSectionController extends mixOf(taiga.Controller, taiga.PageM
"$q", "$q",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle, @translate) ->
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then () => promise.then () =>
@appTitle.set("Project values - " + @scope.sectionName + " - " + @scope.project.name) sectionName = @translate.instant(@scope.sectionName)
title = @translate.instant("ADMIN.PROJECT_VALUES.APP_TITLE", {
"sectionName": sectionName,
"projectName": @scope.project.name
})
@appTitle.set(title)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@ -275,14 +283,12 @@ ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame) ->
if value.id != option.id if value.id != option.id
choices[option.id] = option.name choices[option.id] = option.name
#TODO: i18n
title = "Delete value"
subtitle = value.name subtitle = value.name
replacement = "All items with this value will be changed to"
if _.keys(choices).length == 0
return $confirm.error("You can't delete all values.")
return $confirm.askChoice(title, subtitle, choices, replacement).then (response) -> if _.keys(choices).length == 0
return $confirm.error("ADMIN.PROJECT_VALUES.ERROR_DELETE_ALL")
$confirm.askChoice("PROJECT.TITLE_ACTION_DELETE_VALUE", subtitle, choices, "ADMIN.PROJECT_VALUES.REPLACEMENT").then (response) ->
onSucces = -> onSucces = ->
$ctrl.loadValues().finally -> $ctrl.loadValues().finally ->
response.finish() response.finish()
@ -299,8 +305,7 @@ ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame) ->
return {link:link} return {link:link}
module.directive("tgProjectValues", ["$log", "$tgRepo", "$tgConfirm", "$tgLocation", "animationFrame", module.directive("tgProjectValues", ["$log", "$tgRepo", "$tgConfirm", "$tgLocation", "animationFrame", ProjectValuesDirective])
ProjectValuesDirective])
############################################################################# #############################################################################
@ -601,11 +606,9 @@ ProjectCustomAttributesDirective = ($log, $confirm, animationFrame) ->
deleteCustomAttribute = (formEl) -> deleteCustomAttribute = (formEl) ->
attr = formEl.scope().attr attr = formEl.scope().attr
title = "Delete custom attribute" # i18n
subtitle = "Remeber that all values in this custom field will be deleted.</br> Are you sure you want to continue?"
message = attr.name message = attr.name
$confirm.ask(title, subtitle, message).then (finish) ->
$confirm.ask("COMMON.CUSTOM_ATTRIBUTES.DELETE", "COMMON.CUSTOM_ATTRIBUTES.CONFIRM_DELETE", message).then (finish) ->
onSucces = -> onSucces = ->
$ctrl.loadCustomAttributes().finally -> $ctrl.loadCustomAttributes().finally ->
finish() finish()

View File

@ -44,20 +44,22 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
"$q", "$q",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @appTitle, @translate) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Permissions" #i18n @scope.sectionName = "ADMIN.MENU.PERMISSIONS"
@scope.project = {} @scope.project = {}
@scope.anyComputableRole = true @scope.anyComputableRole = true
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then () => promise.then () =>
@appTitle.set("Roles - " + @scope.project.name) title = @translate.instant("ADMIN.ROLES.SECTION_NAME", {projectName: @scope.project.name})
@appTitle.set(title)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@ -65,7 +67,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
return @rs.projects.get(@scope.projectId).then (project) => return @rs.projects.get(@scope.projectId).then (project) =>
if not project.i_am_owner if not project.i_am_owner
@location.path(@navUrls.resolve("permission-denied")) @location.path(@navUrls.resolve("permission-denied"))
@scope.project = project @scope.project = project
@scope.$emit('project:loaded', project) @scope.$emit('project:loaded', project)
@ -112,11 +114,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
@scope.$broadcast("role:changed", @scope.role) @scope.$broadcast("role:changed", @scope.role)
delete: -> delete: ->
# TODO: i18n
title = "Delete Role" # TODO: i18n
subtitle = @scope.role.name subtitle = @scope.role.name
replacement = "All the users with this role will be moved to" # TODO: i18n
warning = "<strong>Be careful, all role estimations will be removed</strong>" # TODO: i18n
choices = {} choices = {}
for role in @scope.roles for role in @scope.roles
@ -124,9 +122,9 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
choices[role.id] = role.name choices[role.id] = role.name
if _.keys(choices).length == 0 if _.keys(choices).length == 0
return @confirm.error("You can't delete all values.") # TODO: i18n return @confirm.error(@translate.instant("ADMIN.ROLES.ERROR_DELETE_ALL"))
return @confirm.askChoice(title, subtitle, choices, replacement, warning).then (response) => return @confirm.askChoice(@translate.instant("ADMIN.ROLES.TITLE_DELETE_ROLE"), subtitle, choices, @translate.instant("ADMIN.ROLES.REPLACEMENT_ROLE"), @translate.instant("ADMIN.ROLES.WARNING_DELETE_ROLE")).then (response) =>
promise = @repo.remove(@scope.role, {moveTo: response.selected}) promise = @repo.remove(@scope.role, {moveTo: response.selected})
promise.then => promise.then =>
@.loadProject() @.loadProject()

View File

@ -40,19 +40,21 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
"$routeParams", "$routeParams",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appTitle) -> constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appTitle, @translate) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Webhooks" #i18n @scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME"
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then () => promise.then () =>
@appTitle.set("Webhooks - " + @scope.project.name) text = @translate.instant("ADMIN.WEBHOOKS.APP_TITLE", {"projectName": @scope.project.name})
@appTitle.set(text)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@ -85,17 +87,19 @@ module.controller("WebhooksController", WebhooksController)
## Webhook Directive ## Webhook Directive
############################################################################# #############################################################################
WebhookDirective = ($rs, $repo, $confirm, $loading) -> WebhookDirective = ($rs, $repo, $confirm, $loading, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
webhook = $scope.$eval($attrs.tgWebhook) webhook = $scope.$eval($attrs.tgWebhook)
updateLogs = () -> updateLogs = () ->
prettyDate = $translate.instant("ADMIN.WEBHOOKS.DATE")
$rs.webhooklogs.list(webhook.id).then (webhooklogs) => $rs.webhooklogs.list(webhook.id).then (webhooklogs) =>
for log in webhooklogs for log in webhooklogs
log.validStatus = 200 <= log.status < 300 log.validStatus = 200 <= log.status < 300
log.prettySentHeaders = _.map(_.pairs(log.request_headers), ([header, value]) -> "#{header}: #{value}").join("\n") log.prettySentHeaders = _.map(_.pairs(log.request_headers), ([header, value]) -> "#{header}: #{value}").join("\n")
log.prettySentData = JSON.stringify(log.request_data) log.prettySentData = JSON.stringify(log.request_data)
log.prettyDate = moment(log.created).format("DD MMM YYYY [at] hh:mm:ss") # TODO: i18n log.prettyDate = moment(log.created).format(prettyDate)
webhook.logs_counter = webhooklogs.length webhook.logs_counter = webhooklogs.length
webhook.logs = webhooklogs webhook.logs = webhooklogs
@ -105,9 +109,11 @@ WebhookDirective = ($rs, $repo, $confirm, $loading) ->
textElement = $el.find(".toggle-history") textElement = $el.find(".toggle-history")
historyElement = textElement.parents(".single-webhook-wrapper").find(".webhooks-history") historyElement = textElement.parents(".single-webhook-wrapper").find(".webhooks-history")
if historyElement.hasClass("open") if historyElement.hasClass("open")
textElement.text("(Hide history)") # TODO: i18n text = $translate.instant("ADMIN.WEBHOOKS.ACTION_HIDE_HISTORY")
textElement.text(text)
else else
textElement.text("(Show history)") # TODO: i18n text = $translate.instant("ADMIN.WEBHOOKS.ACTION_SHOW_HISTORY")
textElement.text(text)
showVisualizationMode = () -> showVisualizationMode = () ->
$el.find(".edition-mode").addClass("hidden") $el.find(".edition-mode").addClass("hidden")
@ -161,8 +167,8 @@ WebhookDirective = ($rs, $repo, $confirm, $loading) ->
cancel(target) cancel(target)
$el.on "click", ".delete-webhook", () -> $el.on "click", ".delete-webhook", () ->
title = "Delete webhook" #TODO: i18n title = $translate.instant("ADMIN.WEBHOOKS.DELETE")
message = "Webhook '#{webhook.name}'" #TODO: i18n message = $translate.instant("ADMIN.WEBHOOKS.WEBHOOK_NAME", {name: webhook.name})
$confirm.askOnDelete(title, message).then (finish) => $confirm.askOnDelete(title, message).then (finish) =>
onSucces = -> onSucces = ->
@ -203,7 +209,7 @@ WebhookDirective = ($rs, $repo, $confirm, $loading) ->
return {link:link} return {link:link}
module.directive("tgWebhook", ["$tgResources", "$tgRepo", "$tgConfirm", "$tgLoading", WebhookDirective]) module.directive("tgWebhook", ["$tgResources", "$tgRepo", "$tgConfirm", "$tgLoading", "$translate", WebhookDirective])
############################################################################# #############################################################################
@ -279,19 +285,21 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgRepo", "$tgRepo",
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @repo, @rs, @params, @appTitle) -> constructor: (@scope, @repo, @rs, @params, @appTitle, @translate) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Github" #i18n @scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME")
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then () => promise.then () =>
@appTitle.set("Github - " + @scope.project.name) title = @translate.instant("ADMIN.GITHUB.APP_TITLE", {projectName: @scope.project.name})
@appTitle.set(title)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@ -327,18 +335,20 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgRepo", "$tgRepo",
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @repo, @rs, @params, @appTitle) -> constructor: (@scope, @repo, @rs, @params, @appTitle, @translate) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Gitlab" #i18n @scope.sectionName = @translate.instant("ADMIN.GITLAB.SECTION_NAME")
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then () => promise.then () =>
@appTitle.set("Gitlab - " + @scope.project.name) title = @translate.instant("ADMIN.GITLAB.APP_TITLE", {projectName: @scope.project.name})
@appTitle.set(title)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@ -377,18 +387,20 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
"$tgRepo", "$tgRepo",
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"$appTitle" "$appTitle",
"$translate"
] ]
constructor: (@scope, @repo, @rs, @params, @appTitle) -> constructor: (@scope, @repo, @rs, @params, @appTitle, @translate) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Bitbucket" #i18n @scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME")
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() promise = @.loadInitialData()
promise.then () => promise.then () =>
@appTitle.set("Bitbucket - " + @scope.project.name) title = @translate.instant("ADMIN.BITBUCKET.APP_TITLE", {projectName: @scope.project.name})
@appTitle.set(title)
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)

View File

@ -53,7 +53,6 @@ class AuthService extends taiga.Service
setUser: (user) -> setUser: (user) ->
@rootscope.auth = user @rootscope.auth = user
@rootscope.$broadcast("i18n:change", user.default_language)
@storage.set("userInfo", user.getAttrs()) @storage.set("userInfo", user.getAttrs())
@rootscope.user = user @rootscope.user = user
@ -171,7 +170,7 @@ PublicRegisterMessageDirective = ($config, $navUrls, templates) ->
module.directive("tgPublicRegisterMessage", ["$tgConfig", "$tgNavUrls", "$tgTemplate", PublicRegisterMessageDirective]) module.directive("tgPublicRegisterMessage", ["$tgConfig", "$tgNavUrls", "$tgTemplate", PublicRegisterMessageDirective])
LoginDirective = ($auth, $confirm, $location, $config, $routeParams, $navUrls, $events) -> LoginDirective = ($auth, $confirm, $location, $config, $routeParams, $navUrls, $events, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
onSuccess = (response) -> onSuccess = (response) ->
if $routeParams['next'] and $routeParams['next'] != $navUrls.resolve("login") if $routeParams['next'] and $routeParams['next'] != $navUrls.resolve("login")
@ -183,8 +182,8 @@ LoginDirective = ($auth, $confirm, $location, $config, $routeParams, $navUrls, $
$location.path(nextUrl) $location.path(nextUrl)
onError = (response) -> onError = (response) ->
$confirm.notify("light-error", "According to our Oompa Loompas, your username/email $confirm.notify("light-error", $translate.instant("LOGIN_FORM.ERROR_AUTH_INCORRECT"))
or password are incorrect.") #TODO: i18n
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -207,13 +206,13 @@ LoginDirective = ($auth, $confirm, $location, $config, $routeParams, $navUrls, $
return {link:link} return {link:link}
module.directive("tgLogin", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgConfig", "$routeParams", module.directive("tgLogin", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgConfig", "$routeParams",
"$tgNavUrls", "$tgEvents", LoginDirective]) "$tgNavUrls", "$tgEvents", "$translate", LoginDirective])
############################################################################# #############################################################################
## Register Directive ## Register Directive
############################################################################# #############################################################################
RegisterDirective = ($auth, $confirm, $location, $navUrls, $config, $analytics) -> RegisterDirective = ($auth, $confirm, $location, $navUrls, $config, $analytics, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
if not $config.get("publicRegisterEnabled") if not $config.get("publicRegisterEnabled")
$location.path($navUrls.resolve("not-found")) $location.path($navUrls.resolve("not-found"))
@ -224,12 +223,15 @@ RegisterDirective = ($auth, $confirm, $location, $navUrls, $config, $analytics)
onSuccessSubmit = (response) -> onSuccessSubmit = (response) ->
$analytics.trackEvent("auth", "register", "user registration", 1) $analytics.trackEvent("auth", "register", "user registration", 1)
$confirm.notify("success", "Our Oompa Loompas are happy, welcome to Taiga.") #TODO: i18n
$confirm.notify("success", $translate.instant("LOGIN_FORM.SUCCESS"))
$location.path($navUrls.resolve("home")) $location.path($navUrls.resolve("home"))
onErrorSubmit = (response) -> onErrorSubmit = (response) ->
if response.data._error_message? if response.data._error_message?
$confirm.notify("light-error", "According to our Oompa Loompas there was an error. #{response.data._error_message}") #TODO: i18n text = $translate.instant("LOGIN_FORM.ERROR_GENERIC") + " " + response.data._error_message
$confirm.notify("light-error", text + " " + response.data._error_message)
form.setErrors(response.data) form.setErrors(response.data)
@ -247,27 +249,27 @@ RegisterDirective = ($auth, $confirm, $location, $navUrls, $config, $analytics)
return {link:link} return {link:link}
module.directive("tgRegister", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgNavUrls", "$tgConfig", module.directive("tgRegister", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgNavUrls", "$tgConfig",
"$tgAnalytics", RegisterDirective]) "$tgAnalytics", "$translate", RegisterDirective])
############################################################################# #############################################################################
## Forgot Password Directive ## Forgot Password Directive
############################################################################# #############################################################################
ForgotPasswordDirective = ($auth, $confirm, $location, $navUrls) -> ForgotPasswordDirective = ($auth, $confirm, $location, $navUrls, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$scope.data = {} $scope.data = {}
form = $el.find("form").checksley() form = $el.find("form").checksley()
onSuccessSubmit = (response) -> onSuccessSubmit = (response) ->
$location.path($navUrls.resolve("login")) $location.path($navUrls.resolve("login"))
$confirm.success("<strong>Check your inbox!</strong><br />
We have sent a mail to<br /> text = $translate.instant("FORGOT_PASSWORD_FORM.SUCCESS", {email: response.data.email})
<strong>#{response.data.email}</strong><br /> $confirm.success(text)
with the instructions to set a new password") #TODO: i18n
onErrorSubmit = (response) -> onErrorSubmit = (response) ->
$confirm.notify("light-error", "According to our Oompa Loompas, text = $translate.instant("FORGOT_PASSWORD_FORM.ERROR")
your are not registered yet.") #TODO: i18n
$confirm.notify("light-error", text)
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -282,14 +284,14 @@ ForgotPasswordDirective = ($auth, $confirm, $location, $navUrls) ->
return {link:link} return {link:link}
module.directive("tgForgotPassword", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgNavUrls", module.directive("tgForgotPassword", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgNavUrls", "$translate",
ForgotPasswordDirective]) ForgotPasswordDirective])
############################################################################# #############################################################################
## Change Password from Recovery Directive ## Change Password from Recovery Directive
############################################################################# #############################################################################
ChangePasswordFromRecoveryDirective = ($auth, $confirm, $location, $params, $navUrls) -> ChangePasswordFromRecoveryDirective = ($auth, $confirm, $location, $params, $navUrls, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$scope.data = {} $scope.data = {}
@ -303,12 +305,15 @@ ChangePasswordFromRecoveryDirective = ($auth, $confirm, $location, $params, $nav
onSuccessSubmit = (response) -> onSuccessSubmit = (response) ->
$location.path($navUrls.resolve("login")) $location.path($navUrls.resolve("login"))
$confirm.success("Our Oompa Loompas saved your new password.<br />
Try to <strong>sign in</strong> with it.") #TODO: i18n text = $translate.instant("CHANGE_PASSWORD_RECOVERY_FORM.SUCCESS")
$confirm.success(text)
onErrorSubmit = (response) -> onErrorSubmit = (response) ->
$confirm.notify("light-error", "One of our Oompa Loompas say text = $translate.instant("COMMON.GENERIC_ERROR", {error: response.data._error_message})
'#{response.data._error_message}'.") #TODO: i18n
$confirm.notify("light-error", text)
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -324,13 +329,13 @@ ChangePasswordFromRecoveryDirective = ($auth, $confirm, $location, $params, $nav
return {link:link} return {link:link}
module.directive("tgChangePasswordFromRecovery", ["$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams", module.directive("tgChangePasswordFromRecovery", ["$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams",
"$tgNavUrls", ChangePasswordFromRecoveryDirective]) "$tgNavUrls", "$translate", ChangePasswordFromRecoveryDirective])
############################################################################# #############################################################################
## Invitation ## Invitation
############################################################################# #############################################################################
InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics) -> InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
token = $params.token token = $params.token
@ -340,8 +345,9 @@ InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics
promise.then null, (response) -> promise.then null, (response) ->
$location.path($navUrls.resolve("login")) $location.path($navUrls.resolve("login"))
$confirm.success("<strong>Ooops, we have a problem</strong><br />
Our Oompa Loompas can't find your invitation.") #TODO: i18n text = $translate.instant("INVITATION_LOGIN_FORM.NOT_FOUND")
$confirm.success(text)
# Login form # Login form
$scope.dataLogin = {token: token} $scope.dataLogin = {token: token}
@ -350,12 +356,14 @@ InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics
onSuccessSubmitLogin = (response) -> onSuccessSubmitLogin = (response) ->
$analytics.trackEvent("auth", "invitationAccept", "invitation accept with existing user", 1) $analytics.trackEvent("auth", "invitationAccept", "invitation accept with existing user", 1)
$location.path($navUrls.resolve("project", {project: $scope.invitation.project_slug})) $location.path($navUrls.resolve("project", {project: $scope.invitation.project_slug}))
$confirm.notify("success", "You've successfully joined this project", text = $translate.instant("INVITATION_LOGIN_FORM.SUCCESS", {"project_name": $scope.invitation.project_name})
"Welcome to #{_.escape($scope.invitation.project_name)}")
$confirm.notify("success", text)
onErrorSubmitLogin = (response) -> onErrorSubmitLogin = (response) ->
$confirm.notify("light-error", "According to our Oompa Loompas, your are not registered yet or text = $translate.instant("INVITATION_LOGIN_FORM.ERROR")
typed an invalid password.") #TODO: i18n
$confirm.notify("light-error", text)
submitLogin = debounce 2000, (event) => submitLogin = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -380,8 +388,9 @@ InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics
"Welcome to #{_.escape($scope.invitation.project_name)}") "Welcome to #{_.escape($scope.invitation.project_name)}")
onErrorSubmitRegister = (response) -> onErrorSubmitRegister = (response) ->
$confirm.notify("light-error", "According to our Oompa Loompas, that text = $translate.instant("LOGIN_FORM.ERROR_AUTH_INCORRECT")
username or email is already in use.") #TODO: i18n
$confirm.notify("light-error", text)
submitRegister = debounce 2000, (event) => submitRegister = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -398,13 +407,13 @@ InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics
return {link:link} return {link:link}
module.directive("tgInvitation", ["$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams", module.directive("tgInvitation", ["$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams",
"$tgNavUrls", "$tgAnalytics", InvitationDirective]) "$tgNavUrls", "$tgAnalytics", "$translate", InvitationDirective])
############################################################################# #############################################################################
## Change Email ## Change Email
############################################################################# #############################################################################
ChangeEmailDirective = ($repo, $model, $auth, $confirm, $location, $params, $navUrls) -> ChangeEmailDirective = ($repo, $model, $auth, $confirm, $location, $params, $navUrls, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$scope.data = {} $scope.data = {}
$scope.data.email_token = $params.email_token $scope.data.email_token = $params.email_token
@ -414,11 +423,14 @@ ChangeEmailDirective = ($repo, $model, $auth, $confirm, $location, $params, $nav
$repo.queryOne("users", $auth.getUser().id).then (data) => $repo.queryOne("users", $auth.getUser().id).then (data) =>
$auth.setUser(data) $auth.setUser(data)
$location.path($navUrls.resolve("home")) $location.path($navUrls.resolve("home"))
$confirm.success("Our Oompa Loompas updated your email") #TODO: i18n
text = $translate.instant("CHANGE_EMAIL_FORM.SUCCESS")
$confirm.success(text)
onErrorSubmit = (response) -> onErrorSubmit = (response) ->
$confirm.notify("error", "One of our Oompa Loompas says text = $translate.instant("COMMON.GENERIC_ERROR", {error: response.data._error_message})
'#{response.data._error_message}'.") #TODO: i18n
$confirm.notify("light-error", text)
submit = -> submit = ->
if not form.validate() if not form.validate()
@ -438,7 +450,7 @@ ChangeEmailDirective = ($repo, $model, $auth, $confirm, $location, $params, $nav
return {link:link} return {link:link}
module.directive("tgChangeEmail", ["$tgRepo", "$tgModel", "$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams", module.directive("tgChangeEmail", ["$tgRepo", "$tgModel", "$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams",
"$tgNavUrls", ChangeEmailDirective]) "$tgNavUrls", "$translate", ChangeEmailDirective])
############################################################################# #############################################################################
## Cancel account ## Cancel account
@ -453,11 +465,15 @@ CancelAccountDirective = ($repo, $model, $auth, $confirm, $location, $params, $n
onSuccessSubmit = (response) -> onSuccessSubmit = (response) ->
$auth.logout() $auth.logout()
$location.path($navUrls.resolve("home")) $location.path($navUrls.resolve("home"))
$confirm.success("Our Oompa Loompas removed your account") #TODO: i18n
text = $translate.instant("CANCEL_ACCOUNT.SUCCESS")
$confirm.success(text)
onErrorSubmit = (response) -> onErrorSubmit = (response) ->
$confirm.notify("error", "One of our Oompa Loompas says text = $translate.instant("COMMON.GENERIC_ERROR", {error: response.data._error_message})
'#{response.data._error_message}'.") #TODO: i18n
$confirm.notify("error", text)
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()

View File

@ -29,7 +29,7 @@ module = angular.module("taigaBacklog")
## Creare/Edit Sprint Lightbox Directive ## Creare/Edit Sprint Lightbox Directive
############################################################################# #############################################################################
CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading) -> CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading, $translate) ->
link = ($scope, $el, attrs) -> link = ($scope, $el, attrs) ->
hasErrors = false hasErrors = false
createSprint = true createSprint = true
@ -86,8 +86,7 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading)
$confirm.notify("light-error", data.__all__[0]) $confirm.notify("light-error", data.__all__[0])
remove = -> remove = ->
#TODO: i18n title = $translate.instant("LIGHTBOX.DELETE_SPRINT.TITLE")
title = "Delete sprint"
message = $scope.sprint.name message = $scope.sprint.name
$confirm.askOnDelete(title, message).then (finish) => $confirm.askOnDelete(title, message).then (finish) =>
@ -129,11 +128,17 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading)
lastSprintNameDom = $el.find(".last-sprint-name") lastSprintNameDom = $el.find(".last-sprint-name")
if lastSprint?.name? if lastSprint?.name?
lastSprintNameDom.html(" last sprint is <strong> #{lastSprint.name} ;-) </strong>") text = $translate.instant("LIGHTBOX.ADD_EDIT_SPRINT.LAST_SPRINT_NAME", {"lastSprint": lastSprint.name})
lastSprintNameDom.html(text)
$el.find(".delete-sprint").addClass("hidden") $el.find(".delete-sprint").addClass("hidden")
$el.find(".title").text("New sprint") #TODO i18n
$el.find(".button-green").text("Create") #TODO i18n text = $translate.instant("LIGHTBOX.ADD_EDIT_SPRINT.TITLE")
$el.find(".title").text(text)
text = $translate.instant("COMMON.CREATE")
$el.find(".button-green").text(text)
lightboxService.open($el) lightboxService.open($el)
$el.find(".sprint-name").focus() $el.find(".sprint-name").focus()
$el.find(".last-sprint-name").removeClass("disappear") $el.find(".last-sprint-name").removeClass("disappear")
@ -146,8 +151,13 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading)
$scope.sprint.estimated_finish = moment($scope.sprint.estimated_finish).format("DD MMM YYYY") $scope.sprint.estimated_finish = moment($scope.sprint.estimated_finish).format("DD MMM YYYY")
$el.find(".delete-sprint").removeClass("hidden") $el.find(".delete-sprint").removeClass("hidden")
$el.find(".title").text("Edit sprint") #TODO i18n
$el.find(".button-green").text("Save") #TODO i18n editSprint = $translate.instant("BACKLOG.EDIT_SPRINT")
$el.find(".title").text(editSprint)
save = $translate.instant("COMMON.SAVE")
$el.find(".button-green").text(save)
lightboxService.open($el) lightboxService.open($el)
$el.find(".sprint-name").focus().select() $el.find(".sprint-name").focus().select()
$el.find(".last-sprint-name").addClass("disappear") $el.find(".last-sprint-name").addClass("disappear")
@ -178,6 +188,7 @@ module.directive("tgLbCreateEditSprint", [
"$tgResources", "$tgResources",
"$rootScope", "$rootScope",
"lightboxService" "lightboxService"
"$tgLoading" "$tgLoading",
"$translate",
CreateEditSprint CreateEditSprint
]) ])

View File

@ -49,11 +49,12 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
"$tgNavUrls", "$tgNavUrls",
"$tgEvents", "$tgEvents",
"$tgAnalytics", "$tgAnalytics",
"tgLoader" "tgLoader",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q,
@location, @appTitle, @navUrls, @events, @analytics, tgLoader) -> @location, @appTitle, @navUrls, @events, @analytics, tgLoader, @translate) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Backlog" @scope.sectionName = "Backlog"
@ -509,8 +510,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@rootscope.$broadcast("usform:edit", us) @rootscope.$broadcast("usform:edit", us)
deleteUserStory: (us) -> deleteUserStory: (us) ->
#TODO: i18n title = @translate.instant("US.TITLE_DELETE_ACTION")
title = "Delete User Story"
message = us.subject message = us.subject
@confirm.askOnDelete(title, message).then (finish) => @confirm.askOnDelete(title, message).then (finish) =>
@ -541,12 +542,11 @@ module.controller("BacklogController", BacklogController)
## Backlog Directive ## Backlog Directive
############################################################################# #############################################################################
BacklogDirective = ($repo, $rootscope) -> BacklogDirective = ($repo, $rootscope, $translate) ->
## Doom line Link ## Doom line Link
doomLineTemplate = _.template(""" doomLineTemplate = _.template("""
<div class="doom-line"><span>Project Scope [Doomline]</span></div> <div class="doom-line"><span><%- text %></span></div>
""") """)
# TODO: i18n
linkDoomLine = ($scope, $el, $attrs, $ctrl) -> linkDoomLine = ($scope, $el, $attrs, $ctrl) ->
reloadDoomLine = -> reloadDoomLine = ->
@ -573,7 +573,8 @@ BacklogDirective = ($repo, $rootscope) ->
$el.find(".doom-line").remove() $el.find(".doom-line").remove()
addDoomLineDom = (element) -> addDoomLineDom = (element) ->
$(element).before(doomLineTemplate({})) text = $translate.instant("BACKLOG.DOOMLINE")
$(element).before(doomLineTemplate({"text": text}))
getUsItems = -> getUsItems = ->
rowElements = $el.find('.backlog-table-body .us-item-row') rowElements = $el.find('.backlog-table-body .us-item-row')
@ -643,10 +644,14 @@ BacklogDirective = ($repo, $rootscope) ->
if $ctrl.showTags if $ctrl.showTags
elm.addClass("active") elm.addClass("active")
elm.find(".text").text("Hide Tags") # TODO: i18n
text = $translate.instant("BACKLOG.TAGS.HIDE")
elm.find(".text").text(text)
else else
elm.removeClass("active") elm.removeClass("active")
elm.find(".text").text("Show Tags") # TODO: i18n
text = $translate.instant("BACKLOG.TAGS.SHOW")
elm.find(".text").text(text)
showHideFilter = ($scope, $el, $ctrl) -> showHideFilter = ($scope, $el, $ctrl) ->
sidebar = $el.find("sidebar.filters-bar") sidebar = $el.find("sidebar.filters-bar")
@ -660,7 +665,10 @@ BacklogDirective = ($repo, $rootscope) ->
sidebar.toggleClass("active") sidebar.toggleClass("active")
target.toggleClass("active") target.toggleClass("active")
toggleText(target.find(".text"), ["Remove Filters", "Show Filters"]) # TODO: i18n removeText = $translate.instant("BACKLOG.FILTERS.REMOVE")
showText = $translate.instant("BACKLOG.FILTERS.SHOW")
toggleText(target.find(".text"), [removeText, showText])
if !sidebar.hasClass("active") if !sidebar.hasClass("active")
$ctrl.resetFilters() $ctrl.resetFilters()
@ -701,14 +709,13 @@ BacklogDirective = ($repo, $rootscope) ->
return {link: link} return {link: link}
module.directive("tgBacklog", ["$tgRepo", "$rootScope", BacklogDirective]) module.directive("tgBacklog", ["$tgRepo", "$rootScope", "$translate", BacklogDirective])
############################################################################# #############################################################################
## User story points directive ## User story points directive
############################################################################# #############################################################################
UsRolePointsSelectorDirective = ($rootscope, $template) -> UsRolePointsSelectorDirective = ($rootscope, $template, $compile, $translate) ->
#TODO: i18n
selectionTemplate = $template.get("backlog/us-role-points-popover.html", true) selectionTemplate = $template.get("backlog/us-role-points-popover.html", true)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
@ -718,7 +725,7 @@ UsRolePointsSelectorDirective = ($rootscope, $template) ->
numberOfRoles = _.size(roles) numberOfRoles = _.size(roles)
if numberOfRoles > 1 if numberOfRoles > 1
$el.append(selectionTemplate({"roles":roles})) $el.append($compile(selectionTemplate({"roles": roles}))($scope))
else else
$el.find(".icon-arrow-bottom").remove() $el.find(".icon-arrow-bottom").remove()
$el.find(".header-points").addClass("not-clickable") $el.find(".header-points").addClass("not-clickable")
@ -729,7 +736,9 @@ UsRolePointsSelectorDirective = ($rootscope, $template) ->
$scope.$on "uspoints:clear-selection", (ctx, roleId) -> $scope.$on "uspoints:clear-selection", (ctx, roleId) ->
$el.find(".popover").popover().close() $el.find(".popover").popover().close()
$el.find(".header-points").text("Points") #TODO: i18n
text = $translate.instant("COMMON.FIELDS.POINTS")
$el.find(".header-points").text(text)
# Dom Event Handlers # Dom Event Handlers
$el.on "click", (event) -> $el.on "click", (event) ->
@ -757,7 +766,7 @@ UsRolePointsSelectorDirective = ($rootscope, $template) ->
return {link: link} return {link: link}
module.directive("tgUsRolePointsSelector", ["$rootScope", "$tgTemplate", UsRolePointsSelectorDirective]) module.directive("tgUsRolePointsSelector", ["$rootScope", "$tgTemplate", "$compile", UsRolePointsSelectorDirective])
UsPointsDirective = ($tgEstimationsService, $repo, $tgTemplate) -> UsPointsDirective = ($tgEstimationsService, $repo, $tgTemplate) ->
@ -866,7 +875,7 @@ module.directive("tgBacklogUsPoints", ["$tgEstimationsService", "$tgRepo", "$tgT
## Burndown graph directive ## Burndown graph directive
############################################################################# #############################################################################
tgBacklogGraphDirective = -> tgBacklogGraphDirective = ($translate) ->
redrawChart = (element, dataToDraw) -> redrawChart = (element, dataToDraw) ->
width = element.width() width = element.width()
element.height(width/6) element.height(width/6)
@ -946,18 +955,17 @@ tgBacklogGraphDirective = ->
tooltip: true tooltip: true
tooltipOpts: { tooltipOpts: {
content: (label, xval, yval, flotItem) -> content: (label, xval, yval, flotItem) ->
#TODO: i18n
if flotItem.seriesIndex == 1 if flotItem.seriesIndex == 1
return "Optimal pending points for sprint #{xval} should be #{yval}" return $translate.instant("BACKLOG.OPTIMA", {xval: xval, yval: yval})
else if flotItem.seriesIndex == 2 else if flotItem.seriesIndex == 2
return "Real pending points for sprint #{xval} is #{yval}" return $translate.instant("BACKLOG.REAL", {xval: xval, yval: yval})
else if flotItem.seriesIndex == 3 else if flotItem.seriesIndex == 3
return "Incremented points by team requirements for sprint #{xval} is #{Math.abs(yval)}" return $translate.instant("BACKLOG.INCREMENT_TEAM", {xval: xval, yval: Math.abs(yval)})
else else
return "Incremented points by client requirements for sprint #{xval} is #{Math.abs(yval)}" return $translate.instant("BACKLOG.INCREMENT_CLIENT", {xval: xval, yval: Math.abs(yval)})
} }
} }
@ -980,7 +988,7 @@ tgBacklogGraphDirective = ->
return {link: link} return {link: link}
module.directive("tgGmBacklogGraph", tgBacklogGraphDirective) module.directive("tgGmBacklogGraph", ["$translate", tgBacklogGraphDirective])
############################################################################# #############################################################################

View File

@ -39,7 +39,7 @@ deleteElement = (el) ->
el.off() el.off()
el.remove() el.remove()
BacklogSortableDirective = ($repo, $rs, $rootscope, $tgConfirm) -> BacklogSortableDirective = ($repo, $rs, $rootscope, $tgConfirm, $translate) ->
# Notes about jquery bug: # Notes about jquery bug:
# http://stackoverflow.com/questions/5791886/jquery-draggable-shows- # http://stackoverflow.com/questions/5791886/jquery-draggable-shows-
# helper-in-wrong-place-when-scrolled-down-page # helper-in-wrong-place-when-scrolled-down-page
@ -54,7 +54,8 @@ BacklogSortableDirective = ($repo, $rs, $rootscope, $tgConfirm) ->
return return
filterError = -> filterError = ->
$tgConfirm.notify("error", "You can't drop on backlog when filters are open") #TODO: i18n text = $translate.instant("BACKLOG.SORTABLE_FILTER_ERROR")
$tgConfirm.notify(text)
$el.sortable({ $el.sortable({
items: ".us-item-row", items: ".us-item-row",
@ -211,6 +212,7 @@ module.directive("tgBacklogSortable", [
"$tgResources", "$tgResources",
"$rootScope", "$rootScope",
"$tgConfirm", "$tgConfirm",
"$translate",
BacklogSortableDirective BacklogSortableDirective
]) ])

View File

@ -85,8 +85,8 @@ module.directive("tgBacklogSprint", ["$tgRepo", "$rootScope", BacklogSprintDirec
## Sprint Header Directive ## Sprint Header Directive
############################################################################# #############################################################################
BacklogSprintHeaderDirective = ($navUrls, $template) -> BacklogSprintHeaderDirective = ($navUrls, $template, $compile) ->
template = $template.get("backlog/sprint-header.html", true) template = $template.get("backlog/sprint-header.html")
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
isEditable = -> isEditable = ->
@ -112,8 +112,13 @@ BacklogSprintHeaderDirective = ($navUrls, $template) ->
isVisible: isVisible() isVisible: isVisible()
isEditable: isEditable() isEditable: isEditable()
} }
$el.html(template(ctx))
templateScope = $scope.$new()
_.assign(templateScope, ctx)
compiledTemplate = $compile(template)(templateScope)
$el.html(compiledTemplate)
$scope.$watch $attrs.ngModel, (sprint) -> $scope.$watch $attrs.ngModel, (sprint) ->
render(sprint) render(sprint)
@ -130,13 +135,13 @@ BacklogSprintHeaderDirective = ($navUrls, $template) ->
require: "ngModel" require: "ngModel"
} }
module.directive("tgBacklogSprintHeader", ["$tgNavUrls", "$tgTemplate", BacklogSprintHeaderDirective]) module.directive("tgBacklogSprintHeader", ["$tgNavUrls", "$tgTemplate", "$compile", BacklogSprintHeaderDirective])
############################################################################# #############################################################################
## Toggle Closed Sprints Directive ## Toggle Closed Sprints Directive
############################################################################# #############################################################################
ToggleExcludeClosedSprintsVisualization = ($rootscope, $loading) -> ToggleExcludeClosedSprintsVisualization = ($rootscope, $loading, $translate) ->
excludeClosedSprints = true excludeClosedSprints = true
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
@ -162,14 +167,15 @@ ToggleExcludeClosedSprintsVisualization = ($rootscope, $loading) ->
$scope.$on "closed-sprints:reloaded", (ctx, sprints) => $scope.$on "closed-sprints:reloaded", (ctx, sprints) =>
$loading.finish(loadingElm) $loading.finish(loadingElm)
#TODO: i18n
if sprints.length > 0 if sprints.length > 0
text = "Hide closed sprints" key = "BACKLOG.SPRINTS.ACTION_HIDE_CLOSED_SPRINTS"
else else
text = "Show closed sprints" key = "BACKLOG.SPRINTS.ACTION_SHOW_CLOSED_SPRINTS"
text = $translate.instant(key)
$el.find(".text").text(text) $el.find(".text").text(text)
return {link: link} return {link: link}
module.directive("tgBacklogToggleClosedSprintsVisualization", ["$rootScope", "$tgLoading", ToggleExcludeClosedSprintsVisualization]) module.directive("tgBacklogToggleClosedSprintsVisualization", ["$rootScope", "$tgLoading", "$translate", ToggleExcludeClosedSprintsVisualization])

View File

@ -23,7 +23,7 @@ taiga = @.taiga
groupBy = @.taiga.groupBy groupBy = @.taiga.groupBy
bindOnce = @.taiga.bindOnce bindOnce = @.taiga.bindOnce
module = angular.module("taigaBase", ["taigaLocales"]) module = angular.module("taigaBase", [])
############################################################################# #############################################################################
## Main Directive ## Main Directive

View File

@ -1,74 +0,0 @@
###
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
#
# 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: modules/base/i18n.coffee
###
taiga = @.taiga
bindOnce = @.taiga.bindOnce
defaults = {
ns: "app"
fallbackLng: "en"
async: false
lng: "en"
}
class I18nService extends taiga.Service
constructor: (@rootscope, localesEn) ->
@.options = _.clone(defaults, true)
@.options.resStore = {
en: { app: localesEn }
}
setLanguage: (language) ->
i18n.setLng(language)
@rootscope.currentLang = language
@rootscope.$broadcast("i18n:changeLang", language)
initialize: ->
i18n.init(@.options)
@rootscope.t = i18n.t
t: (path, opts) ->
return i18n.t(path, opts)
I18nDirective = ($rootscope, $i18n) ->
link = ($scope, $el, $attrs) ->
values = $attrs.tr.split(",")
options = $attrs.trOpts or '{}'
opts = $scope.$eval(options)
for v in values
if v.indexOf(":") == -1
$el.html(_.escape($i18n.t(v, opts)))
else
[ns, v] = v.split(":")
$el.attr(ns, _.escape($i18n.t(v, opts)))
return {
link: link
restrict: "A"
scope: false
}
module = angular.module("taigaBase")
module.service("$tgI18n", ["$rootScope", "localesEn", I18nService])
module.directive("tr", ["$rootScope", "$tgI18n", I18nDirective])

View File

@ -220,8 +220,8 @@ AttachmentsDirective = ($config, $confirm, $templates) ->
templateFn = ($el, $attrs) -> templateFn = ($el, $attrs) ->
maxFileSize = $config.get("maxUploadFileSize", null) maxFileSize = $config.get("maxUploadFileSize", null)
maxFileSize = sizeFormat(maxFileSize) if maxFileSize maxFileSize = sizeFormat(maxFileSize) if maxFileSize
maxFileSizeMsg = if maxFileSize then "Maximum upload size is #{maxFileSize}" else "" # TODO: i18n maxFileSizeMsg = if maxFileSize then $translation.instant("ATTACHMENT.MAX_UPLOAD_SIZE") else ""
maxFileSize = 4000
ctx = { ctx = {
type: $attrs.type type: $attrs.type
maxFileSize: maxFileSize maxFileSize: maxFileSize
@ -242,7 +242,7 @@ AttachmentsDirective = ($config, $confirm, $templates) ->
module.directive("tgAttachments", ["$tgConfig", "$tgConfirm", "$tgTemplate", AttachmentsDirective]) module.directive("tgAttachments", ["$tgConfig", "$tgConfirm", "$tgTemplate", AttachmentsDirective])
AttachmentDirective = ($template) -> AttachmentDirective = ($template, $compile) ->
template = $template.get("attachment/attachment.html", true) template = $template.get("attachment/attachment.html", true)
templateEdit = $template.get("attachment/attachment-edit.html", true) templateEdit = $template.get("attachment/attachment-edit.html", true)
@ -254,7 +254,7 @@ AttachmentDirective = ($template) ->
ctx = { ctx = {
id: attachment.id id: attachment.id
name: attachment.name name: attachment.name
created_date: moment(attachment.created_date).format("DD MMM YYYY [at] hh:mm") #TODO: i18n created_date: moment(attachment.created_date).format("ATTACHMENT.DATE")
url: attachment.url url: attachment.url
size: sizeFormat(attachment.size) size: sizeFormat(attachment.size)
description: attachment.description description: attachment.description
@ -263,9 +263,9 @@ AttachmentDirective = ($template) ->
} }
if edit if edit
html = templateEdit(ctx) html = $compile(templateEdit(ctx))($scope)
else else
html = template(ctx) html = $compile(template(ctx))($scope)
$el.html(html) $el.html(html)
@ -322,4 +322,4 @@ AttachmentDirective = ($template) ->
restrict: "AE" restrict: "AE"
} }
module.directive("tgAttachment", ["$tgTemplate", AttachmentDirective]) module.directive("tgAttachment", ["$tgTemplate", "$compile", AttachmentDirective])

View File

@ -107,7 +107,7 @@ module.directive("tgSprintProgressbar", SprintProgressBarDirective)
## Created-by display directive ## Created-by display directive
############################################################################# #############################################################################
CreatedByDisplayDirective = ($template)-> CreatedByDisplayDirective = ($template, $compile)->
# Display the owner information (full name and photo) and the date of # Display the owner information (full name and photo) and the date of
# creation of an object (like USs, tasks and issues). # creation of an object (like USs, tasks and issues).
# #
@ -119,7 +119,7 @@ CreatedByDisplayDirective = ($template)->
# 'owner'(ng-model) # 'owner'(ng-model)
# - scope.usersById object is required. # - scope.usersById object is required.
template = $template.get("common/components/created-by.html", true) # TODO: i18n template = $template.get("common/components/created-by.html", true)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
render = (model) -> render = (model) ->
@ -127,10 +127,14 @@ CreatedByDisplayDirective = ($template)->
full_name_display: "external user" full_name_display: "external user"
photo: "/images/unnamed.png" photo: "/images/unnamed.png"
} }
html = template({ html = template({
owner: owner owner: owner
date: moment(model.created_date).format("DD MMM YYYY HH:mm") date: moment(model.created_date).format("DD MMM YYYY HH:mm")
}) })
html = $compile(html)($scope)
$el.html(html) $el.html(html)
bindOnce $scope, $attrs.ngModel, (model) -> bindOnce $scope, $attrs.ngModel, (model) ->
@ -145,18 +149,16 @@ CreatedByDisplayDirective = ($template)->
require: "ngModel" require: "ngModel"
} }
module.directive("tgCreatedByDisplay", ["$tgTemplate", CreatedByDisplayDirective]) module.directive("tgCreatedByDisplay", ["$tgTemplate", "$compile", CreatedByDisplayDirective])
############################################################################# #############################################################################
## Watchers directive ## Watchers directive
############################################################################# #############################################################################
WatchersDirective = ($rootscope, $confirm, $repo, $qqueue, $template) -> WatchersDirective = ($rootscope, $confirm, $repo, $qqueue, $template, $compile) ->
# You have to include a div with the tg-lb-watchers directive in the page # You have to include a div with the tg-lb-watchers directive in the page
# where use this directive # where use this directive
#
# TODO: i18n
template = $template.get("common/components/watchers.html", true) template = $template.get("common/components/watchers.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -200,7 +202,7 @@ WatchersDirective = ($rootscope, $confirm, $repo, $qqueue, $template) ->
isEditable: isEditable() isEditable: isEditable()
} }
html = template(ctx) html = $compile(template(ctx))($scope)
$el.html(html) $el.html(html)
if isEditable() and watchers.length == 0 if isEditable() and watchers.length == 0
@ -247,18 +249,17 @@ WatchersDirective = ($rootscope, $confirm, $repo, $qqueue, $template) ->
return {link:link, require:"ngModel"} return {link:link, require:"ngModel"}
module.directive("tgWatchers", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgQqueue", "$tgTemplate", WatchersDirective]) module.directive("tgWatchers", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgQqueue", "$tgTemplate", "$compile",
WatchersDirective])
############################################################################# #############################################################################
## Assigned to directive ## Assigned to directive
############################################################################# #############################################################################
AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template) -> AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template, $translate, $compile) ->
# You have to include a div with the tg-lb-assignedto directive in the page # You have to include a div with the tg-lb-assignedto directive in the page
# where use this directive # where use this directive
#
# TODO: i18n
template = $template.get("common/components/assigned-to.html", true) template = $template.get("common/components/assigned-to.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -291,7 +292,7 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template
assignedTo: assignedTo assignedTo: assignedTo
isEditable: isEditable() isEditable: isEditable()
} }
html = template(ctx) html = $compile(template(ctx))($scope)
$el.html(html) $el.html(html)
$el.on "click", ".user-assigned", (event) -> $el.on "click", ".user-assigned", (event) ->
@ -303,7 +304,7 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template
$el.on "click", ".icon-delete", (event) -> $el.on "click", ".icon-delete", (event) ->
event.preventDefault() event.preventDefault()
return if not isEditable() return if not isEditable()
title = "Are you sure you want to leave it unassigned?" # TODO: i18n title = $translate.instant("COMMON.ASSIGNED_TO.CONFIRM_UNASSIGNED")
$confirm.ask(title).then (finish) => $confirm.ask(title).then (finish) =>
finish() finish()
@ -326,7 +327,8 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template
require:"ngModel" require:"ngModel"
} }
module.directive("tgAssignedTo", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgLoading", "$tgQqueue", "$tgTemplate", AssignedToDirective]) module.directive("tgAssignedTo", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgLoading", "$tgQqueue", "$tgTemplate", "$translate", "$compile",
AssignedToDirective])
############################################################################# #############################################################################
@ -392,7 +394,7 @@ DeleteButtonDirective = ($log, $repo, $confirm, $location, $template) ->
return $log.error "DeleteButtonDirective requires on-delete-title set in scope." return $log.error "DeleteButtonDirective requires on-delete-title set in scope."
$el.on "click", ".button", (event) -> $el.on "click", ".button", (event) ->
title = $scope.$eval($attrs.onDeleteTitle) title = $attrs.onDeleteTitle
subtitle = $model.$modelValue.subject subtitle = $model.$modelValue.subject
$confirm.askOnDelete(title, subtitle).then (finish) => $confirm.askOnDelete(title, subtitle).then (finish) =>
@ -471,7 +473,6 @@ EditableSubjectDirective = ($rootscope, $repo, $confirm, $loading, $qqueue, $tem
$el.find('div.edit-subject').hide() $el.find('div.edit-subject').hide()
$el.find('div.view-subject span.edit').hide() $el.find('div.view-subject span.edit').hide()
$scope.$watch $attrs.ngModel, (value) -> $scope.$watch $attrs.ngModel, (value) ->
return if not value return if not value
$scope.item = value $scope.item = value
@ -490,7 +491,8 @@ EditableSubjectDirective = ($rootscope, $repo, $confirm, $loading, $qqueue, $tem
template: template template: template
} }
module.directive("tgEditableSubject", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", EditableSubjectDirective]) module.directive("tgEditableSubject", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue",
"$tgTemplate", EditableSubjectDirective])
############################################################################# #############################################################################
@ -498,9 +500,9 @@ module.directive("tgEditableSubject", ["$rootScope", "$tgRepo", "$tgConfirm", "$
############################################################################# #############################################################################
EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, $selectedText, $qqueue, $template) -> EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, $selectedText, $qqueue, $template) ->
template = $template.get("common/components/editable-description.html") # TODO: i18n template = $template.get("common/components/editable-description.html")
noDescriptionMegEditMode = $template.get("common/components/editable-description-msg-edit-mode.html") # TODO: i18n noDescriptionMegEditMode = $template.get("common/components/editable-description-msg-edit-mode.html")
noDescriptionMegReadMode = $template.get("common/components/editable-description-msg-read-mode.html") # TODO: i18n noDescriptionMegReadMode = $template.get("common/components/editable-description-msg-read-mode.html")
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
$el.find('.edit-description').hide() $el.find('.edit-description').hide()
@ -569,8 +571,8 @@ EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading,
template: template template: template
} }
module.directive("tgEditableDescription", ["$rootScope", "$tgRepo", "$tgConfirm", module.directive("tgEditableDescription", ["$rootScope", "$tgRepo", "$tgConfirm", "$compile", "$tgLoading",
"$compile", "$tgLoading", "$selectedText", "$tgQqueue", "$tgTemplate", EditableDescriptionDirective]) "$selectedText", "$tgQqueue", "$tgTemplate", EditableDescriptionDirective])
############################################################################# #############################################################################
@ -580,14 +582,16 @@ module.directive("tgEditableDescription", ["$rootScope", "$tgRepo", "$tgConfirm"
## completely bindonce, they only serves for visualization of data. ## completely bindonce, they only serves for visualization of data.
############################################################################# #############################################################################
ListItemIssueStatusDirective = -> ListItemUsStatusDirective = ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
issue = $scope.$eval($attrs.tgListitemIssueStatus) us = $scope.$eval($attrs.tgListitemUsStatus)
bindOnce $scope, "issueStatusById", (issueStatusById) -> bindOnce $scope, "usStatusById", (usStatusById) ->
$el.html(issueStatusById[issue.status].name) $el.html(usStatusById[us.status].name)
return {link:link} return {link:link}
module.directive("tgListitemUsStatus", ListItemUsStatusDirective)
ListItemTaskStatusDirective = -> ListItemTaskStatusDirective = ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
@ -597,14 +601,7 @@ ListItemTaskStatusDirective = ->
return {link:link} return {link:link}
module.directive("tgListitemTaskStatus", ListItemTaskStatusDirective)
ListItemUsStatusDirective = ->
link = ($scope, $el, $attrs) ->
us = $scope.$eval($attrs.tgListitemUsStatus)
bindOnce $scope, "usStatusById", (usStatusById) ->
$el.html(usStatusById[us.status].name)
return {link:link}
ListItemAssignedtoDirective = ($template) -> ListItemAssignedtoDirective = ($template) ->
@ -626,6 +623,41 @@ ListItemAssignedtoDirective = ($template) ->
module.directive("tgListitemAssignedto", ["$tgTemplate", ListItemAssignedtoDirective]) module.directive("tgListitemAssignedto", ["$tgTemplate", ListItemAssignedtoDirective])
ListItemIssueStatusDirective = ->
link = ($scope, $el, $attrs) ->
issue = $scope.$eval($attrs.tgListitemIssueStatus)
bindOnce $scope, "issueStatusById", (issueStatusById) ->
$el.html(issueStatusById[issue.status].name)
return {link:link}
module.directive("tgListitemIssueStatus", ListItemIssueStatusDirective)
ListItemTypeDirective = ->
link = ($scope, $el, $attrs) ->
render = (issueTypeById, issue) ->
type = issueTypeById[issue.type]
domNode = $el.find(".level")
domNode.css("background-color", type.color)
domNode.attr("title", type.name)
bindOnce $scope, "issueTypeById", (issueTypeById) ->
issue = $scope.$eval($attrs.tgListitemType)
render(issueTypeById, issue)
$scope.$watch $attrs.tgListitemType, (issue) ->
render($scope.issueTypeById, issue)
return {
link: link
templateUrl: "common/components/level.html"
}
module.directive("tgListitemType", ListItemTypeDirective)
ListItemPriorityDirective = -> ListItemPriorityDirective = ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
render = (priorityById, issue) -> render = (priorityById, issue) ->
@ -648,6 +680,7 @@ ListItemPriorityDirective = ->
module.directive("tgListitemPriority", ListItemPriorityDirective) module.directive("tgListitemPriority", ListItemPriorityDirective)
ListItemSeverityDirective = -> ListItemSeverityDirective = ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
render = (severityById, issue) -> render = (severityById, issue) ->
@ -668,26 +701,7 @@ ListItemSeverityDirective = ->
templateUrl: "common/components/level.html" templateUrl: "common/components/level.html"
} }
module.directive("tgListitemSeverity", ListItemSeverityDirective)
ListItemTypeDirective = ->
link = ($scope, $el, $attrs) ->
render = (issueTypeById, issue) ->
type = issueTypeById[issue.type]
domNode = $el.find(".level")
domNode.css("background-color", type.color)
domNode.attr("title", type.name)
bindOnce $scope, "issueTypeById", (issueTypeById) ->
issue = $scope.$eval($attrs.tgListitemType)
render(issueTypeById, issue)
$scope.$watch $attrs.tgListitemType, (issue) ->
render($scope.issueTypeById, issue)
return {
link: link
templateUrl: "common/components/level.html"
}
############################################################################# #############################################################################
@ -715,35 +729,27 @@ TgProgressBarDirective = ($template) ->
module.directive("tgProgressBar", ["$tgTemplate", TgProgressBarDirective]) module.directive("tgProgressBar", ["$tgTemplate", TgProgressBarDirective])
############################################################################# #############################################################################
## Main title directive ## Main title directive
############################################################################# #############################################################################
TgMainTitleDirective = ($template) -> TgMainTitleDirective = ($translate) ->
template = $template.get("common/components/main-title.html", true)
render = (el, projectName, sectionName) ->
el.html(template({
projectName: projectName
sectionName: sectionName
}))
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
element = angular.element($el) $attrs.$observe "i18nSectionName", (i18nSectionName) ->
$scope.$watch "project", (project) -> trans = $translate(i18nSectionName)
render($el, project.name, $scope.sectionName) if project trans.then (sectionName) -> $scope.sectionName = sectionName
trans.catch (sectionName) -> $scope.sectionName = sectionName
$scope.$on "project:loaded", (ctx, project) =>
render($el, project.name, $scope.sectionName)
$scope.$on "$destroy", -> $scope.$on "$destroy", ->
$el.off() $el.off()
return {link: link} return {
link: link
templateUrl: "common/components/main-title.html"
scope: {
projectName : "=projectName"
}
}
module.directive("tgMainTitle", ["$tgTemplate", TgMainTitleDirective]) module.directive("tgMainTitle", ["$translate", TgMainTitleDirective])
module.directive("tgListitemType", ListItemTypeDirective)
module.directive("tgListitemIssueStatus", ListItemIssueStatusDirective)
module.directive("tgListitemSeverity", ListItemSeverityDirective)
module.directive("tgListitemTaskStatus", ListItemTaskStatusDirective)
module.directive("tgListitemUsStatus", ListItemUsStatusDirective)

View File

@ -27,21 +27,21 @@ bindMethods = @.taiga.bindMethods
NOTIFICATION_MSG = { NOTIFICATION_MSG = {
"success": "success":
title: "Everything is ok" title: "NOTIFICATION.OK"
message: "Our Oompa Loompas saved all your changes!" message: "NOTIFICATION.SAVED"
"error": "error":
title: "Oops, something happened..." title: "NOTIFICATION.WARNING"
message: "Our Oompa Loompas are sad, your changes were not saved!" message: "NOTIFICATION.WARNING_TEXT"
"light-error": "light-error":
title: "Oops, something happened..." title: "NOTIFICATION.WARNING"
message: "Our Oompa Loompas are sad, your changes were not saved!" message: "NOTIFICATION.WARNING_TEXT"
} }
class ConfirmService extends taiga.Service class ConfirmService extends taiga.Service
@.$inject = ["$q", "lightboxService", "$tgLoading"] @.$inject = ["$q", "lightboxService", "$tgLoading", "$translate"]
constructor: (@q, @lightboxService, @loading) -> constructor: (@q, @lightboxService, @loading, @translate) ->
bindMethods(@) bindMethods(@)
hide: (el)-> hide: (el)->
@ -51,6 +51,8 @@ class ConfirmService extends taiga.Service
el.off(".confirm-dialog") el.off(".confirm-dialog")
ask: (title, subtitle, message, lightboxSelector=".lightbox-generic-ask") -> ask: (title, subtitle, message, lightboxSelector=".lightbox-generic-ask") ->
defered = @q.defer()
el = angular.element(lightboxSelector) el = angular.element(lightboxSelector)
# Render content # Render content
@ -58,8 +60,6 @@ class ConfirmService extends taiga.Service
el.find("span.subtitle").html(subtitle) el.find("span.subtitle").html(subtitle)
el.find("span.message").html(message) el.find("span.message").html(message)
defered = @q.defer()
# Assign event handlers # Assign event handlers
el.on "click.confirm-dialog", "a.button-green", debounce 2000, (event) => el.on "click.confirm-dialog", "a.button-green", debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -80,9 +80,11 @@ class ConfirmService extends taiga.Service
return defered.promise return defered.promise
askOnDelete: (title, message) -> askOnDelete: (title, message) ->
return @.ask(title, "Are you sure you want to delete?", message) #TODO: i18n return @.ask(title, @translate.instant("NOTIFICATION.ASK_DELETE"), message)
askChoice: (title, subtitle, choices, replacement, warning, lightboxSelector=".lightbox-ask-choice") -> askChoice: (title, subtitle, choices, replacement, warning, lightboxSelector=".lightbox-ask-choice") ->
defered = @q.defer()
el = angular.element(lightboxSelector) el = angular.element(lightboxSelector)
# Render content # Render content
@ -103,7 +105,6 @@ class ConfirmService extends taiga.Service
choicesField.html('') choicesField.html('')
_.each choices, (value, key) -> _.each choices, (value, key) ->
choicesField.append(angular.element("<option value='#{key}'>#{value}</option>")) choicesField.append(angular.element("<option value='#{key}'>#{value}</option>"))
defered = @q.defer()
# Assign event handlers # Assign event handlers
el.on "click.confirm-dialog", "a.button-green", debounce 2000, (event) => el.on "click.confirm-dialog", "a.button-green", debounce 2000, (event) =>
@ -127,11 +128,12 @@ class ConfirmService extends taiga.Service
return defered.promise return defered.promise
error: (message) -> error: (message) ->
defered = @q.defer()
el = angular.element(".lightbox-generic-error") el = angular.element(".lightbox-generic-error")
# Render content # Render content
el.find("h2.title").html(message) el.find("h2.title").html(message)
defered = @q.defer()
# Assign event handlers # Assign event handlers
el.on "click.confirm-dialog", "a.button-green", (event) => el.on "click.confirm-dialog", "a.button-green", (event) =>
@ -149,12 +151,13 @@ class ConfirmService extends taiga.Service
return defered.promise return defered.promise
success: (title, message) -> success: (title, message) ->
defered = @q.defer()
el = angular.element(".lightbox-generic-success") el = angular.element(".lightbox-generic-success")
# Render content # Render content
el.find("h2.title").html(title) if title el.find("h2.title").html(title) if title
el.find("p.message").html(message) if message el.find("p.message").html(message) if message
defered = @q.defer()
# Assign event handlers # Assign event handlers
el.on "click.confirm-dialog", "a.button-green", (event) => el.on "click.confirm-dialog", "a.button-green", (event) =>
@ -208,12 +211,12 @@ class ConfirmService extends taiga.Service
if title if title
el.find("h4").html(title) el.find("h4").html(title)
else else
el.find("h4").html(NOTIFICATION_MSG[type].title) el.find("h4").html(@translate.instant(NOTIFICATION_MSG[type].title))
if message if message
el.find("p").html(message) el.find("p").html(message)
else else
el.find("p").html(NOTIFICATION_MSG[type].message) el.find("p").html(@translate.instant(NOTIFICATION_MSG[type].message))
body = angular.element("body") body = angular.element("body")
body.find(".notification-message .notification-light") body.find(".notification-message .notification-light")

View File

@ -121,7 +121,7 @@ CustomAttributesValuesDirective = ($templates, $storage) ->
module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", CustomAttributesValuesDirective]) module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", CustomAttributesValuesDirective])
CustomAttributeValueDirective = ($template, $selectedText) -> CustomAttributeValueDirective = ($template, $selectedText, $compile) ->
template = $template.get("custom-attributes/custom-attribute-value.html", true) template = $template.get("custom-attributes/custom-attribute-value.html", true)
templateEdit = $template.get("custom-attributes/custom-attribute-value-edit.html", true) templateEdit = $template.get("custom-attributes/custom-attribute-value-edit.html", true)
@ -139,8 +139,10 @@ CustomAttributeValueDirective = ($template, $selectedText) ->
if editable and (edit or not value) if editable and (edit or not value)
html = templateEdit(ctx) html = templateEdit(ctx)
html = $compile(html)($scope)
else else
html = template(ctx) html = template(ctx)
html = $compile(html)($scope)
$el.html(html) $el.html(html)
@ -195,4 +197,4 @@ CustomAttributeValueDirective = ($template, $selectedText) ->
restrict: "AE" restrict: "AE"
} }
module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", CustomAttributeValueDirective]) module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", "$compile", CustomAttributeValueDirective])

View File

@ -28,7 +28,7 @@ module = angular.module("taigaCommon")
## User story estimation directive (for Lightboxes) ## User story estimation directive (for Lightboxes)
############################################################################# #############################################################################
LbUsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $template) -> LbUsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $template, $compile) ->
# Display the points of a US and you can edit it. # Display the points of a US and you can edit it.
# #
# Example: # Example:
@ -40,7 +40,6 @@ LbUsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
$scope.$watch $attrs.ngModel, (us) -> $scope.$watch $attrs.ngModel, (us) ->
console.log "watch"
if us if us
estimationProcess = $tgEstimationsService.create($el, us, $scope.project) estimationProcess = $tgEstimationsService.create($el, us, $scope.project)
estimationProcess.onSelectedPointForRole = (roleId, pointId) -> estimationProcess.onSelectedPointForRole = (roleId, pointId) ->
@ -57,6 +56,7 @@ LbUsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $
mainTemplate = "common/estimation/us-estimation-points-per-role.html" mainTemplate = "common/estimation/us-estimation-points-per-role.html"
template = $template.get(mainTemplate, true) template = $template.get(mainTemplate, true)
html = template(ctx) html = template(ctx)
html = $compile(html)($scope)
@$el.html(html) @$el.html(html)
estimationProcess.render() estimationProcess.render()
@ -69,14 +69,14 @@ LbUsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $
require: "ngModel" require: "ngModel"
} }
module.directive("tgLbUsEstimation", ["$tgEstimationsService", "$rootScope", "$tgRepo", "$tgConfirm", "$tgTemplate", LbUsEstimationDirective]) module.directive("tgLbUsEstimation", ["$tgEstimationsService", "$rootScope", "$tgRepo", "$tgConfirm", "$tgTemplate", "$compile", LbUsEstimationDirective])
############################################################################# #############################################################################
## User story estimation directive ## User story estimation directive
############################################################################# #############################################################################
UsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $qqueue, $template) -> UsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $qqueue, $template, $compile) ->
# Display the points of a US and you can edit it. # Display the points of a US and you can edit it.
# #
# Example: # Example:
@ -103,6 +103,7 @@ UsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $qq
mainTemplate = "common/estimation/us-estimation-points-per-role.html" mainTemplate = "common/estimation/us-estimation-points-per-role.html"
template = $template.get(mainTemplate, true) template = $template.get(mainTemplate, true)
html = template(ctx) html = template(ctx)
html = $compile(html)($scope)
@$el.html(html) @$el.html(html)
estimationProcess.render() estimationProcess.render()
@ -116,7 +117,7 @@ UsEstimationDirective = ($tgEstimationsService, $rootScope, $repo, $confirm, $qq
require: "ngModel" require: "ngModel"
} }
module.directive("tgUsEstimation", ["$tgEstimationsService", "$rootScope", "$tgRepo", "$tgConfirm", "$tgQqueue", "$tgTemplate", module.directive("tgUsEstimation", ["$tgEstimationsService", "$rootScope", "$tgRepo", "$tgConfirm", "$tgQqueue", "$tgTemplate", "$compile"
UsEstimationDirective]) UsEstimationDirective])

View File

@ -33,15 +33,14 @@ defaultFilter = ->
module.filter("default", defaultFilter) module.filter("default", defaultFilter)
yesNoFilter = -> yesNoFilter = ($translate) ->
#TODO: i18n
return (value) -> return (value) ->
if value if value
return "Yes" return $translate.instant("COMMON.YES")
return "No" return $translate.instant("COMMON.NO")
module.filter("yesNo", yesNoFilter) module.filter("yesNo", ["$translate", yesNoFilter])
unslugify = -> unslugify = ->

View File

@ -68,7 +68,7 @@ class HistoryController extends taiga.Controller
return @rs.history.undeleteComment(type, objectId, activityId).then => @.loadHistory(type, objectId) return @rs.history.undeleteComment(type, objectId, activityId).then => @.loadHistory(type, objectId)
HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) -> HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $compile) ->
templateChangeDiff = $template.get("common/history/history-change-diff.html", true) templateChangeDiff = $template.get("common/history/history-change-diff.html", true)
templateChangePoints = $template.get("common/history/history-change-points.html", true) templateChangePoints = $template.get("common/history/history-change-points.html", true)
templateChangeGeneric = $template.get("common/history/history-change-generic.html", true) templateChangeGeneric = $template.get("common/history/history-change-generic.html", true)
@ -96,25 +96,26 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
# Helpers # Helpers
getHumanizedFieldName = (field) -> getHumanizedFieldName = (field) ->
humanizedFieldNames = { humanizedFieldNames = {}
# US
assigned_to: "assigned to"
is_closed: "is closed"
finish_date: "finish date"
client_requirement: "client requirement"
team_requirement: "team requirement"
# Task # US
milestone: "sprint" humanizedFieldNames.assigned_to = $translate.instant("COMMON.FIELDS.ASSIGNED_TO").toLowerCase()
user_story: "user story" humanizedFieldNames.is_closed = $translate.instant("IS_CLOSED").toLowerCase()
is_iocaine: "is iocaine" humanizedFieldNames.finish_date = $translate.instant("US.FIELDS.FINISH_DATE").toLowerCase()
humanizedFieldNames.client_repquirement = $translate.instant("US.FIELDS.CLIENT_REQUIREMENT").toLowerCase()
humanizedFieldNames.team_requirement = $translate.instant("US.FIELDS.TEAM_REQUIREMENT").toLowerCase()
# Attachment # Task
is_deprecated: "is deprecated" humanizedFieldNames.milestone = $translate.instant("TASK.FIELDS.MILESTONE").toLowerCase()
humanizedFieldNames.user_story = $translate.instant("TASK.FIELDS.USER_STORY").toLowerCase()
humanizedFieldNames.is_iocaine = $translate.instant("TASK.FIELDS.IS_IOCAINE").toLowerCase()
# Attachment
humanizedFieldNames.is_deprecated = $translate.instant("TASK.FIELDS.IS_IOCAINE").toLowerCase()
humanizedFieldNames.blocked_note = $translate.instant("TASK.FIELDS.IS_IOCAINE").toLowerCase()
humanizedFieldNames.is_blocked = $translate.instant("TASK.FIELDS.IS_BLOCKED").toLowerCase()
blocked_note: "blocked note"
is_blocked: "is blocked"
} # TODO i18n
return humanizedFieldNames[field] or field return humanizedFieldNames[field] or field
getUserFullName = (userId) -> getUserFullName = (userId) ->
@ -152,16 +153,14 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
attachments = _.map value, (changes, type) -> attachments = _.map value, (changes, type) ->
if type == "new" if type == "new"
return _.map changes, (change) -> return _.map changes, (change) ->
# TODO: i18n return templateChangeDiff({name: $translate.instant("ACTIVITY.NEW_ATTACHMENT"), diff: change.filename})
return templateChangeDiff({name: "new attachment", diff: change.filename})
else if type == "deleted" else if type == "deleted"
return _.map changes, (change) -> return _.map changes, (change) ->
# TODO: i18n return templateChangeDiff({name: $translate.instant("ACTIVITY.DELETED_ATTACHMENT"), diff: change.filename})
return templateChangeDiff({name: "deleted attachment", diff: change.filename})
else else
return _.map changes, (change) -> return _.map changes, (change) ->
# TODO: i18n name = $tranlsate.instant("ACTIVITY.UPDATED_ATTACHMENT", {filename: change.filename})
name = "updated attachment #{change.filename}"
diff = _.map change.changes, (values, name) -> diff = _.map change.changes, (values, name) ->
return { return {
name: getHumanizedFieldName(name) name: getHumanizedFieldName(name)
@ -177,16 +176,19 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
customAttributes = _.map value, (changes, type) -> customAttributes = _.map value, (changes, type) ->
if type == "new" if type == "new"
return _.map changes, (change) -> return _.map changes, (change) ->
return templateChangeGeneric({ html = templateChangeGeneric({
name: change.name, name: change.name,
from: formatChange(""), from: formatChange(""),
to: formatChange(change.value) to: formatChange(change.value)
}) })
html = $compile(html)($scope)
return html[0].outerHTML
else if type == "deleted" else if type == "deleted"
return _.map changes, (change) -> return _.map changes, (change) ->
# TODO: i18n
return templateChangeDiff({ return templateChangeDiff({
name: "deleted custom attribute", name: $translate.instant("ACTIVITY.DELETED_CUSTOM_ATTRIBUTE")
diff: change.name diff: change.name
}) })
else else
@ -207,7 +209,11 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
else if field == "blocked_note" else if field == "blocked_note"
return templateChangeDiff({name: getHumanizedFieldName("blocked_note"), diff: value[1]}) return templateChangeDiff({name: getHumanizedFieldName("blocked_note"), diff: value[1]})
else if field == "points" else if field == "points"
return templateChangePoints({points: value}) html = templateChangePoints({points: value})
html = $compile(html)($scope)
return html[0].outerHTML
else if field == "attachments" else if field == "attachments"
return renderAttachmentEntry(value) return renderAttachmentEntry(value)
else if field == "custom_attributes" else if field == "custom_attributes"
@ -216,7 +222,11 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
name = getHumanizedFieldName(field) name = getHumanizedFieldName(field)
removed = _.difference(value[0], value[1]) removed = _.difference(value[0], value[1])
added = _.difference(value[1], value[0]) added = _.difference(value[1], value[0])
return templateChangeList({name:name, removed:removed, added: added}) html = templateChangeList({name:name, removed:removed, added: added})
html = $compile(html)($scope)
return html[0].outerHTML
else if field == "assigned_to" else if field == "assigned_to"
name = getHumanizedFieldName(field) name = getHumanizedFieldName(field)
from = formatChange(value[0] or "Unassigned") from = formatChange(value[0] or "Unassigned")
@ -233,13 +243,12 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
renderChangesHelperText = (change) -> renderChangesHelperText = (change) ->
size = countChanges(change) size = countChanges(change)
if size == 1
return "Made #{size} change" # TODO: i18n return $translate.instant("ACTIVITY.SIZE_CHANGE", {size: size})
return "Made #{size} changes" # TODO: i18n
renderComment = (comment) -> renderComment = (comment) ->
if (comment.delete_comment_date or comment.delete_comment_user?.name) if (comment.delete_comment_date or comment.delete_comment_user?.name)
return templateDeletedComment({ html = templateDeletedComment({
deleteCommentDate: moment(comment.delete_comment_date).format("DD MMM YYYY HH:mm") if comment.delete_comment_date deleteCommentDate: moment(comment.delete_comment_date).format("DD MMM YYYY HH:mm") if comment.delete_comment_date
deleteCommentUser: comment.delete_comment_user.name deleteCommentUser: comment.delete_comment_user.name
deleteComment: comment.comment_html deleteComment: comment.comment_html
@ -247,7 +256,11 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
canRestoreComment: comment.delete_comment_user.pk == $scope.user.id or $scope.project.my_permissions.indexOf("modify_project") > -1 canRestoreComment: comment.delete_comment_user.pk == $scope.user.id or $scope.project.my_permissions.indexOf("modify_project") > -1
}) })
return templateActivity({ html = $compile(html)($scope)
return html[0].outerHTML
html = templateActivity({
avatar: getUserAvatar(comment.user.pk) avatar: getUserAvatar(comment.user.pk)
userFullName: comment.user.name userFullName: comment.user.name
creationDate: moment(comment.created_at).format("DD MMM YYYY HH:mm") creationDate: moment(comment.created_at).format("DD MMM YYYY HH:mm")
@ -261,6 +274,10 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
canDeleteComment: comment.user.pk == $scope.user?.id or $scope.project.my_permissions.indexOf("modify_project") > -1 canDeleteComment: comment.user.pk == $scope.user?.id or $scope.project.my_permissions.indexOf("modify_project") > -1
}) })
html = $compile(html)($scope)
return html[0].outerHTML
renderChange = (change) -> renderChange = (change) ->
return templateActivity({ return templateActivity({
avatar: getUserAvatar(change.user.pk) avatar: getUserAvatar(change.user.pk)
@ -281,7 +298,11 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
else else
showMore = totalEntries - entries.length showMore = totalEntries - entries.length
return templateBaseEntries({entries: entries, showMore:showMore}) html = templateBaseEntries({entries: entries, showMore:showMore})
html = $compile(html)($scope)
return html
# Render into DOM (operations with dom mutability) # Render into DOM (operations with dom mutability)
@ -394,7 +415,9 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
$el.off() $el.off()
templateFn = ($el, $attrs) -> templateFn = ($el, $attrs) ->
return templateBase({ngmodel: $attrs.ngModel, type: $attrs.type, mode: $attrs.mode}) html = templateBase({ngmodel: $attrs.ngModel, type: $attrs.type, mode: $attrs.mode})
return html
return { return {
controller: HistoryController controller: HistoryController
@ -405,4 +428,4 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm) ->
} }
module.directive("tgHistory", ["$log", "$tgLoading", "$tgQqueue", "$tgTemplate", "$tgConfirm", HistoryDirective]) module.directive("tgHistory", ["$log", "$tgLoading", "$tgQqueue", "$tgTemplate", "$tgConfirm", "$translate", "$compile", HistoryDirective])

View File

@ -22,7 +22,7 @@
module = angular.module("taigaCommon") module = angular.module("taigaCommon")
ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls) -> ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$el.on "click", ".import-project-button", (event) -> $el.on "click", ".import-project-button", (event) ->
event.preventDefault() event.preventDefault()
@ -39,29 +39,25 @@ ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls) ->
onSuccess = (result) -> onSuccess = (result) ->
loader.stop() loader.stop()
if result.status == 202 # Async mode if result.status == 202 # Async mode
title = "Our Oompa Loompas are importing your project" # TODO: i18n title = $translate.instant("PROJECT.IMPORT.ASYNC_IN_PROGRESS_TITLE")
message = "This process could take a few minutes <br/> We will send you message = $translate.instant("PROJECT.IMPORT.ASYNC_IN_PROGRESS_MESSAGE")
an email when ready" # TODO: i18n
$confirm.success(title, message) $confirm.success(title, message)
else # result.status == 201 # Sync mode else # result.status == 201 # Sync mode
ctx = {project: result.data.slug} ctx = {project: result.data.slug}
$location.path($navUrls.resolve("project-admin-project-profile-details", ctx)) $location.path($navUrls.resolve("project-admin-project-profile-details", ctx))
$confirm.notify("success", "Your project has been imported successfuly.") # TODO: i18n msg = $translate.instant("PROJECT.IMPORT.SYNC_SUCCESS")
$confirm.notify("success", msg)
onError = (result) -> onError = (result) ->
loader.stop() loader.stop()
console.log "Error", result console.log "Error", result
errorMsg = "Our oompa loompas have some problems importing your dump data. errorMsg = $translate.instant("PROJECT.IMPORT.ERROR")
Please try again. " # TODO: i18n
if result.status == 429 # TOO MANY REQUESTS if result.status == 429 # TOO MANY REQUESTS
errorMsg = "Sorry, our oompa loompas are very busy right now. errorMsg = $translate.instant("PROJECT.IMPORT.ERROR_TOO_MANY_REQUEST")
Please try again in a few minutes. " # TODO: i18n
else if result.data?._error_message else if result.data?._error_message
errorMsg = "Our oompa loompas have some problems importing your dump data: errorMsg = $translate.instant("PROJECT.IMPORT.ERROR_MESSAGE", {error_message: result.data._error_message})
#{result.data._error_message}" # TODO: i18n
$confirm.notify("error", errorMsg) $confirm.notify("error", errorMsg)
loader.start() loader.start()
@ -69,5 +65,5 @@ ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls) ->
return {link: link} return {link: link}
module.directive("tgImportProjectButton", ["$tgResources", "$tgConfirm", "$location", "$tgNavUrls", module.directive("tgImportProjectButton", ["$tgResources", "$tgConfirm", "$location", "$tgNavUrls", "$translate",
ImportProjectButtonDirective]) ImportProjectButtonDirective])

View File

@ -146,9 +146,10 @@ module.directive("lightbox", ["lightboxService", LightboxDirective])
# Issue/Userstory blocking message lightbox directive. # Issue/Userstory blocking message lightbox directive.
BlockLightboxDirective = ($rootscope, $tgrepo, $confirm, lightboxService, $loading, $qqueue) -> BlockLightboxDirective = ($rootscope, $tgrepo, $confirm, lightboxService, $loading, $qqueue, $translate) ->
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
$el.find("h2.title").text($attrs.title) $translate($attrs.title).then (title) ->
$el.find("h2.title").text(title)
unblock = $qqueue.bindAdd (item, finishCallback) => unblock = $qqueue.bindAdd (item, finishCallback) =>
promise = $tgrepo.save(item) promise = $tgrepo.save(item)
@ -216,14 +217,14 @@ BlockLightboxDirective = ($rootscope, $tgrepo, $confirm, lightboxService, $loadi
require: "ngModel" require: "ngModel"
} }
module.directive("tgLbBlock", ["$rootScope", "$tgRepo", "$tgConfirm", "lightboxService", "$tgLoading", "$tgQqueue", BlockLightboxDirective]) module.directive("tgLbBlock", ["$rootScope", "$tgRepo", "$tgConfirm", "lightboxService", "$tgLoading", "$tgQqueue", "$translate", BlockLightboxDirective])
############################################################################# #############################################################################
## Generic Lightbox Blocking-Message Input Directive ## Generic Lightbox Blocking-Message Input Directive
############################################################################# #############################################################################
BlockingMessageInputDirective = ($log, $template) -> BlockingMessageInputDirective = ($log, $template, $compile) ->
template = $template.get("common/lightbox/lightbox-blocking-message-input.html", true) template = $template.get("common/lightbox/lightbox-blocking-message-input.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -246,14 +247,14 @@ BlockingMessageInputDirective = ($log, $template) ->
restrict: "EA" restrict: "EA"
} }
module.directive("tgBlockingMessageInput", ["$log", "$tgTemplate", BlockingMessageInputDirective]) module.directive("tgBlockingMessageInput", ["$log", "$tgTemplate", "$compile", BlockingMessageInputDirective])
############################################################################# #############################################################################
## Create/Edit Userstory Lightbox Directive ## Create/Edit Userstory Lightbox Directive
############################################################################# #############################################################################
CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService, $loading) -> CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService, $loading, $translate) ->
link = ($scope, $el, attrs) -> link = ($scope, $el, attrs) ->
$scope.isNew = true $scope.isNew = true
@ -270,8 +271,8 @@ CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService,
}) })
# Update texts for creation # Update texts for creation
$el.find(".button-green").html("Create") #TODO: i18n $el.find(".button-green").html($translate.instant("COMMON.CREATE"))
$el.find(".title").html("New user story ") #TODO: i18n $el.find(".title").html($translate.instant("LIGHTBOX.CREATE_EDIT_US.NEW_US"))
$el.find(".tag-input").val("") $el.find(".tag-input").val("")
$el.find(".blocked-note").addClass("hidden") $el.find(".blocked-note").addClass("hidden")
@ -286,8 +287,8 @@ CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService,
$scope.isNew = false $scope.isNew = false
# Update texts for edition # Update texts for edition
$el.find(".button-green").html("Save") #TODO: i18n $el.find(".button-green").html($translate.instant("COMMON.SAVE"))
$el.find(".title").html("Edit user story ") #TODO: i18n $el.find(".title").html($translate.instant("LIGHTBOX.CREATE_EDIT_US.EDIT_US"))
$el.find(".tag-input").val("") $el.find(".tag-input").val("")
# Update requirement info (team, client or blocked) # Update requirement info (team, client or blocked)
@ -365,6 +366,7 @@ module.directive("tgLbCreateEditUserstory", [
"$rootScope", "$rootScope",
"lightboxService", "lightboxService",
"$tgLoading", "$tgLoading",
"$translate",
CreateEditUserstoryDirective CreateEditUserstoryDirective
]) ])
@ -427,7 +429,7 @@ module.directive("tgLbCreateBulkUserstories", [
## AssignedTo Lightbox Directive ## AssignedTo Lightbox Directive
############################################################################# #############################################################################
AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationService, $template) -> AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationService, $template, $compile) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
selectedUser = null selectedUser = null
selectedItem = null selectedItem = null
@ -461,6 +463,9 @@ AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationServic
} }
html = usersTemplate(ctx) html = usersTemplate(ctx)
html = $compile(html)($scope)
$el.find("div.watchers").html(html) $el.find("div.watchers").html(html)
lightboxKeyboardNavigationService.init($el) lightboxKeyboardNavigationService.init($el)
@ -520,7 +525,7 @@ AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationServic
} }
module.directive("tgLbAssignedto", ["lightboxService", "lightboxKeyboardNavigationService", "$tgTemplate", AssignedToLightboxDirective]) module.directive("tgLbAssignedto", ["lightboxService", "lightboxKeyboardNavigationService", "$tgTemplate", "$compile", AssignedToLightboxDirective])
############################################################################# #############################################################################

View File

@ -55,7 +55,7 @@ module = angular.module("taigaCommon")
############################################################################# #############################################################################
## WYSIWYG markitup editor directive ## WYSIWYG markitup editor directive
############################################################################# #############################################################################
tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) -> tgMarkitupDirective = ($rootscope, $rs, $selectedText, $template, $compile) ->
previewTemplate = $template.get("common/wysiwyg/wysiwyg-markitup-preview.html", true) previewTemplate = $template.get("common/wysiwyg/wysiwyg-markitup-preview.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -76,7 +76,10 @@ tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) ->
markdownDomNode = element.parents(".markdown") markdownDomNode = element.parents(".markdown")
markItUpDomNode = element.parents(".markItUp") markItUpDomNode = element.parents(".markItUp")
$rs.mdrender.render($scope.projectId, $model.$modelValue).then (data) -> $rs.mdrender.render($scope.projectId, $model.$modelValue).then (data) ->
markdownDomNode.append(previewTemplate({data: data.data})) html = previewTemplate({data: data.data})
html = $compile(html)($scope)
markdownDomNode.append(html)
markItUpDomNode.hide() markItUpDomNode.hide()
markdown = element.closest(".markdown") markdown = element.closest(".markdown")
@ -178,42 +181,43 @@ tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) ->
setCaretPosition(data.textarea, markdownCaretPositon) if markdownCaretPositon setCaretPosition(data.textarea, markdownCaretPositon) if markdownCaretPositon
#I18N
markupSet: [ markupSet: [
{ {
name: $tr.t("markdown-editor.heading-1") name: "First Level Heading"
key: "1" key: "1"
placeHolder: $tr.t("markdown-editor.placeholder") placeHolder: "Your title here..."
closeWith: (markItUp) -> markdownTitle(markItUp, "=") closeWith: (markItUp) -> markdownTitle(markItUp, "=")
}, },
{ {
name: $tr.t("markdown-editor.heading-2") name: "Second Level Heading"
key: "2" key: "2"
placeHolder: $tr.t("markdown-editor.placeholder") placeHolder: "Your title here..."
closeWith: (markItUp) -> markdownTitle(markItUp, "-") closeWith: (markItUp) -> markdownTitle(markItUp, "-")
}, },
{ {
name: $tr.t("markdown-editor.heading-3") name: "Third Level Heading"
key: "3" key: "3"
openWith: "### " openWith: "### "
placeHolder: $tr.t("markdown-editor.placeholder") placeHolder: "Your title here..."
}, },
{ {
separator: "---------------" separator: "---------------"
}, },
{ {
name: $tr.t("markdown-editor.bold") name: "Bold"
key: "B" key: "B"
openWith: "**" openWith: "**"
closeWith: "**" closeWith: "**"
}, },
{ {
name: $tr.t("markdown-editor.italic") name: "Italic"
key: "I" key: "I"
openWith: "_" openWith: "_"
closeWith: "_" closeWith: "_"
}, },
{ {
name: $tr.t("markdown-editor.strike") name: "Strike"
key: "S" key: "S"
openWith: "~~" openWith: "~~"
closeWith: "~~" closeWith: "~~"
@ -222,29 +226,29 @@ tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) ->
separator: "---------------" separator: "---------------"
}, },
{ {
name: $tr.t("markdown-editor.bulleted-list") name: "Bulleted List"
openWith: "- " openWith: "- "
}, },
{ {
name: $tr.t("markdown-editor.numeric-list") name: "Numeric List"
openWith: (markItUp) -> markItUp.line+". " openWith: (markItUp) -> markItUp.line+". "
}, },
{ {
separator: "---------------" separator: "---------------"
}, },
{ {
name: $tr.t("markdown-editor.picture") name: "Picture"
key: "P" key: "P"
replaceWith: '![[![Alternative text]!]](<<<[![Url:!:http://]!]>>> "[![Title]!]")' replaceWith: '![[![Alternative text]!]](<<<[![Url:!:http://]!]>>> "[![Title]!]")'
beforeInsert:(markItUp) -> prepareUrlFormatting(markItUp) beforeInsert:(markItUp) -> prepareUrlFormatting(markItUp)
afterInsert:(markItUp) -> urlFormatting(markItUp) afterInsert:(markItUp) -> urlFormatting(markItUp)
}, },
{ {
name: $tr.t("markdown-editor.link") name: "Link"
key: "L" key: "L"
openWith: "[" openWith: "["
closeWith: '](<<<[![Url:!:http://]!]>>> "[![Title]!]")' closeWith: '](<<<[![Url:!:http://]!]>>> "[![Title]!]")'
placeHolder: $tr.t("markdown-editor.link-placeholder") placeHolder: "Your text to link here..."
beforeInsert:(markItUp) -> prepareUrlFormatting(markItUp) beforeInsert:(markItUp) -> prepareUrlFormatting(markItUp)
afterInsert:(markItUp) -> urlFormatting(markItUp) afterInsert:(markItUp) -> urlFormatting(markItUp)
}, },
@ -252,11 +256,11 @@ tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) ->
separator: "---------------" separator: "---------------"
}, },
{ {
name: $tr.t("markdown-editor.quotes") name: "Quotes"
openWith: "> " openWith: "> "
}, },
{ {
name: $tr.t("markdown-editor.code-block") name: "Code Block / Code"
openWith: "```\n" openWith: "```\n"
closeWith: "\n```" closeWith: "\n```"
}, },
@ -264,7 +268,7 @@ tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) ->
separator: "---------------" separator: "---------------"
}, },
{ {
name: $tr.t("markdown-editor.preview") name: "Preview"
call: preview call: preview
className: "preview-icon" className: "preview-icon"
}, },
@ -338,4 +342,4 @@ tgMarkitupDirective = ($rootscope, $rs, $tr, $selectedText, $template) ->
return {link:link, require:"ngModel"} return {link:link, require:"ngModel"}
module.directive("tgMarkitup", ["$rootScope", "$tgResources", "$tgI18n", "$selectedText", "$tgTemplate", tgMarkitupDirective]) module.directive("tgMarkitup", ["$rootScope", "$tgResources", "$selectedText", "$tgTemplate", tgMarkitupDirective])

View File

@ -47,13 +47,14 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$appTitle", "$appTitle",
"$tgAnalytics", "$tgAnalytics",
"$tgNavUrls", "$tgNavUrls",
"$translate",
"tgLoader" "tgLoader"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location,
@log, @appTitle, @analytics, @navUrls, tgLoader) -> @log, @appTitle, @analytics, @navUrls, @translate, tgLoader) ->
@scope.issueRef = @params.issueref @scope.issueRef = @params.issueref
@scope.sectionName = "Issue Details" @scope.sectionName = @translate.instant("ISSUES.SECTION_NAME")
@.initializeEventHandlers() @.initializeEventHandlers()
promise = @.loadInitialData() promise = @.loadInitialData()
@ -145,7 +146,7 @@ module.controller("IssueDetailController", IssueDetailController)
## Issue status display directive ## Issue status display directive
############################################################################# #############################################################################
IssueStatusDisplayDirective = ($template)-> IssueStatusDisplayDirective = ($template, $compile)->
# Display if a Issue is open or closed and its issueboard status. # Display if a Issue is open or closed and its issueboard status.
# #
# Example: # Example:
@ -162,6 +163,9 @@ IssueStatusDisplayDirective = ($template)->
html = template({ html = template({
status: $scope.statusById[issue.status] status: $scope.statusById[issue.status]
}) })
html = $compile(html)($scope)
$el.html(html) $el.html(html)
$scope.$watch $attrs.ngModel, (issue) -> $scope.$watch $attrs.ngModel, (issue) ->
@ -176,14 +180,14 @@ IssueStatusDisplayDirective = ($template)->
require: "ngModel" require: "ngModel"
} }
module.directive("tgIssueStatusDisplay", ["$tgTemplate", IssueStatusDisplayDirective]) module.directive("tgIssueStatusDisplay", ["$tgTemplate", "$compile", IssueStatusDisplayDirective])
############################################################################# #############################################################################
## Issue status button directive ## Issue status button directive
############################################################################# #############################################################################
IssueStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template) -> IssueStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template, $compile) ->
# Display the status of Issue and you can edit it. # Display the status of Issue and you can edit it.
# #
# Example: # Example:
@ -208,6 +212,9 @@ IssueStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $t
statuses: $scope.statusList statuses: $scope.statusList
editable: isEditable() editable: isEditable()
}) })
html = $compile(html)($scope)
$el.html(html) $el.html(html)
save = $qqueue.bindAdd (statusId) => save = $qqueue.bindAdd (statusId) =>
@ -259,13 +266,13 @@ IssueStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $t
require: "ngModel" require: "ngModel"
} }
module.directive("tgIssueStatusButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", IssueStatusButtonDirective]) module.directive("tgIssueStatusButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", "$compile", IssueStatusButtonDirective])
############################################################################# #############################################################################
## Issue type button directive ## Issue type button directive
############################################################################# #############################################################################
IssueTypeButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template) -> IssueTypeButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template, $compile) ->
# Display the type of Issue and you can edit it. # Display the type of Issue and you can edit it.
# #
# Example: # Example:
@ -285,6 +292,8 @@ IssueTypeButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $tem
render = (issue) => render = (issue) =>
type = $scope.typeById[issue.type] type = $scope.typeById[issue.type]
html = $compile(html)($scope)
html = template({ html = template({
type: type type: type
typees: $scope.typeList typees: $scope.typeList
@ -340,14 +349,14 @@ IssueTypeButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $tem
require: "ngModel" require: "ngModel"
} }
module.directive("tgIssueTypeButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", IssueTypeButtonDirective]) module.directive("tgIssueTypeButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", "$compile", IssueTypeButtonDirective])
############################################################################# #############################################################################
## Issue severity button directive ## Issue severity button directive
############################################################################# #############################################################################
IssueSeverityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template) -> IssueSeverityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template, $compile) ->
# Display the severity of Issue and you can edit it. # Display the severity of Issue and you can edit it.
# #
# Example: # Example:
@ -372,6 +381,9 @@ IssueSeverityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue,
severityes: $scope.severityList severityes: $scope.severityList
editable: isEditable() editable: isEditable()
}) })
html = $compile(html)($scope)
$el.html(html) $el.html(html)
save = $qqueue.bindAdd (severity) => save = $qqueue.bindAdd (severity) =>
@ -424,14 +436,14 @@ IssueSeverityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue,
require: "ngModel" require: "ngModel"
} }
module.directive("tgIssueSeverityButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", IssueSeverityButtonDirective]) module.directive("tgIssueSeverityButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", "$compile", IssueSeverityButtonDirective])
############################################################################# #############################################################################
## Issue priority button directive ## Issue priority button directive
############################################################################# #############################################################################
IssuePriorityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template) -> IssuePriorityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $template, $compile) ->
# Display the priority of Issue and you can edit it. # Display the priority of Issue and you can edit it.
# #
# Example: # Example:
@ -456,6 +468,9 @@ IssuePriorityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue,
priorityes: $scope.priorityList priorityes: $scope.priorityList
editable: isEditable() editable: isEditable()
}) })
html = $compile(html)($scope)
$el.html(html) $el.html(html)
save = $qqueue.bindAdd (priority) => save = $qqueue.bindAdd (priority) =>
@ -508,14 +523,14 @@ IssuePriorityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue,
require: "ngModel" require: "ngModel"
} }
module.directive("tgIssuePriorityButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", IssuePriorityButtonDirective]) module.directive("tgIssuePriorityButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", "$compile", IssuePriorityButtonDirective])
############################################################################# #############################################################################
## Promote Issue to US button directive ## Promote Issue to US button directive
############################################################################# #############################################################################
PromoteIssueToUsButtonDirective = ($rootScope, $repo, $confirm, $qqueue) -> PromoteIssueToUsButtonDirective = ($rootScope, $repo, $confirm, $qqueue, $translate) ->
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
save = $qqueue.bindAdd (issue, finish) => save = $qqueue.bindAdd (issue, finish) =>
@ -545,8 +560,8 @@ PromoteIssueToUsButtonDirective = ($rootScope, $repo, $confirm, $qqueue) ->
event.preventDefault() event.preventDefault()
issue = $model.$modelValue issue = $model.$modelValue
title = "Promote this issue to a new user story" # TODO: i18n title = $translate.instant("ISSUES.CONFIRM_PROMOTE.TITLE")
message = "Are you sure you want to create a new US from this Issue?" # TODO: i18n message = $translate.instant("ISSUES.CONFIRM_PROMOTE.MESSAGE")
subtitle = issue.subject subtitle = issue.subject
$confirm.ask(title, subtitle, message).then (finish) => $confirm.ask(title, subtitle, message).then (finish) =>
@ -563,5 +578,5 @@ PromoteIssueToUsButtonDirective = ($rootScope, $repo, $confirm, $qqueue) ->
link: link link: link
} }
module.directive("tgPromoteIssueToUsButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgQqueue", module.directive("tgPromoteIssueToUsButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgQqueue", "$translate"
PromoteIssueToUsButtonDirective]) PromoteIssueToUsButtonDirective])

View File

@ -310,7 +310,7 @@ module.controller("IssuesController", IssuesController)
## Issues Directive ## Issues Directive
############################################################################# #############################################################################
IssuesDirective = ($log, $location, $template) -> IssuesDirective = ($log, $location, $template, $compile) ->
## Issues Pagination ## Issues Pagination
template = $template.get("issue/issue-paginator.html", true) template = $template.get("issue/issue-paginator.html", true)
@ -360,7 +360,11 @@ IssuesDirective = ($log, $location, $template) ->
else else
pages.push({classes: "page", num: i, type: "page"}) pages.push({classes: "page", num: i, type: "page"})
$pagEl.html(template(options))
html = template(options)
html = $compile(html)($scope)
$pagEl.html(html)
$scope.$watch "issues", (value) -> $scope.$watch "issues", (value) ->
# Do nothing if value is not logical true # Do nothing if value is not logical true
@ -427,14 +431,14 @@ IssuesDirective = ($log, $location, $template) ->
return {link:link} return {link:link}
module.directive("tgIssues", ["$log", "$tgLocation", "$tgTemplate", IssuesDirective]) module.directive("tgIssues", ["$log", "$tgLocation", "$tgTemplate", "$compile", IssuesDirective])
############################################################################# #############################################################################
## Issues Filters Directive ## Issues Filters Directive
############################################################################# #############################################################################
IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template) -> IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $translate) ->
template = $template.get("issue/issues-filters.html", true) template = $template.get("issue/issues-filters.html", true)
templateSelected = $template.get("issue/issues-filters-selected.html", true) templateSelected = $template.get("issue/issues-filters-selected.html", true)
@ -590,8 +594,8 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template) -
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget)
customFilterName = target.parent().data('id') customFilterName = target.parent().data('id')
title = "Delete custom filter" # TODO: i18n title = $translate.instant("ISSUES.FILTERS.CONFIRM_DELETE.TITLE")
message = "the custom filter '#{customFilterName}'" # TODO: i18n message = $translate.instant("ISSUES.FILTERS.CONFIRM_DELETE.MESSAGE", {customFilterName: customFilterName})
$confirm.askOnDelete(title, message).then (finish) -> $confirm.askOnDelete(title, message).then (finish) ->
promise = $ctrl.deleteMyFilter(customFilterName) promise = $ctrl.deleteMyFilter(customFilterName)
@ -652,7 +656,7 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template) -
return {link:link} return {link:link}
module.directive("tgIssuesFilters", ["$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading", "$tgTemplate", module.directive("tgIssuesFilters", ["$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading", "$tgTemplate", "$translate",
IssuesFiltersDirective]) IssuesFiltersDirective])

View File

@ -307,10 +307,9 @@ module.directive("tgKanban", ["$tgRepo", "$rootScope", KanbanDirective])
## Kanban Archived Status Column Header Control ## Kanban Archived Status Column Header Control
############################################################################# #############################################################################
KanbanArchivedStatusHeaderDirective = ($rootscope) -> KanbanArchivedStatusHeaderDirective = ($rootscope, $translate) ->
#TODO: i18N showArchivedText = $translate.instant("KANBAN.ACTION_SHOW_ARCHIVED")
showArchivedText = "Show archived" hideArchivedText = $translate.instant("KANBAN.ACTION_HIDE_ARCHIVED")
hideArchivedText = "Hide archived"
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
status = $scope.$eval($attrs.tgKanbanArchivedStatusHeader) status = $scope.$eval($attrs.tgKanbanArchivedStatusHeader)
@ -338,19 +337,18 @@ KanbanArchivedStatusHeaderDirective = ($rootscope) ->
return {link:link} return {link:link}
module.directive("tgKanbanArchivedStatusHeader", [ "$rootScope", KanbanArchivedStatusHeaderDirective]) module.directive("tgKanbanArchivedStatusHeader", [ "$rootScope", "$translate", KanbanArchivedStatusHeaderDirective])
############################################################################# #############################################################################
## Kanban Archived Status Column Intro Directive ## Kanban Archived Status Column Intro Directive
############################################################################# #############################################################################
KanbanArchivedStatusIntroDirective = -> KanbanArchivedStatusIntroDirective = ($translate) ->
# TODO: i18n
hiddenUserStoriexText = "The user stories in this status are hidden by default"
userStories = [] userStories = []
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
hiddenUserStoriexText = $translate.instant("KANBAN.HIDDEN_USER_STORIES")
status = $scope.$eval($attrs.tgKanbanArchivedStatusIntro) status = $scope.$eval($attrs.tgKanbanArchivedStatusIntro)
$el.text(hiddenUserStoriexText) $el.text(hiddenUserStoriexText)
@ -397,7 +395,7 @@ KanbanArchivedStatusIntroDirective = ->
return {link:link} return {link:link}
module.directive("tgKanbanArchivedStatusIntro", KanbanArchivedStatusIntroDirective) module.directive("tgKanbanArchivedStatusIntro", ["$translate", KanbanArchivedStatusIntroDirective])
############################################################################# #############################################################################
@ -495,14 +493,14 @@ module.directive("tgKanbanWipLimit", KanbanWipLimitDirective)
## Kanban User Directive ## Kanban User Directive
############################################################################# #############################################################################
KanbanUserDirective = ($log) -> KanbanUserDirective = ($log, $compile) ->
template = _.template(""" template = _.template("""
<figure class="avatar"> <figure class="avatar">
<a href="#" title="Assign User Story" <% if (!clickable) {%>class="not-clickable"<% } %>> <a href="#" title="{{'US.ASSIGN' | translate}}" <% if (!clickable) {%>class="not-clickable"<% } %>>
<img src="<%- imgurl %>" alt="<%- name %>" class="avatar"> <img src="<%- imgurl %>" alt="<%- name %>" class="avatar">
</a> </a>
</figure> </figure>
""") # TODO: i18n """)
clickable = false clickable = false
@ -527,7 +525,7 @@ KanbanUserDirective = ($log) ->
else else
ctx = {name: user.full_name_display, imgurl: user.photo, clickable: clickable} ctx = {name: user.full_name_display, imgurl: user.photo, clickable: clickable}
html = template(ctx) html = $compile(template(ctx))($scope)
$el.html(html) $el.html(html)
username_label.text(ctx.name) username_label.text(ctx.name)
@ -556,4 +554,4 @@ KanbanUserDirective = ($log) ->
return {link: link, require:"ngModel"} return {link: link, require:"ngModel"}
module.directive("tgKanbanUserAvatar", ["$log", KanbanUserDirective]) module.directive("tgKanbanUserAvatar", ["$log", "$compile", KanbanUserDirective])

View File

@ -1,22 +0,0 @@
###
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
#
# 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: modules/locales.coffee
###
module = angular.module("taigaLocales", [])

View File

@ -26,7 +26,7 @@ debounce = @.taiga.debounce
module = angular.module("taigaProject") module = angular.module("taigaProject")
CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $projectUrl, $loading, lightboxService, $cacheFactory) -> CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $projectUrl, $loading, lightboxService, $cacheFactory, $translate) ->
link = ($scope, $el, attrs) -> link = ($scope, $el, attrs) ->
$scope.data = {} $scope.data = {}
$scope.templates = [] $scope.templates = []
@ -41,7 +41,9 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
$loading.finish(submitButton) $loading.finish(submitButton)
$rootscope.$broadcast("projects:reload") $rootscope.$broadcast("projects:reload")
$confirm.notify("success", "Success") #TODO: i18n
$confirm.notify("success", $translate.instant("COMMON.SAVE"))
$location.url($projectUrl.get(response)) $location.url($projectUrl.get(response))
lightboxService.close($el) lightboxService.close($el)
@ -126,7 +128,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
return {link:link} return {link:link}
module.directive("tgLbCreateProject", ["$rootScope", "$tgRepo", "$tgConfirm", "$location", "$tgNavUrls", module.directive("tgLbCreateProject", ["$rootScope", "$tgRepo", "$tgConfirm", "$location", "$tgNavUrls",
"$tgResources", "$projectUrl", "$tgLoading", "lightboxService", "$cacheFactory", CreateProject]) "$tgResources", "$projectUrl", "$tgLoading", "lightboxService", "$cacheFactory", "$translate", CreateProject])
############################################################################# #############################################################################

View File

@ -25,7 +25,7 @@ debounce = @.taiga.debounce
module = angular.module("taigaRelatedTasks", []) module = angular.module("taigaRelatedTasks", [])
RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $template) -> RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $template, $translate) ->
templateView = $template.get("task/related-task-row.html", true) templateView = $template.get("task/related-task-row.html", true)
templateEdit = $template.get("task/related-task-row-edit.html", true) templateEdit = $template.get("task/related-task-row-edit.html", true)
@ -79,9 +79,8 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem
$el.find('input').focus().select() $el.find('input').focus().select()
$el.on "click", ".delete-task", (event) -> $el.on "click", ".delete-task", (event) ->
#TODO: i18n title = $translate.instant("TASK.TITLE_DELETE_ACTION")
task = $model.$modelValue task = $model.$modelValue
title = "Delete Task"
message = task.subject message = task.subject
$confirm.askOnDelete(title, message).then (finish) -> $confirm.askOnDelete(title, message).then (finish) ->
@ -109,7 +108,7 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem
return {link:link, require:"ngModel"} return {link:link, require:"ngModel"}
module.directive("tgRelatedTaskRow", ["$tgRepo", "$compile", "$tgConfirm", "$rootScope", "$tgLoading", "$tgTemplate", RelatedTaskRowDirective]) module.directive("tgRelatedTaskRow", ["$tgRepo", "$compile", "$tgConfirm", "$rootScope", "$tgLoading", "$tgTemplate", "$translate", RelatedTaskRowDirective])
RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $analytics, $template) -> RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $analytics, $template) ->
template = $template.get("task/related-task-create-form.html", true) template = $template.get("task/related-task-create-form.html", true)

View File

@ -24,7 +24,7 @@ taiga = @.taiga
sizeFormat = @.taiga.sizeFormat sizeFormat = @.taiga.sizeFormat
resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $rootScope) -> resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $rootScope, $translate) ->
service = {} service = {}
service.get = (projectId) -> service.get = (projectId) ->
@ -99,7 +99,7 @@ resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $rootScope) ->
statusUpdater("in-progress", null, message, percent) statusUpdater("in-progress", null, message, percent)
uploadComplete = (evt) => uploadComplete = (evt) =>
statusUpdater("done", "Importing Project", "This process can take a while, please keep the window open.") # i18n statusUpdater("done", $translate.instant("PROJECT.IMPORT.TITLE"), $translate.instant("PROJECT.IMPORT.DESCRIPTION"))
uploadFailed = (evt) => uploadFailed = (evt) =>
statusUpdater("error") statusUpdater("error")
@ -141,5 +141,4 @@ resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $rootScope) ->
module = angular.module("taigaResources") module = angular.module("taigaResources")
module.factory("$tgProjectsResourcesProvider", ["$tgConfig", "$tgRepo", "$tgHttp", "$tgUrls", "$tgAuth", "$q", module.factory("$tgProjectsResourcesProvider", ["$tgConfig", "$tgRepo", "$tgHttp", "$tgUrls", "$tgAuth", "$q", "$translate", resourceProvider])
resourceProvider])

View File

@ -85,14 +85,20 @@ SprintGraphDirective = ->
tooltip: true tooltip: true
tooltipOpts: tooltipOpts:
content: (label, xval, yval, flotItem) -> content: (label, xval, yval, flotItem) ->
#TODO: i18n
formattedDate = moment(xval).format("DD MMM") formattedDate = moment(xval).format("DD MMM")
roundedValue = Math.round(yval) roundedValue = Math.round(yval)
if flotItem.seriesIndex == 1 if flotItem.seriesIndex == 1
return "Optimal pending points for day #{formattedDate} should be #{roundedValue}" return $translate.instant("TASKBOARD.CHARTS.OPTIMAL", {
formattedDate: formattedDate,
roundedValue: roundedValue
})
else else
return "Real pending points for day #{formattedDate} is #{roundedValue}" return $translate.instant("TASKBOARD.CHARTS.REAL", {
formattedDate: formattedDate,
roundedValue: roundedValue
})
element.empty() element.empty()
element.plot(data, options).data("plot") element.plot(data, options).data("plot")

View File

@ -23,7 +23,7 @@ taiga = @.taiga
bindOnce = @.taiga.bindOnce bindOnce = @.taiga.bindOnce
debounce = @.taiga.debounce debounce = @.taiga.debounce
CreateEditTaskDirective = ($repo, $model, $rs, $rootscope, $loading, lightboxService) -> CreateEditTaskDirective = ($repo, $model, $rs, $rootscope, $loading, lightboxService, $translate) ->
link = ($scope, $el, attrs) -> link = ($scope, $el, attrs) ->
$scope.isNew = true $scope.isNew = true
@ -40,10 +40,13 @@ CreateEditTaskDirective = ($repo, $model, $rs, $rootscope, $loading, lightboxSer
$scope.isNew = true $scope.isNew = true
# Update texts for creation # Update texts for creation
$el.find(".button-green").html("Create") #TODO: i18n create = $translate.instant("COMMON.CREATE")
$el.find(".title").html("New task ") #TODO: i18n $el.find(".button-green").html(create)
$el.find(".tag-input").val("")
newTask = $translate.instant("LIGHTBOX.CREATE_EDIT_TASK.TITLE")
$el.find(".title").html(newTask + " ")
$el.find(".tag-input").val("")
lightboxService.open($el) lightboxService.open($el)
$scope.$on "taskform:edit", (ctx, task) -> $scope.$on "taskform:edit", (ctx, task) ->
@ -51,10 +54,13 @@ CreateEditTaskDirective = ($repo, $model, $rs, $rootscope, $loading, lightboxSer
$scope.isNew = false $scope.isNew = false
# Update texts for edition # Update texts for edition
$el.find(".button-green").html("Save") #TODO: i18n save = $translate.instant("COMMON.SAVE")
$el.find(".title").html("Edit task ") #TODO: i18n edit = $translate.instant("LIGHTBOX.CREATE_EDIT_TASK.ACTION_EDIT")
$el.find(".tag-input").val("")
$el.find(".button-green").html(save)
$el.find(".title").html(edit + " ")
$el.find(".tag-input").val("")
lightboxService.open($el) lightboxService.open($el)
@ -142,6 +148,7 @@ module.directive("tgLbCreateEditTask", [
"$rootScope", "$rootScope",
"$tgLoading", "$tgLoading",
"lightboxService", "lightboxService",
"$translate"
CreateEditTaskDirective CreateEditTaskDirective
]) ])

View File

@ -259,7 +259,6 @@ TaskboardDirective = ($rootscope) ->
event.preventDefault() event.preventDefault()
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget)
target.toggleClass('active'); target.toggleClass('active');
#toggleText(target, ["Hide statistics", "Show statistics"]) # TODO: i18n
$rootscope.$broadcast("taskboard:graph:toggle-visibility") $rootscope.$broadcast("taskboard:graph:toggle-visibility")
tableBodyDom = $el.find(".taskboard-table-body") tableBodyDom = $el.find(".taskboard-table-body")

View File

@ -145,7 +145,7 @@ module.controller("TaskDetailController", TaskDetailController)
## Task status display directive ## Task status display directive
############################################################################# #############################################################################
TaskStatusDisplayDirective = ($template) -> TaskStatusDisplayDirective = ($template, $compile) ->
# Display if a Task is open or closed and its taskboard status. # Display if a Task is open or closed and its taskboard status.
# #
# Example: # Example:
@ -162,6 +162,9 @@ TaskStatusDisplayDirective = ($template) ->
html = template({ html = template({
status: $scope.statusById[task.status] status: $scope.statusById[task.status]
}) })
html = $compile(html)($scope)
$el.html(html) $el.html(html)
$scope.$watch $attrs.ngModel, (task) -> $scope.$watch $attrs.ngModel, (task) ->
@ -176,14 +179,14 @@ TaskStatusDisplayDirective = ($template) ->
require: "ngModel" require: "ngModel"
} }
module.directive("tgTaskStatusDisplay", ["$tgTemplate", TaskStatusDisplayDirective]) module.directive("tgTaskStatusDisplay", ["$tgTemplate", "$compile", TaskStatusDisplayDirective])
############################################################################# #############################################################################
## Task status button directive ## Task status button directive
############################################################################# #############################################################################
TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue) -> TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $translate) ->
# Display the status of Task and you can edit it. # Display the status of Task and you can edit it.
# #
# Example: # Example:
@ -199,7 +202,7 @@ TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue) ->
<span class="level" style="background-color:<%- status.color %>"></span> <span class="level" style="background-color:<%- status.color %>"></span>
<span class="status-status"><%- status.name %></span> <span class="status-status"><%- status.name %></span>
<% if(editable){ %><span class="icon icon-arrow-bottom"></span><% }%> <% if(editable){ %><span class="icon icon-arrow-bottom"></span><% }%>
<span class="level-name">status</span> <span class="level-name" translate="COMMON.FIELDS.STATUS"></span>
<ul class="popover pop-status"> <ul class="popover pop-status">
<% _.each(statuses, function(st) { %> <% _.each(statuses, function(st) { %>
@ -208,7 +211,7 @@ TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue) ->
<% }); %> <% }); %>
</ul> </ul>
</div> </div>
""") #TODO: i18n """)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
isEditable = -> isEditable = ->
@ -217,11 +220,12 @@ TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue) ->
render = (task) => render = (task) =>
status = $scope.statusById[task.status] status = $scope.statusById[task.status]
html = template({ html = $compile(template({
status: status status: status
statuses: $scope.statusList statuses: $scope.statusList
editable: isEditable() editable: isEditable()
}) }))($scope)
$el.html(html) $el.html(html)
save = $qqueue.bindAdd (status) => save = $qqueue.bindAdd (status) =>
@ -274,7 +278,7 @@ TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue) ->
require: "ngModel" require: "ngModel"
} }
module.directive("tgTaskStatusButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", module.directive("tgTaskStatusButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$translate",
TaskStatusButtonDirective]) TaskStatusButtonDirective])

View File

@ -41,18 +41,19 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgNavUrls", "$tgNavUrls",
"$appTitle", "$appTitle",
"$tgAuth", "$tgAuth",
"tgLoader" "tgLoader",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appTitle, @auth, tgLoader) -> constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appTitle, @auth, tgLoader, @translate) ->
@scope.sectionName = "Team" @scope.sectionName = "TEAM.SECTION_NAME"
promise = @.loadInitialData() promise = @.loadInitialData()
# On Success # On Success
promise.then => promise.then =>
#TODO: i18n text = @translate.instant("TEAM.APP_TITLE", {"projectName": @scope.project.name})
@appTitle.set("Team - " + @scope.project.name) @appTitle.set(text)
# On Error # On Error
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
@ -211,11 +212,13 @@ module.directive("tgTeamMembers", TeamMembersDirective)
## Leave project Directive ## Leave project Directive
############################################################################# #############################################################################
LeaveProjectDirective = ($repo, $confirm, $location, $rs, $navurls) -> LeaveProjectDirective = ($repo, $confirm, $location, $rs, $navurls, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$scope.leave = () -> $scope.leave = () ->
#TODO: i18n leave_project_text = $translate.instant("TEAM.ACTION_LEAVE_PROJECT")
$confirm.ask("Leave this project", "Are you sure you want to leave the project?").then (finish) => confirm_leave_project_text = $translate.instant("TEAM.CONFIRM_LEAVE_PROJECT")
$confirm.ask(leave_project_text, confirm_leave_project_text).then (finish) =>
promise = $rs.projects.leave($attrs.projectid) promise = $rs.projects.leave($attrs.projectid)
promise.then => promise.then =>

View File

@ -42,11 +42,12 @@ class UserChangePasswordController extends mixOf(taiga.Controller, taiga.PageMix
"$q", "$q",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$tgAuth" "$tgAuth",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @auth) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @auth, @translate) ->
@scope.sectionName = "Change Password" #i18n @scope.sectionName = @translate.instant("CHANGE_PASSWORD.SECTION_NAME")
@scope.project = {} @scope.project = {}
@scope.user = @auth.getUser() @scope.user = @auth.getUser()
@ -74,13 +75,13 @@ module.controller("UserChangePasswordController", UserChangePasswordController)
## User ChangePassword Directive ## User ChangePassword Directive
############################################################################# #############################################################################
UserChangePasswordDirective = ($rs, $confirm, $loading) -> UserChangePasswordDirective = ($rs, $confirm, $loading, $translate) ->
link = ($scope, $el, $attrs, ctrl) -> link = ($scope, $el, $attrs, ctrl) ->
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
if $scope.newPassword1 != $scope.newPassword2 if $scope.newPassword1 != $scope.newPassword2
$confirm.notify('error', "The passwords dosn't match") $confirm.notify('error', $translate.instant("CHANGE_PASSWORD.ERROR_PASSWORD_MATCH"))
return return
$loading.start(submitButton) $loading.start(submitButton)

View File

@ -41,17 +41,20 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin)
"$q", "$q",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$tgAuth" "$tgAuth",
"$translate"
] ]
constructor: (@scope, @rootscope, @config, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @auth) -> constructor: (@scope, @rootscope, @config, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @auth, @translate) ->
@scope.sectionName = "User Profile" #i18n @scope.sectionName = "USER_SETTINGS.MENU.SECTION_TITLE"
@scope.project = {} @scope.project = {}
@scope.user = @auth.getUser() @scope.user = @auth.getUser()
@scope.lang = @getLan()
maxFileSize = @config.get("maxUploadFileSize", null) maxFileSize = @config.get("maxUploadFileSize", null)
if maxFileSize if maxFileSize
@scope.maxFileSizeMsg = "[Max, size: #{sizeFormat(maxFileSize)}" # TODO: i18n @scope.maxFileSizeMsg = @translate.instant("USER_SETTINGS.AVATAR_MAX_SIZE", {"maxFileSize": sizeFormat(maxFileSize)})
promise = @.loadInitialData() promise = @.loadInitialData()
@ -73,6 +76,10 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin)
openDeleteLightbox: -> openDeleteLightbox: ->
@rootscope.$broadcast("deletelightbox:new", @scope.user) @rootscope.$broadcast("deletelightbox:new", @scope.user)
getLan: ->
return @scope.user.lang ||
@translate.preferredLanguage()
module.controller("UserSettingsController", UserSettingsController) module.controller("UserSettingsController", UserSettingsController)
@ -80,7 +87,7 @@ module.controller("UserSettingsController", UserSettingsController)
## User Profile Directive ## User Profile Directive
############################################################################# #############################################################################
UserProfileDirective = ($confirm, $auth, $repo) -> UserProfileDirective = ($confirm, $auth, $repo, $translate) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -90,13 +97,15 @@ UserProfileDirective = ($confirm, $auth, $repo) ->
changeEmail = $scope.user.isAttributeModified("email") changeEmail = $scope.user.isAttributeModified("email")
$scope.user.lang = $scope.lang
$translate.use($scope.user.lang)
onSuccess = (data) => onSuccess = (data) =>
$auth.setUser(data) $auth.setUser(data)
if changeEmail if changeEmail
$confirm.success("<strong>Check your inbox!</strong><br /> text = $translate.instant("USER_PROFILE.CHANGE_EMAIL_SUCCESS")
We have sent a mail to your account<br /> $confirm.success(text)
with the instructions to set your new address") #TODO: i18n
else else
$confirm.notify('success') $confirm.notify('success')
@ -113,7 +122,7 @@ UserProfileDirective = ($confirm, $auth, $repo) ->
return {link:link} return {link:link}
module.directive("tgUserProfile", ["$tgConfirm", "$tgAuth", "$tgRepo", UserProfileDirective]) module.directive("tgUserProfile", ["$tgConfirm", "$tgAuth", "$tgRepo", "$translate", UserProfileDirective])
############################################################################# #############################################################################

View File

@ -45,7 +45,7 @@ class UserNotificationsController extends mixOf(taiga.Controller, taiga.PageMixi
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @auth) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @auth) ->
@scope.sectionName = "Email Notifications" #i18n @scope.sectionName = "USER_SETTINGS.NOTIFICATIONS.SECTION_NAME"
@scope.project = {} @scope.project = {}
@scope.user = @auth.getUser() @scope.user = @auth.getUser()

View File

@ -154,7 +154,7 @@ module.controller("UserStoryDetailController", UserStoryDetailController)
## User story status display directive ## User story status display directive
############################################################################# #############################################################################
UsStatusDisplayDirective = ($template) -> UsStatusDisplayDirective = ($template, $compile) ->
# Display if a US is open or closed and its kanban status. # Display if a US is open or closed and its kanban status.
# #
# Example: # Example:
@ -164,14 +164,19 @@ UsStatusDisplayDirective = ($template) ->
# - US object (ng-model) # - US object (ng-model)
# - scope.statusById object # - scope.statusById object
template = $template.get("common/components/status-display.html", true) template = $template.get("common/components/status-display.html")
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
render = (us) -> render = (us) ->
html = template({ statusScope = $scope.$new()
_.assign(statusScope, {
is_closed: us.is_closed is_closed: us.is_closed
status: $scope.statusById[us.status] status: $scope.statusById[us.status]
}) })
html = $compile(html)(statusScope)
$el.html(html) $el.html(html)
$scope.$watch $attrs.ngModel, (us) -> $scope.$watch $attrs.ngModel, (us) ->
@ -186,14 +191,14 @@ UsStatusDisplayDirective = ($template) ->
require: "ngModel" require: "ngModel"
} }
module.directive("tgUsStatusDisplay", ["$tgTemplate", UsStatusDisplayDirective]) module.directive("tgUsStatusDisplay", ["$tgTemplate", "$compile", UsStatusDisplayDirective])
############################################################################# #############################################################################
## User story related tasts progress splay Directive ## User story related tasts progress splay Directive
############################################################################# #############################################################################
UsTasksProgressDisplayDirective = ($template) -> UsTasksProgressDisplayDirective = ($template, $compile) ->
# Display a progress bar with the stats of completed tasks. # Display a progress bar with the stats of completed tasks.
# #
# Example: # Example:
@ -203,8 +208,6 @@ UsTasksProgressDisplayDirective = ($template) ->
# - Task object list (ng-model) # - Task object list (ng-model)
# - scope.taskStatusById object # - scope.taskStatusById object
template = $template.get("us/us-task-progress.html", true)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
render = (tasks) -> render = (tasks) ->
totalTasks = tasks.length totalTasks = tasks.length
@ -212,12 +215,14 @@ UsTasksProgressDisplayDirective = ($template) ->
progress = if totalTasks > 0 then 100 * totalClosedTasks / totalTasks else 0 progress = if totalTasks > 0 then 100 * totalClosedTasks / totalTasks else 0
html = template({ _.assign($scope, {
totalTasks: totalTasks totalTasks: totalTasks
totalClosedTasks: totalClosedTasks totalClosedTasks: totalClosedTasks
progress: progress progress: progress,
style: {
width: progress + "%"
}
}) })
$el.html(html)
$scope.$watch $attrs.ngModel, (tasks) -> $scope.$watch $attrs.ngModel, (tasks) ->
render(tasks) if tasks? render(tasks) if tasks?
@ -226,12 +231,14 @@ UsTasksProgressDisplayDirective = ($template) ->
$el.off() $el.off()
return { return {
templateUrl: "us/us-task-progress.html"
link: link link: link
restrict: "EA" restrict: "EA"
require: "ngModel" require: "ngModel"
scope: true
} }
module.directive("tgUsTasksProgressDisplay", ["$tgTemplate", UsTasksProgressDisplayDirective]) module.directive("tgUsTasksProgressDisplay", ["$tgTemplate", "$compile", UsTasksProgressDisplayDirective])
############################################################################# #############################################################################
@ -326,7 +333,7 @@ module.directive("tgUsStatusButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$t
## User story team requirements button directive ## User story team requirements button directive
############################################################################# #############################################################################
UsTeamRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qqueue, $template) -> UsTeamRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qqueue, $template, $compile) ->
template = $template.get("us/us-team-requirement-button.html", true) template = $template.get("us/us-team-requirement-button.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -343,6 +350,8 @@ UsTeamRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qq
isRequired: us.team_requirement isRequired: us.team_requirement
} }
html = template(ctx) html = template(ctx)
html = $compile(html)($scope)
$el.html(html) $el.html(html)
save = $qqueue.bindAdd (team_requirement) => save = $qqueue.bindAdd (team_requirement) =>
@ -383,13 +392,13 @@ UsTeamRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qq
require: "ngModel" require: "ngModel"
} }
module.directive("tgUsTeamRequirementButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", UsTeamRequirementButtonDirective]) module.directive("tgUsTeamRequirementButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", "$compile", UsTeamRequirementButtonDirective])
############################################################################# #############################################################################
## User story client requirements button directive ## User story client requirements button directive
############################################################################# #############################################################################
UsClientRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qqueue, $template) -> UsClientRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qqueue, $template, $compile) ->
template = $template.get("us/us-client-requirement-button.html", true) template = $template.get("us/us-client-requirement-button.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -405,7 +414,7 @@ UsClientRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $
canEdit: canEdit() canEdit: canEdit()
isRequired: us.client_requirement isRequired: us.client_requirement
} }
html = template(ctx) html = $compile(template(ctx))($scope)
$el.html(html) $el.html(html)
save = $qqueue.bindAdd (client_requirement) => save = $qqueue.bindAdd (client_requirement) =>
@ -443,5 +452,5 @@ UsClientRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $
require: "ngModel" require: "ngModel"
} }
module.directive("tgUsClientRequirementButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", module.directive("tgUsClientRequirementButton", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQqueue", "$tgTemplate", "$compile",
UsClientRequirementButtonDirective]) UsClientRequirementButtonDirective])

View File

@ -49,11 +49,12 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$appTitle", "$appTitle",
"$tgNavUrls", "$tgNavUrls",
"$tgAnalytics", "$tgAnalytics",
"tgLoader" "tgLoader",
"$translate"
] ]
constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location, constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location,
@filter, @log, @appTitle, @navUrls, @analytics, tgLoader) -> @filter, @log, @appTitle, @navUrls, @analytics, tgLoader, @translate) ->
@scope.projectSlug = @params.pslug @scope.projectSlug = @params.pslug
@scope.wikiSlug = @params.slug @scope.wikiSlug = @params.slug
@scope.sectionName = "Wiki" @scope.sectionName = "Wiki"
@ -111,8 +112,7 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@q.all([@.loadWikiLinks(), @.loadWiki()]) @q.all([@.loadWikiLinks(), @.loadWiki()])
delete: -> delete: ->
# TODO: i18n title = @translate.instant("WIKI.DELETE_LIGHTBOX_TITLE")
title = "Delete Wiki Page"
message = unslugify(@scope.wiki.slug) message = unslugify(@scope.wiki.slug)
@confirm.askOnDelete(title, message).then (finish) => @confirm.askOnDelete(title, message).then (finish) =>
@ -135,7 +135,7 @@ module.controller("WikiDetailController", WikiDetailController)
## Wiki Summary Directive ## Wiki Summary Directive
############################################################################# #############################################################################
WikiSummaryDirective = ($log, $template) -> WikiSummaryDirective = ($log, $template, $compile) ->
template = $template.get("wiki/wiki-summary.html", true) template = $template.get("wiki/wiki-summary.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@ -156,6 +156,7 @@ WikiSummaryDirective = ($log, $template) ->
user: user user: user
} }
html = template(ctx) html = template(ctx)
html = $compile(html)($scope)
$el.html(html) $el.html(html)
$scope.$watch $attrs.ngModel, (wikiPage) -> $scope.$watch $attrs.ngModel, (wikiPage) ->
@ -171,7 +172,7 @@ WikiSummaryDirective = ($log, $template) ->
require: "ngModel" require: "ngModel"
} }
module.directive("tgWikiSummary", ["$log", "$tgTemplate", WikiSummaryDirective]) module.directive("tgWikiSummary", ["$log", "$tgTemplate", "$compile", WikiSummaryDirective])
############################################################################# #############################################################################

View File

@ -34,7 +34,7 @@ module = angular.module("taigaWiki")
## Wiki Main Directive ## Wiki Main Directive
############################################################################# #############################################################################
WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $loading, $template) -> WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $loading, $template, $compile, $translate) ->
template = $template.get("wiki/wiki-nav.html", true) template = $template.get("wiki/wiki-nav.html", true)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$ctrl = $el.controller() $ctrl = $el.controller()
@ -53,6 +53,8 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l
deleteWikiLinkPermission: deleteWikiLinkPermission deleteWikiLinkPermission: deleteWikiLinkPermission
}) })
html = $compile(html)($scope)
$el.off() $el.off()
$el.html(html) $el.html(html)
@ -80,8 +82,7 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget)
linkId = target.parents('.wiki-link').data('id') linkId = target.parents('.wiki-link').data('id')
# TODO: i18n title = $translate.instant("WIKI.DELETE_LIGHTBOX_TITLE")
title = "Delete Wiki Link"
message = $scope.wikiLinks[linkId].title message = $scope.wikiLinks[linkId].title
$confirm.askOnDelete(title, message).then (finish) => $confirm.askOnDelete(title, message).then (finish) =>
@ -143,4 +144,4 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l
return {link:link} return {link:link}
module.directive("tgWikiNav", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", "$tgNavUrls", module.directive("tgWikiNav", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", "$tgNavUrls",
"$tgAnalytics", "$tgLoading", "$tgTemplate", WikiNavDirective]) "$tgAnalytics", "$tgLoading", "$tgTemplate", "$compile", "$translate", WikiNavDirective])

View File

@ -1,63 +0,0 @@
{
"checksley": {
"defaultMessage": "This value seems to be invalid.",
"type-email": "This value should be a valid email.",
"type-url": "This value should be a valid url.",
"type-urlstrict": "This value should be a valid url.",
"type-number": "This value should be a valid number.",
"type-digits": "This value should be digits.",
"type-dateIso": "This value should be a valid date (YYYY-MM-DD).",
"type-alphanum": "This value should be alphanumeric.",
"type-phone": "This value should be a valid phone number.",
"notnull": "This value should not be null.",
"notblank": "This value should not be blank.",
"required": "This value is required.",
"regexp": "This value seems to be invalid.",
"min": "This value should be greater than or equal to %s.",
"max": "This value should be lower than or equal to %s.",
"range": "This value should be between %s and %s.",
"minlength": "This value is too short. It should have %s characters or more.",
"maxlength": "This value is too long. It should have %s characters or less.",
"rangelength": "This value length is invalid. It should be between %s and %s characters long.",
"mincheck": "You must select at least %s choices.",
"maxcheck": "You must select %s choices or less.",
"rangecheck": "You must select between %s and %s choices.",
"equalto": "This value should be the same."
},
"common": {
"subject": "Subject",
"save": "Save",
"blocked": "Blocked",
"cancel": "Cancel",
"status": "Status",
"new-bulk": "New bulk insert",
"one-item-line": "One item per line..."
},
"pagination": {
"next": "Next",
"prev": "Previous"
},
"markdown-editor": {
"heading-1": "First Level Heading",
"heading-2": "Second Level Heading",
"heading-3": "Third Level Heading",
"bold": "Bold",
"italic": "Italic",
"strike": "Strike",
"bulleted-list": "Bulleted List",
"numeric-list": "Numeric List",
"picture": "Picture",
"link": "Link",
"quotes": "Quotes",
"code-block": "Code Block / Code",
"preview": "Preview",
"help": "Help",
"placeholder": "Your title here...",
"link-placeholder": "Your text to link here..."
},
"us": {
"title-new": "New User Story",
"team-requirement": "Team Requirement",
"client-requirement": "Client Requirement"
}
}

872
app/locales/locale-en.json Normal file
View File

@ -0,0 +1,872 @@
{
"COMMON": {
"YES": "Yes",
"NO": "No",
"LOADING": "Loading...",
"LOADING_PROJECT": "Loading project...",
"SAVE": "Save",
"CANCEL": "Cancel",
"ACCEPT": "Accept",
"DELETE": "Delete",
"CREATE": "Create",
"ADD": "Add",
"YES": "Yes",
"NO": "No",
"COPY_TO_CLIPBOARD": "Copy to clipboard: Ctrl+C",
"EDIT": "Edit",
"DRAG": "Drag",
"TAG_LINE": "Your agile, free, and open source project management tool",
"TAG_LINE_2": "LOVE YOUR PROJECT",
"BLOCK": "Block",
"UNBLOCK": "Unblock",
"BLOCKED": "Blocked",
"CREATED_BY": "Created by {{fullDisplayName}}",
"FROM": "from",
"TO": "to",
"CLOSE": "close",
"BLOCKED_NOTE": "Why is this user story blocked?",
"BLOCKED_REASON": "Please explain the reason",
"GO_HOME": "Take me home",
"PLUGINS": "Plugins",
"BETA": "We are on beta!",
"ONE_ITEM_LINE": "One item per line...",
"NEW_BULK": "New bulk insert",
"RELATED_TASKS": "Related tasks",
"LOGOUT": "Logout",
"GENERIC_ERROR": "One of our Oompa Loompas says {{error}}.",
"IOCAINE_TEXT": "Feeling a bit overwhelmed by a task? Make sure others know about it by clicking on Iocaine when editing a task. It's possible to become immune to this (fictional) deadly poison by consuming small amounts over time just as it's possible to get better at what you do by occasionally taking on extra challenges!",
"TAGS": {
"PLACEHOLDER": "I'm it! Tag me...",
"DELETE": "delete tag",
"ADD": "Add tag"
},
"DESCRIPTION": {
"EMPTY": "Empty space is so boring... go on be descriptive... A rose by any other name would smell as sweet...",
"MARKDOWN_HELP": "Markown syntax help",
"NO_DESCRIPTION": "No description yet"
},
"FIELDS": {
"SUBJECT": "Subject",
"NAME": "Name",
"URL": "URL",
"DESCRIPTION": "Description",
"VALUE": "Value",
"SLUG": "Slug",
"COLOR": "Color",
"IS_CLOSED": "Is closed?",
"STATUS": "Status",
"ASSIGNED_TO": "Assigned to",
"POINTS": "Points",
"BLOCKED_NOTE": "blocked note",
"IS_BLOCKED": "is blocked"
},
"ROLES": {
"ALL": "All"
},
"ASSIGNED_TO": {
"NOT_ASSIGNED": "Not assigned",
"DELETE_ASSIGNMENT": "Delete assignment",
"REMOVE_ASSIGNED": "Remove assigned",
"TOO_MANY": "...too many users, keep filtering",
"CONFIRM_UNASSIGNED": "Are you sure you want to leave it unassigned?"
},
"STATUS": {
"CLOSED": "Closed",
"OPEN": "Open"
},
"WATCHERS": {
"ADD": "Add watcher",
"TITLE": "watchers",
"DELETE": "delete watcher"
},
"CUSTOM_ATTRIBUTES": {
"CUSTOM_FIELDS": "Custom Fields",
"SAVE": "Save Custom Field",
"EDIT": "Edit Custom Field",
"DELETE": "Delete custom attribute",
"CONFIRM_DELETE": "Remeber that all values in this custom field will be deleted.</br> Are you sure you want to continue?"
},
"FILTERS": {
"TITLE": "filters",
"INPUT_PLACEHOLDER": "Subject or reference",
"TITLE_ACTION_FILTER_BUTTON": "search",
"BREADCRUMB_TITLE": "back to categories",
"BREADCRUMB_FILTERS": "Filters",
"BREADCRUMB_STATUS": "status"
}
},
"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"
},
"ATTACHMENT": {
"SECTION_NAME": "attachments",
"TITLE": "<%- name %> uploaded on <%- created_date %>",
"DESCIPTION": "Type a short description",
"DEPRECATED_FILE": "Deprecated?",
"ADD": "Add new attachment. <%- maxFileSizeMsg %>",
"MAX_FILE_SIZE": "[Max. size: {{maxFileSize}}]",
"SHOW_DEPRECATED": "+ show deprecated atachments",
"HIDE_DEPRECATED": "- hide deprecated atachments",
"COUNT_DEPRECATED": "({{ctrl.deprecatedAttachmentsCount }} deprecated)",
"MAX_UPLOAD_SIZE": "Maximum upload size is {{maxFileSize}}",
"DATE": "DD MMM YYYY [at] hh:mm",
"FIELDS": {
"IS_DEPRECATED": "is deprecated"
}
},
"PAGINATION": {
"PREVIOUS": "Prev",
"NEXT": "Next"
},
"ADMIN": {
"COMMON": {
"TITLE_ACTION_EDIT_VALUE": "Edit value",
"TITLE_ACTION_DELETE_VALUE": "Delete value"
},
"HELP": "Do you need help? Check out our support page!",
"PROJECT_DEFAULT_VALUES": {
"TITLE": "Default Values",
"SUBTITLE": "Set default values for all selector inputs."
},
"MEMBERSHIPS": {
"TITLE": "Manage members",
"ADD_BUTTON": "+ New member",
"ADD_BUTTON_TITLE": "Add new member"
},
"PROJECT_EXPORT": {
"TITLE": "Export",
"SUBTITLE": "Export your project to save a backup or to create a new one based on this.",
"EXPORT_BUTTON": "Export",
"EXPORT_BUTTON_TITLE": "Export your project",
"LOADING_TITLE": "We are generating your dump file",
"DUMP_READY": "Your dump file is ready!",
"LOADING_MESSAGE": "Please don't close this page.",
"ASYNC_MESSAGE": "We will send you an email when ready.",
"SYNC_MESSAGE": "If the download doesn't start automatically click <a href='{{url}}' download title='Download the dump file'>here.",
"ERROR": "Our oompa loompas have some problems generasting your dump. MPlease try again.",
"ERROR_BUSY": "Sorry, our oompa loompas are very busy right now. Please try again in a few minutes.",
"ERROR_MESSAGE": "Our oompa loompas have some problems generasting your dump: {{message}}"
},
"MODULES": {
"TITLE": "Modules",
"ENABLE": "Enable",
"DISABLE": "Disable",
"BACKLOG": "Backlog",
"BACKLOG_DESCRIPTION": "Manage your user stories to maintain an organized view of upcoming and prioritized work.",
"KANBAN": "Kanban",
"KANBAN_DESCRIPTION": "Organize your project in a lean way with this board.",
"ISSUES": "Issues",
"ISSUES_DESCRIPTION": "Track the bugs, questions and enhancements related to your project. Don't miss anything!",
"WIKI": "Wiki",
"WIKI_DESCRIPTION": "Add, modify, or delete content in collaboration with others. This is the right place for your project documentation.",
"MEETUP": "Meet Up",
"MEETUP_DESCRIPTION": "Choose your videoconference system. Even developers need face to face contact.",
"SELECT_VIDEOCONFERENCE": "Select a videoconference system",
"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}}",
"PROJECT_DETAILS": "Project details",
"PROJECT_NAME": "Project name",
"PROJECT_SLUG": "Project slug",
"NUMBER_SPRINTS": "Number of sprints",
"NUMBER_US_POINTS": "Number of US points",
"DESCRIPTION": "DESCRIPTION",
"PUBLIC_PROJECT": "Public project",
"PRIVATE_PROJECT": "Private project",
"DELETE": "Delete this project"
},
"REPORTS": {
"TITLE": "Reports",
"SUBTITLE": "Export your project data in CSV format and make your own reports.",
"DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analize all your data easily.",
"HELP": "How to use this on my own spreadsheet?",
"REGENERATE_TITLE": "Change URL",
"REGENERATE_SUBTITLE": "You going to change the CSV data access url. The previous url will be disabled. Are you sure?"
},
"CUSTOM_FIELDS": {
"TITLE": "Custom Fields",
"SUBTITLE": "Specify the custom fields for your user stories, tasks and issues",
"US_DESCRIPTION": "User stories custom fields",
"US_ADD": "Add a custom field in user stories",
"TASK_DESCRIPTION": "Tasks custom fields",
"TASK_ADD": "Add a custom field in tasks",
"ISSUE_DESCRIPTION": "Issues custom fields",
"ISSUE_ADD": "Add a custom field in issues"
},
"PROJECT_VALUES": {
"APP_TITLE": "Project values - {{sectionName}} - {{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",
"SUBTITLE": "Specify the points your user stories could be estimated to",
"ACTION_ADD": "Add new point"
},
"PROJECT_VALUES_PRIORITIES": {
"TITLE": "Issue priorities",
"SUBTITLE": "Specify the priorities your issues will have"
},
"PROJECT_VALUES_SEVERITIES": {
"TITLE": "Issue severities",
"SUBTITLE": "Specify the severities your issues will have"
},
"PROJECT_VALUES_STATUS": {
"TITLE": "Status",
"SUBTITLE": "Specify the statuses your user stories, tasks and issues will go through",
"US_TITLE": "US Statuses",
"TASK_TITLE": "Task Statuses",
"ISSUE_TITLE": "Issue Statuses"
},
"PROJECT_VALUES_TYPES": {
"TITLE": "Types",
"SUBTITLE": "Specify the types your user stories could be estimated to",
"ISSUE_TITLE": "Issues types",
"ACTION_ADD": "Add new {{objName}}"
},
"ROLES": {
"SECTION_NAME": "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",
"TITLE_DELETE_ROLE": "Delete Role",
"REPLACEMENT_ROLE": "All the users with this role will be moved to",
"WARNING_DELETE_ROLE": "<strong>Be careful, all role estimations will be removed</strong>",
"ERROR_DELETE_ALL": "You can't delete all values"
},
"THIRD_PARTIES": {
"SECRET_KEY": "Secret key",
"PAYLOAD_URL": "Payload URL",
"VALID_IPS": "Valid origin ips (separated by ,)"
},
"BITBUCKET": {
"SECTION_NAME": "Bitbucket",
"APP_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}}",
"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}}"
},
"WEBHOOKS": {
"APP_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",
"TYPE_NAME": "Type the service name",
"TYPE_PAYLOAD_URL": "Type the service payload url",
"TYPE_SERVICE_SECRET": "Type the service secret key",
"SAVE": "Save Webhook",
"CANCEL": "Cancel Webhook",
"TOGGLE_HISTORY": "Toggle history",
"SHOW_HISTORY": "(Show history)",
"TEST": "Test Webhook",
"EDIT": "Edit Webhook",
"DELETE": "Delete Webhook",
"REQUEST": "Request",
"RESEND_REQUEST": "Resend request",
"HEADERS": "Headers",
"PAYLOAD": "Payload",
"RESPONSE": "Response",
"DATE": "DD MMM YYYY [at] hh:mm:ss",
"ACTION_HIDE_HISTORY": "(Hide history)",
"ACTION_SHOW_HISTORY": "(Show history)",
"WEBHOOK_NAME": "Webhook '{{name}}'"
},
"CUSTOM_ATTRIBUTES": {
"ADD": "Add custom field",
"EDIT": "Edit Custom Field",
"DELETE": "Delete Custom Field",
"SAVE_TITLE": "Save Custom Field",
"CANCEL_TITLE": "Cancel creation",
"SET_FIELD_NAME": "Set your custom field name",
"SET_FIELD_DESCRIPTION": "Set your custom field description",
"ACTION_UPDATE": "Update Custom Field",
"ACTION_CANCEL_EDITION": "Cancel edition"
},
"MEMBERSHIP": {
"COLUMN_MEMBER": "Member",
"COLUMN_ADMIN": "Admin",
"COLUMN_ROLE": "Role",
"COLUMN_STATUS": "Status",
"STATUS_ACTIVE": "Active",
"STATUS_PENDING": "Pending",
"DELETE_MEMBER": "Delete member",
"SUCCESS_SEND_INVITATION": "We've sent the invitation again to '{{email}}'.",
"ERROR_SEND_INVITATION": "We haven't sent the invitation.",
"SUCCESS_DELETE": "We've deleted {{message}}.",
"ERROR_DELETE": "We have not been able to delete {{message}}.",
"DEFAULT_DELETE_MESSAGE": "the invitation to {{email}}"
},
"DEFAULT_VALUES": {
"LABEL_POINTS": "Default value for points selector",
"LABEL_US": "Default value for US status selector",
"LABEL_TASK_STATUS": "Default value for task status selector",
"LABEL_PRIORITY": "Default value for priority selector",
"LABEL_SEVERITY": "Default value for severity selector",
"LABEL_ISSUE_TYPE": "Default value for issue type selector",
"LABEL_ISSUE_STATUS": "Default value for issue status selector"
},
"PROJECT": {
"COLORS": {
"ACTION_NEW_STATUS": "+ Add new status"
}
},
"CSV": {
"TITLE": "{{csvType}} reports",
"DOWNLOAD": "Download CSV",
"URL_FIELD_PLACEHOLDER": "Please regenerate CSV url",
"TITLE_REGENERATE_URL": "Regenerate CSV url",
"ACTION_GENERATE_URL": "Generate Url",
"ACTION_REGENERATE": "Regenerate"
},
"STATUS": {
"PLACEHOLDER_WRITE_STATUS_NAME": "Write a name for the new status"
},
"TYPES": {
"PLACEHOLDER_WRITE_NAME": "Write a name for the new element"
},
"US_STATUS": {
"ACTION_ADD_STATUS": "Add new status",
"IS_ARCHIVED_COLUMN": "Is archived?",
"WIP_LIMIT_COLUMN": "WIP Limit",
"PLACEHOLDER_WRITE_NAME": "Write a name for the new status"
},
"MENU": {
"TITLE": "Admin",
"PROJECT": "Project",
"ATTRIBUTES": "Attributes",
"MEMBERS": "Members",
"PERMISSIONS": "Permissions",
"INTEGRATIONS": "Integrations",
"PLUGINS": "Plugins"
},
"SUBMENU": {
"ROLE_UX": "UX",
"ROLE_PRODUCT_OWNER": "Product Owner",
"ROLE_DESIGNER": "Designer",
"ROLE_BACK": "Back",
"ROLE_FRONT": "Front",
"ACTION_NEW_ROLE": "+ New role",
"TITLE_ACTION_NEW_ROLE": "Add new role"
},
"SUBMENU_PROJECT_VALUES": {
"STATUS": "Status",
"POINTS": "Points",
"PRIORITIES": "Priorities",
"SEVERITIES": "Severities",
"TYPES": "Types",
"CUSTOM_FIELDS": "Custom fields"
},
"SUBMENU_PROJECT_PROFILE": {
"TITLE": "Project Profile"
},
"SUBMENU_ROLES": {
"TITLE": "Roles"
},
"SUBMENU_THIDPARTIES": {
"TITLE": "Services"
}
},
"PROJECT": {
"WELCOME": "Welcome",
"SECTION_PROJECTS": "Projects",
"STATS": {
"PROJECT": "project<br/> points",
"DEFINED": "defined<br/> points",
"ASSIGNED": "assigned<br/> points",
"CLOSED": "closed<br/> points"
},
"SECTION": {
"SEARCH": "Search",
"BACKLOG": "Backlog",
"KANBAN": "Kanban",
"ISSUES": "Issues",
"WIKI": "Wiki",
"TEAM": "Team",
"MEETUP": "Meet Up",
"ADMIN": "Admin"
},
"NAVIGATION": {
"SECTION_TITLE": "Your project",
"PLACEHOLDER_SEARCH": "Search in...",
"ACTION_CREATE_PROJECT": "Create project",
"TITLE_ACTION_IMPORT": "Import project",
"TITLE_PRVIOUS_PROJECT": "Show previous projects",
"TITLE_NEXT_PROJECT": "Show next projects"
},
"IMPORT": {
"TITLE": "Importing Project",
"DESCRIPTION": "This process can take a while, please keep the window open.",
"ASYNC_IN_PROGRESS_TITLE": "Our Oompa Loompas are importing your project",
"ASYNC_IN_PROGRESS_MESSAGE": "This process could take a few minutes <br/> We will send you an email when ready",
"ERROR": "Our oompa loompas have some problems importing your dump data. Please try again.",
"ERROR_TOO_MANY_REQUEST": "Sorry, our oompa loompas are very busy right now. Please try again in a few minutes.",
"ERROR_MESSAGE": "Our oompa loompas have some problems importing your dump data: {{error_message}}",
"SYNC_SUCCESS": "Your project has been imported successfuly"
}
},
"LIGHTBOX": {
"DELETE_ACCOUNT": {
"SECTION_NAME": "Delete Taiga Account",
"CONFIRM": "Are you sure you want to delete your Taiga account?",
"SUBTITLE": "We're going to miss you! :-("
},
"DELETE_PROJECT": {
"TITLE": "Delete project",
"QUESTION": "Are you sure you want to delete this project?",
"SUBTITLE": "All project data US/Tasks/Issues/Sprints/WikiPages will be lost! :-(",
"CONFIRM": "Yes, I'm really sure"
},
"ASSIGNED_TO": {
"SELECT": "Select assigned to",
"SEARCH": "Search for users"
},
"ADD_MEMBER": {
"TITLE": "New Member",
"HELP_TEXT": "If users are already registered on Taiga, they will be added automatically. Otherwise they will receive an invitation."
},
"CREATE_ISSUE": {
"TITLE": "Add Issue"
},
"FEEDBACK": {
"TITLE": "Tell us something...",
"COMMENT": "...a bug, some suggestions, something cool... or even your worst nightmare with Taiga",
"ACTION_SEND": "Send feedback"
},
"SEARCH": {
"TITLE": "Search",
"PLACEHOLDER_SEARCH": "What are you looking for?"
},
"ADD_EDIT_SPRINT": {
"TITLE": "New sprint",
"PLACEHOLDER_SPRINT_NAME": "sprint name",
"PLACEHOLDER_SPRINT_START": "Estimated Start",
"PLACEHOLDER_SPRINT_END": "Estimated End",
"ACTION_DELETE_SPRINT": "Do you want to delete this sprint?",
"TITLE_ACTION_DELETE_SPRINT": "delete sprint",
"LAST_SPRINT_NAME": " last sprint is <strong> {{lastSprint}} ;-) </strong>"
},
"CREATE_EDIT_TASK": {
"TITLE": "New task",
"PLACEHOLDER_SUBJECT": "A task subject",
"PLACEHOLDER_STATUS": "Task status",
"OPTION_UNASSIGNED": "Unassigned",
"PLACEHOLDER_SHORT_DESCRIPTION": "Type a short description",
"ACTION_EDIT": "Edit task"
},
"CREATE_EDIT_US": {
"TITLE": "New US",
"PLACEHOLDER_DESCRIPTION": "Please add descriptive text to help others better understand this US",
"NEW_US": "New user story",
"EDIT_US": "Edit user story"
},
"DELETE_SPRINT": {
"TITLE": "Delete sprint"
},
"CREATE_MEMBER": {
"PLACEHOLDER_INVITATION_TEXT": "(Optional) Add a personalized text to the invitation. Tell something lovely to your new members ;-)",
"PLACEHOLDER_TYPE_EMAIL": "Type an Email"
}
},
"US": {
"TOTAL_POINTS": "total",
"ADD": "+ Add a new User Story",
"ADD_BULK": "Add some new User Stories in bulk",
"PROMOTED": "This US has been promoted from Issue",
"TITLE_LINK_GO_TO_ISSUE": "Go to issue",
"EXTERNAL_REFERENCE": "This US has been created from",
"GO_TO_EXTERNAL_REFERENCE": "Go to origin",
"BLOCKED": "This user story is blocked",
"PREVIOUS": "previous user story",
"NEXT": "next user story",
"TITLE_DELETE_ACTION": "Delete User Story",
"LIGHTBOX_TITLE_BLOKING_US": "Blocking us",
"TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} tasks completed",
"ASSIGN": "Assign User Story",
"NOT_ESTIMATED": "Not estimated",
"TOTAL_US_POINTS": "Total Us points",
"FIELDS": {
"TEAM_REQUIREMENT": "Team Requirement",
"CLIENT_REQUIREMENT": "Client Requirement",
"FINISH_DATE": "Finish date"
}
},
"COMMENTS": {
"DELETED_INFO": "Comment deleted by {{deleteCommentUser}} on {{deleteCommentDate}}",
"TITLE": "Comments",
"COMMENT": "Comment",
"TYPE_NEW_COMMENT": "Type a new comment here",
"SHOW_DELETED": "Show deleted comment",
"HIDE_DELETED": "Hide deleted comment",
"RESTORE": "Restore comment"
},
"ACTIVITY": {
"SHOW_ACTIVITY": "Show activity",
"SHOW_MORE": "+ Show previous entries ({{showMore}} more)",
"TITLE": "Activity",
"REMOVED": "removed",
"ADDED": "added",
"US_POINTS": "US points ({{name}})",
"NEW_ATTACHMENT": "new attachment",
"DELETED_ATTACHMENT": "deleted attachment",
"UPDATED_ATTACHMENT": "updated attachment {{filename}}",
"DELETED_CUSTOM_ATTRIBUTE": "deleted custom attribute",
"SIZE_CHANGE": "Made {{size}} {size, plural, one{change} other{changes}}"
},
"BACKLOG": {
"MOVE_US_TO_CURRENT_SPRINT": "Move to Current Sprint",
"SHOW_FILTERS": "Show filters",
"SHOW_TAGS": "Show tags",
"EMPTY": "Your backlog is empty!",
"CREATE_NEW_US": "Create a new US",
"CREATE_NEW_US_EMPTY_HELP": "You may want to create a new user story",
"EXCESS_OF_POINTS": "Excess of points",
"PENDING_POINTS": "Pending Points",
"CLOSED_POINTS": "Closed points",
"COMPACT_SPRINT": "Compact Sprint",
"GO_TO_TASKBOARD": "Go to the taskboard of {{::name}}",
"EDIT_SPRINT": "Edit Sprint",
"CLOSED_POINTS": "closed",
"TOTAL_POINTS": "total",
"STATUS_NAME": "Status Name",
"SORTABLE_FILTER_ERROR": "You can't drop on backlog when filters are open",
"DOOMLINE": "Project Scope [Doomline]",
"CHART": {
"OPTIMAL": "Optimal pending points for sprint {{xval}} should be {{yval}}",
"REAL": "Real pending points for sprint {{xval}} is {{yval}}",
"INCREMENT_TEAM": "Incremented points by team requirements for sprint {{xval}} is {{yval}}",
"INCREMENT_CLIENT": "Incremented points by client requirements for sprint {{xval}} is {{yval}}"
},
"TAGS": {
"SHOW": "Show Tags",
"HIDE": "Hide Tags"
},
"TABLE": {
"COLUMN_US": "User Stories",
"TITLE_COLUMN_POINTS": "Select view per Role"
},
"SPRINT_SUMMARY": {
"TOTAL_POINTS": "total<br />points",
"COMPLETED_POINTS": "completed<br />points",
"OPEN_TASKS": "open<br />tasks",
"CLOSED_TASKS": "closed<br />tasks",
"IOCAINE_DOSES": "iocaine<br />doses",
"SHOW_STATISTICS_TITLE": "Show statistics"
},
"SUMMARY": {
"PROJECT_POINTS": "project<br />points",
"DEFINED_POINTS": "defined<br />points",
"CLOSED_POINTS": "closed<br />points",
"POINTS_PER_SPRINT": "points /<br />sprint"
},
"FILTERS": {
"TITLE": "Filters",
"REMOVE": "Remove Filters",
"SHOW": "Show Filters",
"FILTER_CATEGORY_STATUS": "Status",
"FILTER_CATEGORY_TAGS": "Tags"
},
"SPRINTS": {
"TITLE": "SPRINTS",
"LINK_TASKBOARD": "Sprint Taskboard",
"TITLE_LINK_TASKBOARD": "Go to Taskboard of {{spring.name}}",
"NUMBER_SPRINTS": "<br/>sprints",
"TITLE_ACTION_NEW_SPRINT": "+ New sprint",
"ACTION_NEW_SPRINT": "+ New sprint",
"ACTION_SHOW_CLOSED_SPRINTS": "Show closed sprints",
"ACTION_HIDE_CLOSED_SPRINTS": "Hide closed sprints"
}
},
"ERROR": {
"TEXT1": "Something happened and our Oompa Loompas are working on it.",
"TEXT2": "Try reloading again soon.",
"NOT_FOUND": "Not found",
"NOT_FOUND_TEXT": "Error 404. The page you are looking for no longer exists. Perhaps you can return back to TAIGA homepage and see if you can find what you are looking for.",
"PERMISSION_DENIED": "Permission denied",
"PERMISSION_DENIED_CODE": "Error 403."
},
"TASKBOARD": {
"SECTION_NAME": "Taskboard",
"TITLE_ACTION_ADD": "Add a new Task",
"TITLE_ACTION_ADD_BULK": "Add some new Tasks in bulk",
"TITLE_ACTION_ASSIGN": "Assign task",
"TITLE_ACTION_EDIT": "Edit task",
"TABLE": {
"COLUMN": "User story",
"TITLE_ACTION_FOLD": "Fold column",
"TITLE_ACTION_UNFOLD": "Unfold column",
"TITLE_ACTION_FOLD_ROW": "Fold Row",
"TITLE_ACTION_UNFOLD_ROW": "Unfold Row",
"FIELD_POINTS": "points",
"ROW_UNASSIGED_TASKS_TITLE": "Unassigned tasks"
},
"CHARTS": {
"OPTIMAL": "Optimal pending points for day #{formattedDate} should be {{roundedValue}}",
"REAL": "Real pending points for day {{formattedDate}} is {{roundedValue}}"
}
},
"TASK": {
"PLACEHOLDER_SUBJECT": "Type the new task subject",
"TITLE_SELECT_STATUS": "Status Name",
"LINK_TASKBOARD": "Go to taskboard",
"OWNER_US": "This task belongs to",
"TITLE_LINK_GO_OWNER": "Go to user story",
"ORIGIN_US": "This task has been created from",
"TITLE_LINK_GO_ORIGIN": "Go to user story",
"BLOCKED": "This task is blocked",
"PREVIOUS": "previous task",
"NEXT": "next task",
"TITLE_DELETE_ACTION": "Delete Task",
"LIGHTBOX_TITLE_BLOKING_TASK": "Blocking task",
"FIELDS": {
"MILESTONE": "Sprint",
"USER_STORY": "User story",
"IS_IOCAINE": "Is iocaine"
}
},
"NOTIFICATION": {
"OK": "Everything is ok",
"WARNING": "Oops, something happened...",
"WARNING_TEXT": "Our oompa Loompas are sad, your changes were not saved!",
"SAVED": "Our oompa Loompas saved all your changes!",
"CLOSE": "Close notification",
"MAIL": "Notifications By Mail",
"ASK_DELETE": "Are you sure you want to delete?"
},
"CANCEL_ACCOUNT": {
"TITLE": "Cancel your account",
"SUBTITLE": "We're sorry you are leaving the taiga, we hope you enjoyed your stay :)",
"PLACEHOLDER_INPUT_TOKEN": "cancel account token",
"ACTION_LEAVING": "Yes, I'm leaving!",
"SUCCESS": "Our Oompa Loompas removed your account"
},
"CHANGE_EMAIL_FORM": {
"TITLE": "Change your email",
"SUBTITLE": "One click more and your email will be updated!",
"PLACEHOLDER_INPUT_TOKEN": "change email token",
"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 a mail to<br /><strong>{{email}}</strong><br />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": {
"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": {
"SECTION_NAME": "Issue Details",
"ACTION_NEW_ISSUE": "+ NEW ISSUE",
"ACTION_PROMOTE_TO_US": "Promote to User Story",
"PLACEHOLDER_FILTER_NAME": "Write the filter name and press enter",
"PROMOTED": "This issue has been promoted to US:",
"EXTERNAL_REFERENCE": "This issue has been created from",
"GO_TO_EXTERNAL_REFERENCE": "Go to origin",
"BLOCKED": "This issue is blocked",
"TITLE_PREVIOUS_ISSUE": "previous issue",
"TITLE_NEXT_ISSUE": "next issue",
"ACTION_DELETE": "Delete issue",
"LIGHTBOX_TITLE_BLOKING_ISSUE": "Blocking issue",
"FIELDS": {
"PRIORITY": "priority",
"SEVERITY": "severity",
"TYPE": "type"
},
"CONFIRM_PROMOTE": {
"TITLE": "Promote this issue to a new user story",
"MESSAGE": "Are you sure you want to create a new US from this Issue?"
},
"FILTERS": {
"ACTION_SAVE_CUSTOM_FILTER": "save as custom filter",
"CONFIRM_DELETE": {
"TITLE": "Delete custom filter",
"MESSAGE": "the custom filter '{{customFilterName}}'"
},
"FILTER_CATEGORY_TYPE": "Type",
"FILTER_CATEGORY_STATUS": "Status",
"FILTER_CATEGORY_SEVERITY": "Severity",
"FILTER_CATEGORY_PRIORITIES": "Priorities",
"FILTER_CATEGORY_TAGS": "Tags",
"FILTER_CATEGORY_ASSIGNED_TO": "Assigned to",
"FILTER_CATEGORY_CREATED_BY": "Created by",
"CUSTOM_FILTERS": "Custom filters"
},
"TABLE": {
"COLUMN_CREATED": "Created",
"TITLE_ACTION_CHANGE_STATUS": "Change status",
"EMPTY": {
"TITLE": "There are no issues to report :-)",
"SUBTITLE": "Did you find an issue?",
"ACTION_CREATE_ISSUE": "Create a new Issue"
}
}
},
"KANBAN": {
"TITLE_ACTION_FOLD": "Fold column",
"TITLE_ACTION_UNFOLD": "Unfold column",
"TITLE_ACTION_FOLD_CARDS": "Fold cards",
"TITLE_ACTION_UNFOLD_CARDS": "Unfold cards",
"TITLE_ACTION_ADD_US": "Add New User Story",
"TITLE_ACTION_ADD_BULK": "Add New bulk",
"ACTION_SHOW_ARCHIVED": "Show archived",
"ACTION_HIDE_ARCHIVED": "Hide archived",
"HIDDEN_USER_STORIES": "The user stories in this status are hidden by default",
"ARCHIVED": "You have archived",
"UNDO_ARCHIVED": "Drag & drop again to undo"
},
"SEARCH": {
"FILTER_USER_STORIES": "User Stories",
"FILTER_ISSUES": "Issues",
"FILTER_TASKS": "Tasks",
"FILTER_WIKI": "Wiki Pages",
"PLACEHOLDER_SEARCH": "Search in...",
"TITLE_ACTION_SEARCH": "search",
"EMPTY_TITLE": "It looks like nothing was found with your search criteria.",
"EMPTY_DESCRIPTION": "Maybe try one of the tabs above or search again"
},
"TEAM": {
"SECTION_NAME": "Team",
"APP_TITLE": "TEAM - {{projectName}}",
"PLACEHOLDER_INPUT_SEARCH": "Search by username or role...",
"COLUMN_MR_WOLF": "Mr. Wolf",
"EXPLANATION_COLUMN_MR_WOLF": "Closed issues",
"COLUMN_IOCAINE": "Iocaine Drinker",
"EXPLANATION_COLUMN_IOCAINE": "Iocaine doses ingested",
"COLUMN_CERVANTES": "Cervantes",
"EXPLANATION_COLUMN_CERVANTES": "Wiki pages edited",
"COLUMN_BUG_HUNTER": "Total Bug Hunter",
"EXPLANATION_COLUMN_BUG_HUNTER": "Bugs reported",
"COLUMN_NIGHT_SHIFT": "Night Shift",
"EXPLANATION_COLUMN_NIGHT_SHIFT": "Tasks closed",
"COLUMN_TOTAL_POWER": "Total Power",
"EXPLANATION_COLUMN_TOTAL_POWER": "Total Points",
"SECTION_TITLE_TEAM": "Team >",
"SECTION_FILTER_ALL": "All",
"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",
"FIELD_RETYPE_PASSWORD": "Retype Password",
"ERROR_PASSWORD_MATCH": "The passwords doesn't match"
},
"USER_SETTINGS": {
"AVATAR_MAX_SIZE": "[Max, size: {{maxFileSize}}}",
"MENU": {
"SECTION_TITLE": "User Settings",
"USER_PROFILE": "User profile",
"CHANGE_PASSWORD": "Change password",
"EMAIL_NOTIFICATIONS": "Email notifications"
},
"NOTIFICATIONS": {
"SECTION_NAME": "Email Notifications",
"COLUMN_PROJECT": "Project",
"COLUMN_RECEIVE_ALL": "Receive All",
"COLUMN_ONLY_INVOLVED": "Only Involved",
"COLUMN_NO_NOTIFICATIONS": "No notifications"
},
"POPOVER": {
"USER_PROFILE": "User Profile",
"CHANGE_PASSWORD": "Change Password",
"NOTIFICATIONS": "Notifications",
"FEEDBACK": "Feedback",
"TITLE_AVATAR": "User preferences"
}
},
"USER_PROFILE": {
"IMAGE_HELP": "The image will be cropped to 80x80px.<br>",
"ACTION_CHANGE_IMAGE": "Change",
"ACTION_USE_GRAVATAR": "Use gravatar image",
"ACTION_DELETE_ACCOUNT": "Delete Taiga account",
"CHANGE_EMAIL_SUCCESS": "<strong>Check your inbox!</strong><br />We have sent a mail to your account<br />with the instructions to set your new address",
"CHANGE_PHOTO": "Change photo",
"FIELD": {
"USERNAME": "Username",
"EMAIL": "Email",
"FULL_NAME": "Full name",
"PLACEHOLDER_FULL_NAME": "Set your full name (ex. Íñigo Montoya)",
"BIO": "Bio",
"PLACEHOLDER_BIO": "Tell us something about you",
"LANGUAGE": "Language"
}
},
"WIZARD": {
"SECTION_TITLE_CHOOSE_TEMPLATE": "Choose a template",
"CHOOSE_TEMPLATE_TEXT": "Which template would fit better in your project?",
"SECTION_TITLE_CREATE_PROJECT": "Create Project",
"CREATE_PROJECT_TEXT": "Fresh and clean. So exciting!",
"PROGRESS_TEMPLATE_SELECTION": "Template selection",
"PROGRESS_NAME_DESCRIPTION": "Name and description"
},
"WIKI": {
"PLACEHOLDER_PAGE": "Write your wiki page",
"REMOVE": "Remove this wiki page",
"DELETE_LIGHTBOX_TITLE": "Delete Wiki Page",
"NAVIGATION": {
"SECTION_NAME": "Links",
"ACTION_ADD_LINK": "Add link"
},
"SUMMARY": {
"TIMES_EDITED": "times <br />edited",
"LAST_EDIT": "last <br />edit",
"LAST_MODIFICATION": "last modification"
}
},
"LANGUAGES": {
"ENGLISH": "English"
}
}

View File

@ -2,7 +2,7 @@ ul.paginator
<% if (showPrevious) { %> <% if (showPrevious) { %>
li.previous li.previous
a(href="", class="previous next_prev_button", class="disabled") a(href="", class="previous next_prev_button", class="disabled")
span(i18next="pagination.prev") Prev span(translate="PAGINATION.PREVIOUS")
<% } %> <% } %>
<% _.each(pages, function(item) { %> <% _.each(pages, function(item) { %>
@ -19,5 +19,5 @@ ul.paginator
<% if (showNext) { %> <% if (showNext) { %>
li.next li.next
a(href="", class="next next_prev_button", class="disabled") a(href="", class="next next_prev_button", class="disabled")
span(i18next="pagination.next") Next span(translate="PAGINATION.NEXT")
<% } %> <% } %>

View File

@ -1,5 +1,5 @@
.check .check
input(type="checkbox", id!="<%- inputId %>") input(type="checkbox", id!="<%- inputId %>")
div div
span.check-text.check-yes Yes span.check-text.check-yes(translate="COMMON.YES")
span.check-text.check-no No span.check-text.check-no(translate="COMMON.NO")

View File

@ -1,5 +1,7 @@
doctype html
div.wrapper.memberships(ng-controller="MembershipsController as ctrl", div.wrapper.memberships(ng-controller="MembershipsController as ctrl",
ng-init="section='admin'", tg-memberships) ng-init="section='admin'; sectionName='ADMIN.MEMBERSHIPS.TITLE'", tg-memberships)
sidebar.menu-secondary.sidebar(tg-admin-navigation="memberships") sidebar.menu-secondary.sidebar(tg-admin-navigation="memberships")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -9,8 +11,9 @@ div.wrapper.memberships(ng-controller="MembershipsController as ctrl",
include ../includes/components/mainTitle include ../includes/components/mainTitle
.action-buttons .action-buttons
a.button-green(title="Add new member" href="" ng-click="ctrl.addNewMembers()") a.button-green(href="", title="{{ ADMIN.MEMBERSHIPS.ADD_BUTTON_TITLE | translate }}",
span.text + New member ng-click="ctrl.addNewMembers()")
span.text(translate="ADMIN.MEMBERSHIPS.ADD_BUTTON")
include ../includes/modules/admin/admin-membership-table include ../includes/modules/admin/admin-membership-table

View File

@ -1,5 +1,7 @@
doctype html
div.wrapper(tg-project-default-values, ng-controller="ProjectProfileController as ctrl", div.wrapper(tg-project-default-values, ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='Default values'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_DEFAULT_VALUES.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -9,7 +11,6 @@ div.wrapper(tg-project-default-values, ng-controller="ProjectProfileController a
section.main.admin-common section.main.admin-common
header header
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle(translate="ADMIN.PROJECT_DEFAULT_VALUES.SUBTITLE")
p.total Default Values
include ../includes/modules/admin/default-values include ../includes/modules/admin/default-values

View File

@ -1,5 +1,8 @@
doctype html
div.wrapper(ng-controller="ProjectProfileController as ctrl", div.wrapper(ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='Export'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_EXPORT.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -9,18 +12,18 @@ div.wrapper(ng-controller="ProjectProfileController as ctrl",
section.main.admin-common(tg-project-export) section.main.admin-common(tg-project-export)
header header
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Export your project to save a backup or to create a new one based on this. p.admin-subtitle(translate="ADMIN.PROJECT_EXPORT.SUBTITLE")
div.admin-project-export-buttons div.admin-project-export-buttons
a.button-green.button-export(href="", title="Export your project") a.button-green.button-export(href="", title="{{ 'ADMIN.PROJECT_EXPORT.EXPORT_BUTTON_TITLE' | translate }}")
span Export span(translate="ADMIN.PROJECT_EXPORT.EXPORT_BUTTON")
div.admin-project-export-result.hidden div.admin-project-export-result.hidden
div.spin.hidden div.spin.hidden
img(src="/svg/spinner-circle.svg", alt="loading...") img(src="/svg/spinner-circle.svg", alt="{{ 'COMMON.LOADING' | translate }}")
h3.result-title h3.result-title
p.result-message p.result-message
a.help-button(href="https://taiga.io/support/import-export-projects/", target="_blank") a.help-button(href="https://taiga.io/support/import-export-projects/", target="_blank")
span.icon.icon-help span.icon.icon-help
span Do you need help? Check out our support page! span(translate="ADMIN.HELP")

View File

@ -1,5 +1,7 @@
doctype html
div.wrapper(tg-project-modules, ng-controller="ProjectProfileController as ctrl", div.wrapper(tg-project-modules, ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='Modules'") ng-init="section='admin'; sectionName='ADMIN.MODULES.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -15,76 +17,76 @@ div.wrapper(tg-project-modules, ng-controller="ProjectProfileController as ctrl"
div.icon.icon-backlog div.icon.icon-backlog
div.desc div.desc
p p
span Backlog span.title(translate="ADMIN.MODULES.BACKLOG")
| Manage your user stories to maintain an organized view of upcoming and prioritized work. span(translate="ADMIN.MODULES.BACKLOG_DESCRIPTION")
div.activate div.activate
input.activate-input(type="checkbox", id="functionality-backlog", input.activate-input(type="checkbox", id="functionality-backlog",
ng-model="project.is_backlog_activated") ng-model="project.is_backlog_activated")
label.button.button-gray(ng-switch="project.is_backlog_activated", label.button.button-gray(ng-switch="project.is_backlog_activated",
for="functionality-backlog") for="functionality-backlog")
span(ng-switch-when="true") Disable span(ng-switch-when="true", translate="ADMIN.MODULES.DISABLE")
span(ng-switch-when="false") Enable span(ng-switch-when="false", translate="ADMIN.MODULES.ENABLE")
div.functionality(ng-class="{true:'active', false:''}[project.is_kanban_activated]") div.functionality(ng-class="{true:'active', false:''}[project.is_kanban_activated]")
div.icon.icon-kanban div.icon.icon-kanban
div.desc div.desc
p p
span Kanban span.title(translate="ADMIN.MODULES.KANBAN")
| Organize your project in a lean way with this board. span(translate="ADMIN.MODULES.KANBAN_DESCRIPTION")
div.activate div.activate
input.activate-input(type="checkbox", id="functionality-kanban", input.activate-input(type="checkbox", id="functionality-kanban",
ng-model="project.is_kanban_activated") ng-model="project.is_kanban_activated")
label.button.button-gray(ng-switch="project.is_kanban_activated", label.button.button-gray(ng-switch="project.is_kanban_activated",
for="functionality-kanban") for="functionality-kanban")
span(ng-switch-when="true") Disable span(ng-switch-when="true", translate="ADMIN.MODULES.DISABLE")
span(ng-switch-when="false") Enable span(ng-switch-when="false", translate="ADMIN.MODULES.ENABLE")
div.functionality(ng-class="{true:'active', false:''}[project.is_issues_activated]") div.functionality(ng-class="{true:'active', false:''}[project.is_issues_activated]")
div.icon.icon-issues div.icon.icon-issues
div.desc div.desc
p p
span Issues span.title(translate="COMMON.ISSUES")
| Track the bugs, questions and enhancements related to your project. Don't miss anything! span(translate="ADMIN.MODULES.ISSUES_DESCRIPTION")
div.activate div.activate
input.activate-input(type="checkbox", id="functionality-issues", input.activate-input(type="checkbox", id="functionality-issues",
ng-model="project.is_issues_activated") ng-model="project.is_issues_activated")
label.button.button-gray(ng-switch="project.is_issues_activated", label.button.button-gray(ng-switch="project.is_issues_activated",
for="functionality-issues") for="functionality-issues")
span(ng-switch-when="true") Disable span(ng-switch-when="true", translate="ADMIN.MODULES.DISABLE")
span(ng-switch-when="false") Enable span(ng-switch-when="false", translate="ADMIN.MODULES.ENABLE")
div.functionality(ng-class="{true:'active', false:''}[project.is_wiki_activated]") div.functionality(ng-class="{true:'active', false:''}[project.is_wiki_activated]")
div.icon.icon-wiki div.icon.icon-wiki
div.desc div.desc
p p
span Wiki span.title(translate="ADMIN.MODULES.WIKI")
| Add, modify, or delete content in collaboration with others. This is the right place for your project documentation. span(translate="ADMIN.MODULES.WIKI_DESCRIPTION")
div.activate div.activate
input.activate-input(type="checkbox", id="functionality-wiki", input.activate-input(type="checkbox", id="functionality-wiki",
ng-model="project.is_wiki_activated") ng-model="project.is_wiki_activated")
label.button.button-gray(ng-switch="project.is_wiki_activated", label.button.button-gray(ng-switch="project.is_wiki_activated",
for="functionality-wiki") for="functionality-wiki")
span(ng-switch-when="true") Disable span(ng-switch-when="true", translate="ADMIN.MODULES.DISABLE")
span(ng-switch-when="false") Enable span(ng-switch-when="false", translate="ADMIN.MODULES.ENABLE")
div.functionality(ng-class="{true:'active', false:''}[isVideoconferenceActivated]") div.functionality(ng-class="{true:'active', false:''}[isVideoconferenceActivated]")
div.icon.icon-video div.icon.icon-video
div.desc div.desc
p p
span Meet Up span.title(translate="ADMIN.MODULES.MEETUP")
| Choose your videoconference system. Even developers need face to face contact. span(translate="ADMIN.MODULES.MEETUP_DESCRIPTION")
div.activate div.activate
input.activate-input(type="checkbox", id="functionality-video", input.activate-input(type="checkbox", id="functionality-video",
ng-model="isVideoconferenceActivated") ng-model="isVideoconferenceActivated")
label.button.button-gray(ng-switch="isVideoconferenceActivated", label.button.button-gray(ng-switch="isVideoconferenceActivated",
for="functionality-video") for="functionality-video")
span(ng-switch-when="true") Disable span(ng-switch-when="true", translate="ADMIN.MODULES.DISABLE")
span(ng-switch-when="false") Enable span(ng-switch-when="false", translate="ADMIN.MODULES.ENABLE")
div.videoconference-attributes.hidden div.videoconference-attributes.hidden
select(ng-model="project.videoconferences", select(ng-model="project.videoconferences",
ng-options="e.id as e.name for e in [{'id':'appear-in', 'name':'AppearIn'},{'id':'talky', 'name': 'Talky'}]") ng-options="e.id as e.name for e in [{'id':'appear-in', 'name':'AppearIn'},{'id':'talky', 'name': 'Talky'}]")
option(value="") Select a videoconference system option(value="", translate="ADMIN.MODULES.SELECT_VIDEOCONFERENCE")
input(type="text", ng-model="project.videoconferences_salt", input(type="text", ng-model="project.videoconferences_salt",
placeholder="If you want you can append a salt code to the name of the chat room") placeholder="{{'ADMIN.MODULES.SALT_CHAT_ROOM' | translate}}")
button.button-green.submit-button(type="submit", title="Save") Save button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", translate="COMMON.SAVE")

View File

@ -1,5 +1,7 @@
doctype html
div.wrapper(tg-project-profile, ng-controller="ProjectProfileController as ctrl", div.wrapper(tg-project-profile, ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='Project details'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_PROFILE.PROJECT_DETAILS'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -12,29 +14,29 @@ div.wrapper(tg-project-profile, ng-controller="ProjectProfileController as ctrl"
form form
fieldset fieldset
label(for="project-name") Project Name label(for="project-name", translate="ADMIN.PROJECT_PROFILE.PROJECT_NAME")
input(type="text", name="name", placeholder="Project name", id="project-name", input(type="text", name="name", placeholder="{{'ADMIN.PROJECT_PROFILE.PROJECT_NAME' | translate}}", id="project-name",
ng-model="project.name", data-required="true", maxlength="45") ng-model="project.name", data-required="true", maxlength="45")
fieldset fieldset
label(for="project-slug") Project Slug label(for="project-slug", translate="ADMIN.PROJECT_PROFILE.PROJECT_SLUG")
input(type="text", name="slug", placeholder="Slug", id="project-slug", input(type="text", name="slug", placeholder="{{'ADMIN.PROJECT_PROFILE.PROJECT_SLUG' | translate}}", id="project-slug",
ng-model="project.slug", data-required="true") ng-model="project.slug", data-required="true")
fieldset fieldset
label(for="project-sprints") Number of sprints label(for="project-sprints", translate="ADMIN.PROJECT_PROFILE.NUMBER_SPRINTS")
input(type="number", name="total_milestones", min="0", placeholder="Number of sprints", input(type="number", name="total_milestones", min="0", placeholder="{{'ADMIN.PROJECT_PROFILE.NUMBER_SPRINTS' | translate}}",
id="project-sprints", ng-model="project.total_milestones", data-type="digits") id="project-sprints", ng-model="project.total_milestones", data-type="digits")
fieldset fieldset
label(for="total-story-points") Number of US points label(for="total-story-points", translate="ADMIN.PROJECT_PROFILE.NUMBER_US_POINTS")
input(type="number", name="total_story_points", min="0", placeholder="Number of US points", input(type="number", name="total_story_points", min="0", placeholder="{{'ADMIN.PROJECT_PROFILE.NUMBER_US_POINTS' | translate}}",
id="total-story-points", ng-model="project.total_story_points", id="total-story-points", ng-model="project.total_story_points",
data-type="digits", data-required="true") data-type="digits", data-required="true")
fieldset fieldset
label(for="project-description") Description label(for="project-description", translate="ADMIN.PROJECT_PROFILE.DESCRIPTION")
textarea(name="description", placeholder="Description", id="project-description", textarea(name="description", placeholder="{{'ADMIN.PROJECT_PROFILE.DESCRIPTION' | translate}}", id="project-description",
ng-model="project.description", data-required="true") ng-model="project.description", data-required="true")
div div
@ -42,14 +44,14 @@ div.wrapper(tg-project-profile, ng-controller="ProjectProfileController as ctrl"
div div
input.privacy-project(type="radio", name="private-project", ng-model="project.is_private", ng-value="false") input.privacy-project(type="radio", name="private-project", ng-model="project.is_private", ng-value="false")
label.trans-button(for="public-project") label.trans-button(for="public-project")
span Public Project span(translate="ADMIN.PROJECT_PROFILE.PUBLIC_PROJECT")
div div
input.privacy-project(type="radio", name="private-project", ng-model="project.is_private", ng-value="true") input.privacy-project(type="radio", name="private-project", ng-model="project.is_private", ng-value="true")
label.trans-button(for="private-project") label.trans-button(for="private-project")
span Private Project span(translate="ADMIN.PROJECT_PROFILE.PRIVATE_PROJECT")
button.button-green.submit-button(type="submit", title="Save") Save button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", translate="COMMON.SAVE")
a.delete-project(href="", title="Delete this project", ng-click="ctrl.openDeleteLightbox()") Delete this project a.delete-project(href="", title="{{'ADMIN.PROJECT_PROFILE.DELETE' | translate}}", ng-click="ctrl.openDeleteLightbox()", translate="ADMIN.PROJECT_PROFILE.DELETE")
div.lightbox.lightbox-delete-project(tg-lb-delete-project) div.lightbox.lightbox-delete-project(tg-lb-delete-project)
include ../includes/modules/lightbox-delete-project include ../includes/modules/lightbox-delete-project

View File

@ -1,5 +1,7 @@
doctype html
div.wrapper(ng-controller="ProjectProfileController as ctrl", div.wrapper(ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='Reports'") ng-init="section='admin'; sectionName='ADMIN.REPORTS.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -9,24 +11,14 @@ div.wrapper(ng-controller="ProjectProfileController as ctrl",
section.main.admin-common(tg-project-export) section.main.admin-common(tg-project-export)
header header
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Export your project data in CSV format and make your own reports. p.admin-subtitle(translate="ADMIN.REPORTS.SUBTITLE")
p Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analize all your data easily. p(translate="ADMIN.REPORTS.DESCRIPTION")
- var csvType = "US"; div.admin-attributes-section(tg-csv-us)
- var controller = "CsvExporterUserstoriesController"; div.admin-attributes-section(tg-csv-task)
div.admin-attributes-section div.admin-attributes-section
include ../includes/modules/admin/project-csv div(tg-csv-issue)
- var csvType = "Task";
- var controller = "CsvExporterTasksController";
div.admin-attributes-section
include ../includes/modules/admin/project-csv
- var csvType = "Issues";
- var controller = "CsvExporterIssuesController";
div.admin-attributes-section
include ../includes/modules/admin/project-csv
a.help-button(href="https://taiga.io/support/csv-reports/", target="_blank") a.help-button(href="https://taiga.io/support/csv-reports/", target="_blank")
span.icon.icon-help span.icon.icon-help
span How to use this on my own spreadsheet? span(translate="ADMIN.REPORTS.HELP")

View File

@ -1,4 +1,7 @@
div.wrapper(ng-controller="ProjectValuesSectionController") doctype html
div.wrapper(ng-controller="ProjectValuesSectionController",
ng-init="sectionName='ADMIN.CUSTOM_FIELDS.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -7,25 +10,19 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
section.main.admin-common.admin-attributes section.main.admin-common.admin-attributes
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Specify the custom fields for your user stories, tasks and issues p.admin-subtitle(translate="ADMIN.CUSTOM_FIELDS.SUBTITLE")
div.admin-attributes-section(tg-project-custom-attributes, div.admin-attributes-section(tg-project-custom-attributes,
ng-controller="ProjectCustomAttributesController as ctrl", ng-controller="ProjectCustomAttributesController as ctrl",
ng-init="type='userstory';") ng-init="type='userstory'; customFieldSectionTitle='ADMIN.CUSTOM_FIELDS.US_DESCRIPTION'; customFieldButtonTitle='ADMIN.CUSTOM_FIELDS.US_ADD'")
- var customFieldSectionTitle = "User stories custom fields"
- var customFieldButtonTitle = "Add a custom field in user stories"
include ../includes/modules/admin/admin-custom-attributes include ../includes/modules/admin/admin-custom-attributes
div.admin-attributes-section(tg-project-custom-attributes, div.admin-attributes-section(tg-project-custom-attributes,
ng-controller="ProjectCustomAttributesController as ctrl", ng-controller="ProjectCustomAttributesController as ctrl",
ng-init="type='task';") ng-init="type='task'; customFieldSectionTitle='ADMIN.CUSTOM_FIELDS.TASK_DESCRIPTION'; customFieldButtonTitle='ADMIN.CUSTOM_FIELDS.TASK_ADD'")
- var customFieldSectionTitle = "Tasks custom fields"
- var customFieldButtonTitle = "Add a custom field in tasks"
include ../includes/modules/admin/admin-custom-attributes include ../includes/modules/admin/admin-custom-attributes
div.admin-attributes-section(tg-project-custom-attributes, div.admin-attributes-section(tg-project-custom-attributes,
ng-controller="ProjectCustomAttributesController as ctrl", ng-controller="ProjectCustomAttributesController as ctrl",
ng-init="type='issue';") ng-init="type='issue'; customFieldSectionTitle='ADMIN.CUSTOM_FIELDS.ISSUE_DESCRIPTION'; customFieldButtonTitle='ADMIN.CUSTOM_FIELDS.ISSUE_ADD'")
- var customFieldSectionTitle = "Issues custom fields"
- var customFieldButtonTitle = "Add a custom field in issues"
include ../includes/modules/admin/admin-custom-attributes include ../includes/modules/admin/admin-custom-attributes

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper(ng-controller="ProjectValuesSectionController") div.wrapper(ng-controller="ProjectValuesSectionController")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -7,9 +9,9 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
section.main.admin-common.admin-attributes section.main.admin-common.admin-attributes
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Specify the points your user stories could be estimated to p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_POINTS.SUBTITLE")
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
ng-init="section='admin'; resource='userstories'; type='points'; sectionName='Us points'", ng-init="section='admin'; resource='userstories'; type='points'; sectionName='ADMIN.PROJECT_VALUES_POINTS.TITLE'",
type="points") type="points")
include ../includes/modules/admin/project-points include ../includes/modules/admin/project-points

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper(ng-controller="ProjectValuesSectionController") div.wrapper(ng-controller="ProjectValuesSectionController")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -7,9 +9,9 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
section.main.admin-common.admin-attributes section.main.admin-common.admin-attributes
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Specify the priorities your issues will have p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_PRIORITIES.SUBTITLE")
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
ng-init="section='admin'; resource='issues'; type='priorities'; sectionName='Issue priorities'; objName='priority'", ng-init="section='admin'; resource='issues'; type='priorities'; sectionName='ADMIN.PROJECT_VALUES_PRIORITIES.TITLE'; objName='priority'",
type="priorities") type="priorities")
include ../includes/modules/admin/project-types include ../includes/modules/admin/project-types

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper(ng-controller="ProjectValuesSectionController") div.wrapper(ng-controller="ProjectValuesSectionController")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -7,9 +9,9 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
section.main.admin-common.admin-attributes section.main.admin-common.admin-attributes
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Specify the severities your issues will have p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_SEVERITIES.SUBTITLE")
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
ng-init="section='admin'; resource='issues'; type='severities'; sectionName='Issue severities'; objName='severity'", ng-init="section='admin'; resource='issues'; type='severities'; sectionName='ADMIN.PROJECT_VALUES_SEVERITIES.TITLE'; objName='severity'",
type="severities") type="severities")
include ../includes/modules/admin/project-types include ../includes/modules/admin/project-types

View File

@ -1,4 +1,7 @@
div.wrapper(ng-controller="ProjectValuesSectionController") doctype html
div.wrapper(ng-controller="ProjectValuesSectionController",
ng-init="section='admin'; sectionName='ADMIN.PROJECT_VALUES_STATUS.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -7,19 +10,19 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
section.main.admin-common.admin-attributes section.main.admin-common.admin-attributes
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Specify the statuses your user stories, tasks and issues will go through p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_STATUS.SUBTITLE")
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, type="userstory-statuses",
ng-init="section='admin'; resource='userstories'; type='userstory-statuses'; sectionName='Us Statuses'", ng-controller="ProjectValuesController as ctrl",
type="userstory-statuses") ng-init="section='admin'; resource='userstories'; type='userstory-statuses'; sectionName='ADMIN.PROJECT_VALUES_STATUS.US_TITLE'")
include ../includes/modules/admin/project-us-status include ../includes/modules/admin/project-us-status
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, type="task-statuses",
ng-init="section='admin'; resource='tasks'; type='task-statuses'; sectionName='Task Statuses'", ng-controller="ProjectValuesController as ctrl",
type="task-statuses") ng-init="section='admin'; resource='tasks'; type='task-statuses'; sectionName='ADMIN.PROJECT_VALUES_STATUS.TASK_TITLE'")
include ../includes/modules/admin/project-status include ../includes/modules/admin/project-status
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, type="issue-statuses",
ng-init="section='admin'; resource='issues'; type='issue-statuses'; sectionName='Issue Statuses'", ng-controller="ProjectValuesController as ctrl",
type="issue-statuses") ng-init="section='admin'; resource='issues'; type='issue-statuses'; sectionName='ADMIN.PROJECT_VALUES_STATUS.ISSUE_TITLE'")
include ../includes/modules/admin/project-status include ../includes/modules/admin/project-status

View File

@ -1,4 +1,7 @@
div.wrapper(ng-controller="ProjectValuesSectionController") doctype html
div.wrapper(ng-controller="ProjectValuesSectionController"
ng-init="sectionName='ADMIN.PROJECT_VALUES_TYPES.TITLE'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
@ -7,9 +10,9 @@ div.wrapper(ng-controller="ProjectValuesSectionController")
section.main.admin-common.admin-attributes section.main.admin-common.admin-attributes
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Specify the types your user stories could be estimated to p.admin-subtitle(translate="ADMIN.PROJECT_VALUES_TYPES.SUBTITLE")
div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl", div.admin-attributes-section(tg-project-values, ng-controller="ProjectValuesController as ctrl",
ng-init="section='admin'; resource='issues'; type='issue-types'; sectionName='Issue types'; objName='type'", ng-init="section='admin'; resource='issues'; sectionName='ADMIN.PROJECT_VALUES_TYPES.ISSUE_TITLE'; type='issue-types'; objName='type'",
type="issue-types") type="issue-types")
include ../includes/modules/admin/project-types include ../includes/modules/admin/project-types

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper.roles(ng-controller="RolesController as ctrl", div.wrapper.roles(ng-controller="RolesController as ctrl",
ng-init="section='admin'", tg-roles) ng-init="section='admin'", tg-roles)
sidebar.menu-secondary.sidebar(tg-admin-navigation="roles") sidebar.menu-secondary.sidebar(tg-admin-navigation="roles")
@ -9,29 +11,28 @@ div.wrapper.roles(ng-controller="RolesController as ctrl",
.header-with-actions .header-with-actions
include ../includes/components/mainTitle include ../includes/components/mainTitle
.action-buttons(ng-if="!role.external_user") .action-buttons(ng-if="!role.external_user")
a.button-red.delete-role(href="", title="Delete", ng-click="ctrl.delete()") a.button-red.delete-role(href="", title="{{'COMMON.DELETE' | translate}}", ng-click="ctrl.delete()")
span Delete span(translate="COMMON.DELETE")
div(ng-if="!role.external_user") div(ng-if="!role.external_user")
div(tg-edit-role) div(tg-edit-role)
.edit-role .edit-role
input(type="text", value="{{ role.name }}") input(type="text", value="{{ role.name }}")
a.save.icon.icon-floppy(href="", title="Save") a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}")
p.total p.total
span.role-name(title="{{ role.members_count }} members with this role") {{ role.name }} span.role-name(title="{{'ADMIN.ROLES.COUNT_MEMBERS' | translate}}") {{ role.name }}
a.edit-value.icon.icon-edit a.edit-value.icon.icon-edit
div.any-computable-role(ng-hide="anyComputableRole") Be careful, no role in your project will be able to estimate the point value for user stories div.any-computable-role(ng-hide="anyComputableRole", translate="ADMIN.ROLES.WARNING_NO_ROLE")
div.general-category div.general-category(translate="ADMIN.ROLES.HELP_ROLE_ENABLED")
| When enabled, members assigned to this role will be able to estimate the point value for user stories
div.check div.check
input(type="checkbox", ng-model="role.computable", ng-change="ctrl.setComputable()") input(type="checkbox", ng-model="role.computable", ng-change="ctrl.setComputable()")
div div
span.check-text.check-yes Yes span.check-text.check-yes(translate="COMMON.YES")
span.check-text.check-no No span.check-text.check-no(translate="COMMON.NO")
div(ng-if="role.external_user") div(ng-if="role.external_user")
p.total p.total

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper.roles(tg-bitbucket-webhooks, ng-controller="BitbucketController as ctrl", div.wrapper.roles(tg-bitbucket-webhooks, ng-controller="BitbucketController as ctrl",
ng-init="section='admin'") ng-init="section='admin'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties") sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties")
@ -10,25 +12,25 @@ div.wrapper.roles(tg-bitbucket-webhooks, ng-controller="BitbucketController as c
form form
fieldset fieldset
label(for="secret-key") Secret key label(for="secret-key", translate="ADMIN.THIRD_PARTIES.SECRET_KEY")
input(type="text", name="secret-key", ng-model="bitbucket.secret", placeholder="Secret key", id="secret-key") input(type="text", name="secret-key", ng-model="bitbucket.secret", placeholder="{{'ADMIN.THIRD_PARTIES.SECRET_KEY' | translate}}", id="secret-key")
fieldset fieldset
.select-input-text(tg-select-input-text) .select-input-text(tg-select-input-text)
div div
label(for="payload-url") Payload URL label(for="payload-url", translate="ADMIN.THIRD_PARTIES.PAYLOAD_URL")
.field-with-option .field-with-option
input(type="text", ng-model="bitbucket.webhooks_url", name="payload-url", readonly="readonly", placeholder="Payload URL", id="payload-url") input(type="text", ng-model="bitbucket.webhooks_url", name="payload-url", readonly="readonly", placeholder="{{'ADMIN.THIRD_PARTIES.PAYLOAD_URL' | translate}}", id="payload-url")
.option-wrapper.select-input-content .option-wrapper.select-input-content
.icon.icon-copy .icon.icon-copy
.help-copy Copy to clipboard: Ctrl+C .help-copy(translate="COMMON.COPY_TO_CLIPBOARD")
fieldset fieldset
label(for="valid-origin-ips") Valid origin ips (separated by ,) label(for="valid-origin-ips", translate="ADMIN.THIRD_PARTIES.VALID_IPS")
input(type="text", name="valid-origin-ips", tg-valid-origin-ips, ng-model="bitbucket.valid_origin_ips", placeholder="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.", id="valid-origin-ips") input(type="text", name="valid-origin-ips", tg-valid-origin-ips, ng-model="bitbucket.valid_origin_ips", placeholder="{{'ADMIN.BITBUCKET.INFO_VERIFYING_IP' | translate}}", id="valid-origin-ips")
button.button-green.submit-button(type="submit", title="Save") Save button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", translate="COMMON.SAVE")
a.help-button(href="https://taiga.io/support/bitbucket-integration/", target="_blank") a.help-button(href="https://taiga.io/support/bitbucket-integration/", target="_blank")
span.icon.icon-help span.icon.icon-help
span Do you need help? Check out our support page! span(translate="ADMIN.HELP")

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl", div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl",
ng-init="section='admin'") ng-init="section='admin'")
sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties") sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties")
@ -10,21 +12,21 @@ div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl",
form form
fieldset fieldset
label(for="secret-key") Secret key label(for="secret-key", translate="ADMIN.THIRD_PARTIES.SECRET_KEY")
input(type="text", name="secret-key", ng-model="github.secret", placeholder="Secret key", id="secret-key") input(type="text", name="secret-key", ng-model="github.secret", placeholder="{{'ADMIN.THIRD_PARTIES.SECRET_KEY' | translate}}", id="secret-key")
fieldset fieldset
.select-input-text(tg-select-input-text) .select-input-text(tg-select-input-text)
div div
label(for="payload-url") Payload URL label(for="payload-url", translate="ADMIN.THIRD_PARTIES.PAYLOAD_URL")
.field-with-option .field-with-option
input(type="text", ng-model="github.webhooks_url", name="payload-url", readonly="readonly", placeholder="Payload URL", id="payload-url") input(type="text", ng-model="github.webhooks_url", name="payload-url", readonly="readonly", placeholder="{{'ADMIN.THIRD_PARTIES.PAYLOAD_URL' | translate}}", id="payload-url")
.option-wrapper.select-input-content .option-wrapper.select-input-content
.icon.icon-copy .icon.icon-copy
.help-copy Copy to clipboard: Ctrl+C .help-copy(translate="COMMON.COPY_TO_CLIPBOARD")
button.button-green.submit-button(type="submit", title="Save") Save button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}")
a.help-button(href="https://taiga.io/support/github-integration/", target="_blank") a.help-button(href="https://taiga.io/support/github-integration/", target="_blank")
span.icon.icon-help span.icon.icon-help
span Do you need help? Check out our support page! span(translate="ADMIN.HELP")

View File

@ -1,38 +1,36 @@
block head doctype html
title Taiga Your agile, free, and open source project management tool
block content div.wrapper.roles(tg-gitlab-webhooks, ng-controller="GitlabController as ctrl",
div.wrapper.roles(tg-gitlab-webhooks, ng-controller="GitlabController as ctrl", ng-init="section='admin'")
ng-init="section='admin'") sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties")
sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties") include ../includes/modules/admin-menu
include ../includes/modules/admin-menu sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-gitlab")
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-gitlab") include ../includes/modules/admin-submenu-third-parties
include ../includes/modules/admin-submenu-third-parties
section.main.admin-common.admin-third-parties section.main.admin-common.admin-third-parties
include ../includes/components/mainTitle include ../includes/components/mainTitle
form form
fieldset fieldset
label(for="secret-key") Secret key label(for="secret-key", translate="ADMIN.THIRD_PARTIES.SECRET_KEY")
input(type="text", name="secret-key", ng-model="gitlab.secret", placeholder="Secret key", id="secret-key") input(type="text", name="secret-key", ng-model="gitlab.secret", placeholder="{{'ADMIN.THIRD_PARTIES.SECRET_KEY' | translate}}", id="secret-key")
fieldset fieldset
.select-input-text(tg-select-input-text) .select-input-text(tg-select-input-text)
div div
label(for="payload-url") Payload URL label(for="payload-url", translate="ADMIN.THIRD_PARTIES.PAYLOAD_URL")
.field-with-option .field-with-option
input(type="text", ng-model="gitlab.webhooks_url", name="payload-url", readonly="readonly", placeholder="Payload URL", id="payload-url") input(type="text", ng-model="gitlab.webhooks_url", name="payload-url", readonly="readonly", placeholder="{{'ADMIN.THIRD_PARTIES.PAYLOAD_URL' | translate}}", id="payload-url")
.option-wrapper.select-input-content .option-wrapper.select-input-content
.icon.icon-copy .icon.icon-copy
.help-copy Copy to clipboard: Ctrl+C .help-copy(translate="COMMON.COPY_TO_CLIPBOARD")
fieldset fieldset
label(for="valid-origin-ips") Valid origin ips (separated by ,) label(for="valid-origin-ips", translate="ADMIN.THIRD_PARTIES.VALID_IPS")
input(type="text", name="valid-origin-ips", tg-valid-origin-ips, ng-model="gitlab.valid_origin_ips", placeholder="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.", id="valid-origin-ips") input(type="text", name="valid-origin-ips", tg-valid-origin-ips, ng-model="gitlab.valid_origin_ips", placeholder="{{'ADMIN.GITLAB.INFO_VERIFYING_IP' | translate}}", id="valid-origin-ips")
button.button-green.submit-button(type="submit", title="Save") Save button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", translate="COMMON.SAVE")
a.help-button(href="https://taiga.io/support/gitlab-integration/", target="_blank") a.help-button(href="https://taiga.io/support/gitlab-integration/", target="_blank")
span.icon.icon-help span.icon.icon-help
span Do you need help? Check out our support page! span(translate="ADMIN.HELP")

View File

@ -1,99 +1,97 @@
block head doctype html
title Taiga Your agile, free, and open source project management tool
block content div.wrapper.roles(ng-controller="WebhooksController as ctrl",
div.wrapper.roles(ng-controller="WebhooksController as ctrl", ng-init="section='admin'")
ng-init="section='admin'") sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties")
sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties") include ../includes/modules/admin-menu
include ../includes/modules/admin-menu sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-webhooks")
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-webhooks") include ../includes/modules/admin-submenu-third-parties
include ../includes/modules/admin-submenu-third-parties
section.main.admin-common.admin-webhooks(tg-new-webhook) section.main.admin-common.admin-webhooks(tg-new-webhook)
include ../includes/components/mainTitle include ../includes/components/mainTitle
p.admin-subtitle Webhooks notify external services about events in Taiga, like comments, user stories.... p.admin-subtitle(translate="ADMIN.WEBHOOKS.SUBTITLE")
div.webhooks-options div.webhooks-options
a.button-green.hidden.add-webhook(href="",title="Add a New Webhook") Add Webhook a.button-green.hidden.add-webhook(href="", title="{{'ADMIN.WEBHOOKS.ADD_NEW' | translate}}", translate="ADMIN.WEBHOOKS.ADD_NEW")
section.webhooks-table.basic-table section.webhooks-table.basic-table
div.table-header div.table-header
div.row div.row
div.webhook-service Name div.webhook-service(translate="COMMON.FIELDS.NAME")
div.webhook-url URL div.webhook-url(translate="COMMON.FIELDS.URL")
div.webhook-options div.webhook-options
div.table-body div.table-body
div.single-webhook-wrapper(tg-webhook="webhook", ng-repeat="webhook in webhooks") div.single-webhook-wrapper(tg-webhook="webhook", ng-repeat="webhook in webhooks")
div.edition-mode.hidden div.edition-mode.hidden
form.row form.row
fieldset.webhook-service fieldset.webhook-service
input(type="text", name="name", placeholder="Type the service name", data-required="true", ng-model="webhook.name") input(type="text", name="name", placeholder="{{'ADMIN.WEBHOOKS.TYPE_NAME' | translate}}", data-required="true", ng-model="webhook.name")
div.webhook-url div.webhook-url
div.webhook-url-inputs div.webhook-url-inputs
fieldset fieldset
input(type="text", name="url", data-type="url", placeholder="Type the service payload url", data-required="true", ng-model="webhook.url") input(type="text", name="url", data-type="url", placeholder="{{'ADMIN.WEBHOOKS.TYPE_PAYLOAD_URL' | translate}}", data-required="true", ng-model="webhook.url")
fieldset fieldset
input(type="text", name="key", placeholder="Type the service secret key", data-required="true", ng-model="webhook.key") input(type="text", name="key", placeholder="{{'ADMIN.WEBHOOKS.TYPE_SERVICE_SECRET' | translate}}", data-required="true", ng-model="webhook.key")
div.webhook-options div.webhook-options
a.edit-existing.icon.icon-floppy(href="", title="Save Webhook") a.edit-existing.icon.icon-floppy(href="", title="{{'ADMIN.WEBHOOKS.SAVE' | translate}}")
a.cancel-existing.icon.icon-delete(href="", title="Cancel Webhook") a.cancel-existing.icon.icon-delete(href="", title="{{'ADMIN.WEBHOOKS.CANCEL' | translate}}")
div.visualization-mode div.visualization-mode
div.row div.row
div.webhook-service div.webhook-service
span(ng-bind="webhook.name") span(ng-bind="webhook.name")
div.webhook-url div.webhook-url
span(ng-bind="webhook.url") span(ng-bind="webhook.url")
a.show-history.toggle-history(href="", title="Toggle history", ng-show="webhook.logs_counter") (Show history) a.show-history.toggle-history(href="", title="{{'ADMIN.WEBHOOKS.TOOGLE_HISTORY' | translate}}", ng-show="webhook.logs_counter", translate="ADMIN.WEBHOOKS.SHOW_HISTORY")
div.webhook-options div.webhook-options
div.webhook-options-wrapper div.webhook-options-wrapper
a.test-webhook.icon.icon-check-square(href="", title="Test Webhook") a.test-webhook.icon.icon-check-square(href="", title="{{'ADMIN.WEBHOOKS.TEST' | translate}}")
a.edit-webhook.icon.icon-edit(href="", title="Edit Webhook") a.edit-webhook.icon.icon-edit(href="", title="{{'ADMIN.WEBHOOKS.EDIT' | translate}}")
a.delete-webhook.icon.icon-delete(href="", title="Delete Webhook") a.delete-webhook.icon.icon-delete(href="", title="{{'ADMIN.WEBHOOKS.DELETE' | translate}}")
div.webhooks-history(ng-show="webhook.logs") div.webhooks-history(ng-show="webhook.logs")
div.history-single-wrapper(ng-repeat="log in webhook.logs") div.history-single-wrapper(ng-repeat="log in webhook.logs")
div.history-single div.history-single
div div
span.history-response-icon(ng-class="log.validStatus ? 'history-success' : 'history-error'", title="{{log.status}}") span.history-response-icon(ng-class="log.validStatus ? 'history-success' : 'history-error'", title="{{log.status}}")
span.history-date(ng-bind="log.prettyDate") span.history-date(ng-bind="log.prettyDate")
span.toggle-log.icon.icon-arrow-bottom span.toggle-log.icon.icon-arrow-bottom
div.history-single-response div.history-single-response
div.history-single-request-header div.history-single-request-header
span Request span(translate="ADMIN.WEBHOOKS.REQUEST")
a.resend-request(href="", title="Resend request", data-log="{{log.id}}") a.resend-request(href="", title="{{'ADMIN.WEBHOOKS.RESEND_REQUEST' | translate}}", data-log="{{log.id}}")
span.icon.icon-reload span.icon.icon-reload
span Resend request span(translate="ADMIN.WEBHOOKS.RESEND_REQUEST")
div.history-single-request-body div.history-single-request-body
div.response-container div.response-container
span.response-title Headers span.response-title(translate="ADMIN.WEBHOOKS.HEADERS")
textarea(name="headers", ng-bind="log.prettySentHeaders") textarea(name="headers", ng-bind="log.prettySentHeaders")
div.response-container div.response-container
span.response-title Payload span.response-title(translate="ADMIN.WEBHOOKS.PAYLOAD")
textarea(name="payload", ng-bind="log.prettySentData") textarea(name="payload", ng-bind="log.prettySentData")
div.history-single-response-header div.history-single-response-header
span Response span(translate="ADMIN.WEBHOOKS.RESPONSE")
div.history-single-response-body div.history-single-response-body
div.response-container div.response-container
textarea(name="response-data", ng-bind="log.response_data") textarea(name="response-data", ng-bind="log.response_data")
form.new-webhook-form.row.hidden form.new-webhook-form.row.hidden
fieldset.webhook-service fieldset.webhook-service
input(type="text", name="name", placeholder="Type the service name", data-required="true", ng-model="newValue.name") input(type="text", name="name", placeholder="{{'ADMIN.WEBHOOKS.TYPE_NAME' | translate}}", data-required="true", ng-model="newValue.name")
div.webhook-url div.webhook-url
div.webhook-url-inputs div.webhook-url-inputs
fieldset fieldset
input(type="text", name="url", data-type="url", placeholder="Type the service payload url", data-required="true", ng-model="newValue.url") input(type="text", name="url", data-type="url", placeholder="{{'ADMIN.WEBHOOKS.TYPE_PAYLOAD_URL' | translate}}", data-required="true", ng-model="newValue.url")
fieldset fieldset
input(type="text", name="key", placeholder="Type the service secret key", data-required="true", ng-model="newValue.key") input(type="text", name="key", placeholder="{{'ADMIN.WEBHOOKS.TYPE_SERVICE_SECRET' | translate}}", data-required="true", ng-model="newValue.key")
div.webhook-options div.webhook-options
a.add-new.icon.icon-floppy(href="", title="Save Webhook") a.add-new.icon.icon-floppy(href="", title="{{'ADMIN.WEBHOOKS.SAVE' | translate}}")
a.cancel-new.icon.icon-delete(href="", title="Cancel Webhook") a.cancel-new.icon.icon-delete(href="", title="{{'ADMIN.WEBHOOKS.CANCEL' | translate}}")
a.help-button(href="https://taiga.io/support/webhooks/", target="_blank") a.help-button(href="https://taiga.io/support/webhooks/", target="_blank")
span.icon.icon-help span.icon.icon-help
span Do you need help? Check out our support page! span(translate="ADMIN.HELP")

View File

@ -0,0 +1,16 @@
section.project-csv(tg-select-input-text)
div.project-values-title
h2(translate="ADMIN.CSV.TITLE", translate-values='{ csvType: csvType}')
a.button.button-gray(title="{{'ADMIN.CSV.DOWNLOAD' | translate}}", ng-href="{{csvUrl}}", ng-show="csvUrl", target="_blank")
span(translate="ADMIN.CSV.DOWNLOAD")
div.csv-regenerate-field
.field-with-options
input(type="text", placeholder="{{'ADMIN.CSV.URL_FIELD_PLACEHOLDER' | translate}}", readonly, ng-model="csvUrl")
.option-wrapper.select-input-content
.icon.icon-copy
a(href="", title="{{'ADMIN.CSV.TITLE_REGENERATE_URL' | translate}}", ng-click="ctrl.regenerateUuid()")
span.icon.icon-plus(ng-hide="csvUrl")
span(ng-hide="csvUrl", translate="ADMIN.CSV.ACTION_GENERATE_URL")
span.icon.icon-reload(ng-Show="csvUrl")
span(ng-Show="csvUrl", translate="ADMIN.CSV.ACTION_REGENERATE")

View File

@ -1,19 +1,19 @@
.attachment-name .attachment-name
span.icon.icon-document span.icon.icon-document
a(href!="<%- url %>", title!="<%- name %> uploaded on <%- created_date %>", target="_blank") a(href!="<%- url %>", title!="{{ 'ATTACHMENT.TITLE' | translate}}", target="_blank")
| <%- name %> | <%- name %>
.attachment-size .attachment-size
span <%- size %> span <%- size %>
.editable.editable-attachment-comment .editable.editable-attachment-comment
input(type="text", name="description", maxlength="140", input(type="text", name="description", maxlength="140",
value!="<%- description %>", placeholder="Type a short description") value!="<%- description %>", placeholder="{{'ATTACHMENT.DESCRIPTION' | translate}}")
.editable.editable-attachment-deprecated .editable.editable-attachment-deprecated
input(type="checkbox", name="is-deprecated", input(type="checkbox", name="is-deprecated",
id!="attach-<%- id %>-is-deprecated") id!="attach-<%- id %>-is-deprecated")
label(for!="attach-<%- id %>-is-deprecated") Deprecated? label(for!="attach-<%- id %>-is-deprecated", translate="{{'ATTACHMENT.DEPRECATED_FILE' | translate}}")
.attachment-settings .attachment-settings
a.editable-settings.icon.icon-floppy(href="", title="Save") a.editable-settings.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}")
a.editable-settings.icon.icon-delete(href="", title="Cancel") a.editable-settings.icon.icon-delete(href="", title="{{'COMMON.CANCEL' | translate}}")

View File

@ -1,5 +1,5 @@
.attachment-name .attachment-name
a(href!="<%- url %>", title!="<%- name %> uploaded on <%- created_date %>", target="_blank") a(href!="<%- url %>", title!="{{ 'ATTACHMENT.TITLE' | translate}}", target="_blank")
span.icon.icon-documents span.icon.icon-documents
span <%- name %> span <%- name %>
.attachment-size .attachment-size
@ -7,13 +7,13 @@
.attachment-comments .attachment-comments
<% if (isDeprecated){ %> <% if (isDeprecated){ %>
span.deprecated-file (deprecated) span.deprecated-file {{ 'ATTACHMENT.DEPRECATED' | translate}}
<% } %> <% } %>
span <%- description %> span <%- description %>
<% if (modifyPermission) {%> <% if (modifyPermission) {%>
.attachment-settings .attachment-settings
a.settings.icon.icon-edit(href="", title="Edit") a.settings.icon.icon-edit(href="", title="{{'COMMON.EDIT' | translate}}")
a.settings.icon.icon-delete(href="", title="Delete") a.settings.icon.icon-delete(href="", title="{{'COMMON.DELETE' | translate}}")
a.settings.icon.icon-drag-v(href="", title="Drag") a.settings.icon.icon-drag-v(href="", title="{{'COMMON.DRAG' | translate}}")
<% } %> <% } %>

View File

@ -2,10 +2,10 @@ section.attachments
.attachments-header .attachments-header
h3.attachments-title h3.attachments-title
span.attachments-num(tg-bind-html="ctrl.attachmentsCount") span.attachments-num(tg-bind-html="ctrl.attachmentsCount")
span.attachments-text attachments span.attachments-text(translate="ATTACHMENT.SECTION_NAME")
.add-attach(tg-check-permission!="modify_<%- type %>", title!="Add new attachment. <%- maxFileSizeMsg %>") .add-attach(tg-check-permission!="modify_<%- type %>", title!="{{'ATTACHMENT.ADD' | translate}}")
<% if (maxFileSize){ %> <% if (maxFileSize){ %>
span.size-info.hidden [Max. size: <%- maxFileSize %>] span.size-info.hidden(translate="ATTACHMENT.MAX_FILE_SIZE", translate-values!="{ 'maxFileSize': '<%- maxFileSize %>'}")
<% }; %> <% }; %>
label(for="add-attach", class="icon icon-plus related-tasks-buttons") label(for="add-attach", class="icon icon-plus related-tasks-buttons")
input(id="add-attach", type="file", multiple="multiple") input(id="add-attach", type="file", multiple="multiple")
@ -22,9 +22,7 @@ section.attachments
span(ng-bind="file.progressMessage") span(ng-bind="file.progressMessage")
.percentage(ng-style="{'width': file.progressPercent}") .percentage(ng-style="{'width': file.progressPercent}")
a.more-attachments(href="", title="show deprecated atachments", ng-if="ctrl.deprecatedAttachmentsCount > 0") a.more-attachments(href="", title="{{'ATTACHMENT.SHOW_DEPRECATED' | translate}}", ng-if="ctrl.deprecatedAttachmentsCount > 0")
span.text(data-type="show") + show deprecated atachments span.text(data-type="show", translate="ATTACHMENT.SHOW_DEPRECATED")
span.text.hidden(data-type="hide") span.text.hidden(data-type="hide", translate="ATTACHMENT.HIDE_DEPRECATED")
| - hide deprecated atachments span.more-attachments-num(translate="ATTACHMENT.COUNT_DEPRECATED")
span.more-attachments-num
| ({{ctrl.deprecatedAttachmentsCount }} deprecated)

View File

@ -1,8 +1,10 @@
doctype html
div.wrapper div.wrapper
div.login-main div.login-main
div.login-container div.login-container
h1.logo h1.logo
img.logo-svg(src="/svg/logo.svg", alt="TAIGA") img.logo-svg(src="/svg/logo.svg", alt="TAIGA")
p.tagline Your agile, free, and open source project management tool p.tagline(translate="COMMON.TAG_LINE")
include ../includes/modules/change-password-from-recovery-form include ../includes/modules/change-password-from-recovery-form

View File

@ -1,9 +1,11 @@
doctype html
include ../includes/components/beta include ../includes/components/beta
div.wrapper div.wrapper
div.login-main div.login-main
div.login-container div.login-container
img.logo-svg(src="/svg/logo.svg", alt="TAIGA") img.logo-svg(src="/svg/logo.svg", alt="TAIGA")
h1.logo Taiga h1.logo Taiga
h2.tagline LOVE YOUR PROJECT h2.tagline(translate="COMMON.TAG_LINE_2")
include ../includes/modules/forgot-form include ../includes/modules/forgot-form

View File

@ -1,3 +1,5 @@
doctype html
div.wrapper div.wrapper
div.invitation-main div.invitation-main
div.invitation-container(tg-invitation) div.invitation-container(tg-invitation)
@ -8,7 +10,7 @@ div.wrapper
span.person-name(tg-bo-bind="invitation.invited_by.full_name_display") span.person-name(tg-bo-bind="invitation.invited_by.full_name_display")
span.invitation-text span.invitation-text
p has invited you to join the project p(translate="AUTH.INVITED_YOU")
p.project-name(tg-bo-bind="invitation.project_name") p.project-name(tg-bo-bind="invitation.project_name")
div.invitation-form div.invitation-form

View File

@ -1,3 +1,3 @@
p.login-text p.login-text
span Not registered yet? span(translate="AUTH.NOT_REGISTERED_YET")
a(href!='<%- url %>', tg-nav='register', title='Register') create your free account here a(href!='<%- url %>', tg-nav='register', title='{{"AUTH.REGISTER" | translate}}', translate="AUTH.CREATE_ACCOUNT")

View File

@ -1,9 +1,11 @@
doctype html
include ../includes/components/beta include ../includes/components/beta
div.wrapper div.wrapper
div.login-main div.login-main
div.login-container div.login-container
img.logo-svg(src="/svg/logo.svg", alt="TAIGA") img.logo-svg(src="/svg/logo.svg", alt="TAIGA")
h1.logo Taiga h1.logo Taiga
h2.tagline LOVE YOUR PROJECT h2.tagline(translate="COMMON.TAG_LINE_2")
include ../includes/modules/login-form include ../includes/modules/login-form

View File

@ -1,8 +1,10 @@
doctype html
div.wrapper div.wrapper
div.login-main div.login-main
div.login-container div.login-container
img.logo-svg(src="/svg/logo.svg", alt="TAIGA") img.logo-svg(src="/svg/logo.svg", alt="TAIGA")
h1.logo Taiga h1.logo Taiga
h2.tagline LOVE YOUR PROJECT h2.tagline(translate="COMMON.TAG_LINE_2")
include ../includes/modules/register-form include ../includes/modules/register-form

View File

@ -1,5 +1,8 @@
doctype html
div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl", div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl",
ng-init="section='backlog'") ng-init="section='backlog'")
sidebar.menu-secondary.extrabar.filters-bar(tg-backlog-filters) sidebar.menu-secondary.extrabar.filters-bar(tg-backlog-filters)
include ../includes/modules/backlog-filters include ../includes/modules/backlog-filters
section.main.backlog section.main.backlog
@ -10,23 +13,22 @@ div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl",
include ../includes/modules/burndown include ../includes/modules/burndown
div.backlog-menu div.backlog-menu
div.backlog-table-options div.backlog-table-options
a.trans-button.move-to-current-sprint(href="", title="Move to Current Sprint", a.trans-button.move-to-current-sprint(href="", title="{{'BACKLOG.MOVE_US_TO_CURRENT_SPRINT' | translate}}", id="move-to-current-sprint")
id="move-to-current-sprint")
span.icon.icon-move span.icon.icon-move
span.text Move to current Sprint span.text(translate="BACKLOG.MOVE_US_TO_CURRENT_SPRINT")
a.trans-button(href="", title="Show Filters", id="show-filters-button") a.trans-button(href="", title="{{'BACKLOG.SHOW_FILTERS' | translate}}", id="show-filters-button")
span.icon.icon-filter span.icon.icon-filter
span.text Show Filters span.text(translate="BACKLOG.SHOW_FILTERS") Show Filters
a.trans-button(href="", title="Show Tags", id="show-tags") a.trans-button(href="", title="{{'BACKLOG.SHOW_TAGS' | translate}}", id="show-tags")
span.icon.icon-tag span.icon.icon-tag
span.text Show Tags span.text(translate="BACKLOG.SHOW_TAGS")
include ../includes/components/addnewus include ../includes/components/addnewus
section.backlog-table(ng-class="{'hidden': !visibleUserstories.length}") section.backlog-table(ng-class="{'hidden': !visibleUserstories.length}")
include ../includes/modules/backlog-table include ../includes/modules/backlog-table
div.empty.empty-backlog(ng-class="{'hidden': visibleUserstories.length}", tg-backlog-empty-sortable) div.empty.empty-backlog(ng-class="{'hidden': visibleUserstories.length}", tg-backlog-empty-sortable)
span.icon.icon-backlog span.icon.icon-backlog
span.title Your backlog is empty! span.title(translate="BACKLOG.EMPTY")
a(href="", title+"Create a new US", ng-click="ctrl.addNewUs('standard')", tg-check-permission="add_us") You may want to create a new user story a(href="", title="{{'BACKLOG.CREATE_NEW_US' | translate}}", ng-click="ctrl.addNewUs('standard')", tg-check-permission="add_us", translate="BACKLOG.CREATE_NEW_US_EMPTY_HELP")
sidebar.menu-secondary.sidebar sidebar.menu-secondary.sidebar
include ../includes/modules/sprints include ../includes/modules/sprints

View File

@ -1,3 +1,3 @@
.defined-points(title="Excess of points") .defined-points(title="{{'BACKLOG.EXCESS_OF_POINTS' | translate}}")
.project-points-progress(title="Pending Points", style!="width: <%- projectPointsPercentaje %>%") .project-points-progress(title="{{'BACKLOG.PENDING_POINTS' | translate}}", style!="width: <%- projectPointsPercentaje %>%")
.closed-points-progress(title="Closed points", style!="width: <%- closedPointsPercentaje %>%") .closed-points-progress(title="{{'BACKLOG.CLOSED_POINTS' | translate}}", style!="width: <%- closedPointsPercentaje %>%")

View File

@ -1,20 +1,16 @@
.sprint-name .sprint-name
a.icon.icon-arrow-up(href="", title="Compact Sprint") a.icon.icon-arrow-up(href="", title="{{'BACKLOG.COMPACT_SPRINT' | translate}}")
<% if(isVisible){ %> a(ng-if="::isVisible", href="{{::taskboardUrl}}", title="{{'BACKLOG.GO_TO_TASKBOARD' | translate}}")
a(href!="<%- taskboardUrl %>", title!="'Go to the taskboard of '<%- name %>'") span {{::name}}
span <%- name %>
<% } %>
<% if(isEditable){ %> a.icon.icon-edit(ng-if="::isEditable", href="", title="{{'BACKLOG.EDIT_SPRINT' | translate}}")
a.icon.icon-edit(href="", title="Edit Sprint")
<% } %>
.sprint-summary .sprint-summary
.sprint-date <%- estimatedDateRange %> .sprint-date {{::estimatedDateRange}}
ul ul
li li
span.number <%- closedPoints %> span.number {{::closedPoints}}
span.description closed span.description(translate="BACKLOG.CLOSED_POINTS")
li li
span.number <%- totalPoints %> span.number {{::totalPoints}}
span.description total span.description(translate="BACKLOG.TOTAL_POINTS")

View File

@ -1,6 +1,6 @@
ul.popover.pop-role ul.popover.pop-role
li li
a.clear-selection(href="", title="All") All a.clear-selection(href="", title="{{'COMMON.ROLES.ALL' | translate}}", translate="COMMON.ROLES.ALL")
<% _.each(roles, function(role) { %> <% _.each(roles, function(role) { %>
li li
a(href="", class="role", title!="<%- role.name %>", data-role-id!="<%- role.id %>") a(href="", class="role", title!="<%- role.name %>", data-role-id!="<%- role.id %>")

View File

@ -4,18 +4,18 @@
<% } %> <% } %>
.assigned-to .assigned-to
span.assigned-title Assigned to span.assigned-title(translate="COMMON.FIELDS.ASSIGNED_TO")
a(href="" title="edit assignment", class!="user-assigned <% if(isEditable){ %>editable<% }; %>") a(href="" title="edit assignment", class!="user-assigned <% if(isEditable){ %>editable<% }; %>")
span.assigned-name span.assigned-name
<% if (assignedTo) { %> <% if (assignedTo) { %>
<%- assignedTo.full_name_display %> <%- assignedTo.full_name_display %>
<% } else { %> <% } else { %>
| Not assigned | {{'COMMON.FIELDS.ASSIGNED_TO' | translate}}
<% } %> <% } %>
<% if(isEditable){ %> <% if(isEditable){ %>
span.icon.icon-arrow-bottom span.icon.icon-arrow-bottom
<% }; %> <% }; %>
<% if (assignedTo!==null && isEditable) { %> <% if (assignedTo!==null && isEditable) { %>
a.icon.icon-delete(href="" title="delete assignment") a.icon.icon-delete(href="" title="{{'COMMON.ASSIGNED_TO.DELETE_ASSIGNMENT' | translate}}")
<% } %> <% } %>

View File

@ -1,4 +1,4 @@
a(href="#", class="button button-gray item-block") a(href="#", class="button button-gray item-block")
span Block span(translate="COMMON.BLOCK")
a(href="#", class="button button-red item-unblock") a(href="#", class="button button-red item-unblock")
span Unblock span(translate="COMMON.UNBLOCK")

View File

@ -2,7 +2,6 @@
img(src!="<%- owner.photo %>", alt!="<%- owner.full_name_display %>") img(src!="<%- owner.photo %>", alt!="<%- owner.full_name_display %>")
.created-by .created-by
span.created-title span.created-title(translate="COMMON.CREATED_BY", translate-values!="{ 'fullDisplayName': '<%- owner.full_name_display %>'}")
| Created by <%- owner.full_name_display %>
span.created-date span.created-date
| <%- date %> | <%- date %>

View File

@ -1,2 +1,2 @@
a(href="", class="button button-red") a(href="", class="button button-red")
span Delete span(translate="COMMON.DELETE")

View File

@ -1,2 +1 @@
p.no-description.editable p.no-description.editable(translate="COMMON.DESCRIPTION.EMPTY")
| Empty space is so boring... go on be descriptive... A rose by any other name would smell as sweet...

View File

@ -1 +1 @@
p.no-description No description yet. p.no-description(translate="COMMON.NO_DESCRIPTION")

View File

@ -3,9 +3,9 @@
span.edit.icon.icon-edit span.edit.icon.icon-edit
.edit-description .edit-description
textarea(placeholder="Empty space is so boring... go on be descriptive... A rose by any other name would smell as sweet...", ng-model="item.description", tg-markitup="tg-markitup") textarea(placeholder="{{'COMMON.DESCRIPTION.EMPTY' | translate}}", ng-model="item.description", tg-markitup="tg-markitup")
a.help-markdown(href="https://taiga.io/support/taiga-markdown-syntax/", target="_blank", title="Mardown syntax help") a.help-markdown(href="https://taiga.io/support/taiga-markdown-syntax/", target="_blank", title="{{'COMMON.MARKDOWN_HELP' | translate}}")
span.icon.icon-help span.icon.icon-help
span Markdown syntax help span(translate="COMMON.MARKDOWN_HELP")
span.save-container span.save-container
a.save.icon.icon-floppy(href="", title="Save") a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}")

View File

@ -1,7 +1,7 @@
.view-subject .view-subject
| {{ item.subject }} | {{ item.subject }}
a.edit.icon.icon-edit(href="" title="Edit") a.edit.icon.icon-edit(href="" title="{{'COMMON.EDIT' | translate}}")
.edit-subject .edit-subject
input(type="text", ng-model="item.subject", data-required="true", data-maxlength="500") input(type="text", ng-model="item.subject", data-required="true", data-maxlength="500")
span.save-container span.save-container
a.save.icon.icon-floppy(href="", title="Save") a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}")

View File

@ -1,2 +1,4 @@
span.project-name <%- projectName %> span.project-name
span.green <%- sectionName %> | {{ projectName }}
span.green
| {{ sectionName }}

View File

@ -1,9 +1,5 @@
span span(translate="STATUS.OPEN", ng-if="status.is_closed")
<% if (status.is_closed) { %> span(translate="STATUS.CLOSED", ng-if="!status.is_closed")
| Closed
<% } else { %>
| Open
<% } %>
span(class="us-detail-status", style!="color:<%- status.color %>") span(class="us-detail-status", style!="color:<%- status.color %>")
| <%- status.name %> | <%- status.name %>

View File

@ -1,10 +1,10 @@
<% if(isEditable){ %> <% if(isEditable){ %>
.watchers-header .watchers-header
span.title watchers span.title(translate="COMMON.WATCHERS.TITLE")
a.icon.icon-plus.add-watcher(href="", title="Add watcher") a.icon.icon-plus.add-watcher(href="", title="{{'COMMON.WATCHERS.ADD' | translate}}")
<% } else if(watchers.length > 0){ %> <% } else if(watchers.length > 0){ %>
.watchers-header .watchers-header
span.title watchers span.title(translate="COMMON.WATCHERS.TITLE")
<% }; %> <% }; %>
<% _.each(watchers, function(watcher) { %> <% _.each(watchers, function(watcher) { %>
@ -16,7 +16,7 @@
span <%- watcher.full_name_display %> span <%- watcher.full_name_display %>
<% if(isEditable){ %> <% if(isEditable){ %>
a.icon.icon-delete(data-watcher-id!="<%- watcher.id %>" href="" title="delete-watcher") a.icon.icon-delete(data-watcher-id!="<%- watcher.id %>" href="" title="{{'WATCHERS.DELETE' | translate}}")
<% }; %> <% }; %>
<% } %> <% } %>
<% }); %> <% }); %>

View File

@ -1,7 +1,7 @@
ul.points-per-role ul.points-per-role
li.total li.total
span.points <%- totalPoints %> span.points <%- totalPoints %>
span.role total span.role(translate="US.TOTAL_POINTS")
<% _.each(roles, function(role) { %> <% _.each(roles, function(role) { %>
li(class!="total <% if(editable){ %>clickable<% } %>", data-role-id!="<%- role.id %>", title!="<%- role.name %>") li(class!="total <% if(editable){ %>clickable<% } %>", data-role-id!="<%- role.id %>", title!="<%- role.name %>")
span.points <%- role.points %> span.points <%- role.points %>

View File

@ -12,8 +12,7 @@ div(class!="activity-single <%- mode %>")
<% if (comment.length > 0) { %> <% if (comment.length > 0) { %>
<% if ((deleteCommentDate || deleteCommentUser)) { %> <% if ((deleteCommentDate || deleteCommentUser)) { %>
.deleted-comment .deleted-comment
span span(translate="COMMENTS.DELETED_INFO", translate-values!="{ deleteCommentUser: '<%- deleteCommentUser %>', deleteCommentDate: '<% deleteCommentDate %>'}")
| Comment deleted by <%- deleteCommentUser %> on <%- deleteCommentDate %>
<% } %> <% } %>
.comment.wysiwyg .comment.wysiwyg
| <%= comment %> | <%= comment %>
@ -25,7 +24,7 @@ div(class!="activity-single <%- mode %>")
<% if(changes.length > 0) { %> <% if(changes.length > 0) { %>
.changes .changes
<% if (mode != "activity") { %> <% if (mode != "activity") { %>
a.changes-title(href="", title="Show activity") a.changes-title(href="", title="{{'ACTIVITY.SHOW_ACTIVITY' | translate}}")
span <%- changesText %> span <%- changesText %>
span.icon.icon-arrow-up span.icon.icon-arrow-up
<% } %> <% } %>

View File

@ -1,6 +1,5 @@
<% if (showMore > 0) { %> <% if (showMore > 0) { %>
a(href="" title="Show more" class="show-more show-more-comments") a(href="" title="{{ 'ACTIVITY.SHOW_MORE' | translate}}" class="show-more show-more-comments", translate="ACTIVITY.SHOW_MORE", translate-values!="{showMore: '<%- showMore %>'}")
| + Show previous entries (<%- showMore %> more)
<% } %> <% } %>
<% _.each(entries, function(entry) { %> <% _.each(entries, function(entry) { %>
<%= entry %> <%= entry %>

View File

@ -3,21 +3,21 @@ section.history
li li
a(href="#", class="active") a(href="#", class="active")
span.icon.icon-comment span.icon.icon-comment
span.tab-title Comments span.tab-title(translate="COMMENTS.TITLE")
li li
a(href="#") a(href="#")
span.icon.icon-issues span.icon.icon-issues
span.tab-title Activity span.tab-title(translate="ACTIVITY.TITLE")
section.history-comments section.history-comments
.comments-list .comments-list
div(tg-check-permission!="modify_<%- type %>", tg-toggle-comment, class="add-comment") div(tg-check-permission!="modify_<%- type %>", tg-toggle-comment, class="add-comment")
textarea(placeholder="Type a new comment here", ng-model!="<%- ngmodel %>.comment", tg-markitup="tg-markitup") textarea(placeholder="{{'COMMENTS.TYPE_NEW_COMMENT' | translate}}", ng-model!="<%- ngmodel %>.comment", tg-markitup="tg-markitup")
<% if (mode !== "edit") { %> <% if (mode !== "edit") { %>
a(class="help-markdown", href="https://taiga.io/support/taiga-markdown-syntax/", target="_blank", title="Mardown syntax help") a(class="help-markdown", href="https://taiga.io/support/taiga-markdown-syntax/", target="_blank", title="{{'COMMON.DESCRIPTION.MARKDOWN_HELP' | translate}}")
span.icon.icon-help span.icon.icon-help
span Markdown syntax help span(translate="COMMON.DESCRIPTION.MARKDOWN_HELP")
a(href="", title="Comment", class="button button-green save-comment") a(href="", title="{{'COMMENTS.COMMENT' | translate}}", class="button button-green save-comment")
span Comment span(translate="COMMENTS.COMMENT")
<% } %> <% } %>
section.history-activity.hidden section.history-activity.hidden
.changes-list .changes-list

View File

@ -3,10 +3,10 @@
span <%- name %> span <%- name %>
.activity-fromto .activity-fromto
p p
strong from strong(translate="COMMON.FROM")
br br
span <%- from %> span <%- from %>
p p
strong to strong(translate="COMMON.TO")
br br
span <%- to %> span <%- to %>

View File

@ -4,14 +4,14 @@
.activity-fromto .activity-fromto
<% if (removed.length > 0) { %> <% if (removed.length > 0) { %>
p p
strong removed strong(translate="ACTIVITY.REMOVED")
br br
span <%- removed %> span <%- removed %>
<% } %> <% } %>
<% if (added.length > 0) { %> <% if (added.length > 0) { %>
p p
strong added strong(translate="ACTIVITY.ADDED")
br br
span <%- added %> span <%- added %>
<% } %> <% } %>

View File

@ -1,14 +1,14 @@
<% _.each(points, function(point, name) { %> <% _.each(points, function(point, name) { %>
.change-entry .change-entry
.activity-changed .activity-changed
span US points (<%- name.toLowerCase() %>) span(translate="ACTIVITY.US_POINTS", translate-values!="<%- name.toLowerCase() %>")
.activity-fromto .activity-fromto
p p
strong from strong(translate="COMMON.FROM")
br br
span <%- point[0] %> span <%- point[0] %>
p p
strong to strong(translate="COMMON.TO")
br br
span <%- point[1] %> span <%- point[1] %>
<% }); %> <% }); %>

View File

@ -1,11 +1,11 @@
.activity-single.comment.deleted-comment .activity-single.comment.deleted-comment
div div
span Comment deleted by <%- deleteCommentUser %> on <%- deleteCommentDate %> span(translate="COMMENTS.DELETED_INFO", translate-values!="{deleteCommentUser: '<%- deleteCommentUser %>', deleteCommentDate: '<%- deleteCommentDate %>'}")
a(href="", title="Show comment", class="show-deleted-comment") (Show deleted comment) a(href="", title="{{'COMMENTS.SHOW_DELETED' | translate}}", class="show-deleted-comment", translate="COMMENTS.SHOW_DELETED")
a(href="", title="Show comment", class="hide-deleted-comment hidden") (Hide deleted comment)</a> a(href="", title="{{'COMMENTS.HIDE_DELETED' | translate}}", class="hide-deleted-comment hidden", translate="COMMENTS.HIDE_DELETED")
.comment-body.wysiwyg <%= deleteComment %> .comment-body.wysiwyg <%= deleteComment %>
<% if (canRestoreComment) { %> <% if (canRestoreComment) { %>
a(href="", class="comment-restore", data-activity-id!="<%- activityId %>") a(href="", class="comment-restore", data-activity-id!="<%- activityId %>")
span.icon.icon-reload span.icon.icon-reload
span Restore comment span(translate="COMMENTS.RESTORE")
<% } %> <% } %>

View File

@ -1,17 +1,17 @@
<% if (selected) { %> <% if (selected) { %>
.watcher-single.active .watcher-single.active
.watcher-avatar .watcher-avatar
a(href="", title="Assigned to", class="avatar") a(href="", title="{{'COMMON.ASSIGNED_TO' | translate}}", class="avatar")
img(src!="<%- selected.photo %>") img(src!="<%- selected.photo %>")
a(href="", title!="<%- selected.full_name_display %>", class="watcher-name") a(href="", title!="<%- selected.full_name_display %>", class="watcher-name")
| <%-selected.full_name_display %> | <%-selected.full_name_display %>
a(href="", title="Remove assigned", class="icon icon-delete remove-assigned-to") a(href="", title="{{'REMOVE_ASSIGNED' | translate}}", class="icon icon-delete remove-assigned-to")
<% } %> <% } %>
<% _.each(users, function(user) { %> <% _.each(users, function(user) { %>
.watcher-single(data-user-id!="<%- user.id %>") .watcher-single(data-user-id!="<%- user.id %>")
.watcher-avatar .watcher-avatar
a(href="#", title="Assigned to", class="avatar") a(href="#", title="{{'COMMON.ASSIGNED_TO.TITLE' | translate}}", class="avatar")
img(src!="<%- user.photo %>") img(src!="<%- user.photo %>")
a(href="", title!="<%- user.full_name_display %>", class="watcher-name") a(href="", title!="<%- user.full_name_display %>", class="watcher-name")
| <%- user.full_name_display %> | <%- user.full_name_display %>
@ -19,5 +19,5 @@
<% if (showMore) { %> <% if (showMore) { %>
div(ng-show="filteringUsers", class="more-watchers") div(ng-show="filteringUsers", class="more-watchers")
span ...too many users, keep filtering span(translate="COMMON.ASSIGNED_TO.TOO_MANY")
<% } %> <% } %>

View File

@ -1,9 +1,9 @@
a.close(href="", title="close") a.close(href="", title="close")
span.icon.icon-delete span.icon.icon-delete
div.form div.form
h2.title Select assigned to h2.title(translate="LIGHTBOX.ASSIGNED_TO.SELECT")
fieldset fieldset
input(type="text", data-maxlength="500", placeholder="Search for users", ng-model="usersSearch") input(type="text", data-maxlength="500", placeholder="{{'LIGHTBOX.ASSIGNED_TO.SEARCH' | translate}}", ng-model="usersSearch")
//-This block is rendered by the directive //-This block is rendered by the directive
div.watchers div.watchers

View File

@ -1,9 +1,9 @@
a.close(href="", title="close") a.close(href="", title="{{'COMMON.CLOSE' | translate}}")
span.icon.icon-delete span.icon.icon-delete
div.form div.form
h2.title h2.title
fieldset fieldset
textarea.reason(placeholder="Please explain the reason") textarea.reason(placeholder="{{'COMMON.BLOCKED_REASON' | translate}}")
a.button-green(href="") a.button-green(href="")
span Save span(translate="COMMON.SAVE")

Some files were not shown because too many files have changed in this diff Show More