Merge branch 'master' into stable

stable
David Barragán Merino 2016-04-29 11:52:38 +02:00
commit af069abae5
451 changed files with 4688 additions and 14709 deletions

View File

@ -21,6 +21,7 @@ answer newbie questions, and generally made Taiga that much better:
- Brett Profitt <brett.profitt@gmail.com> - Brett Profitt <brett.profitt@gmail.com>
- Chris Wilson <chris.wilson@aridhia.com> - Chris Wilson <chris.wilson@aridhia.com>
- Daniel Koch - Daniel Koch
- Everardo Medina <everblut@gmail.com>
- Florian Bezagu - Florian Bezagu
- Guilhem Got <guilhem.got@gmail.com> - Guilhem Got <guilhem.got@gmail.com>
- Jordan Rinke - Jordan Rinke

View File

@ -1,6 +1,15 @@
# Changelog # # Changelog #
## 2.1.0 Ursus Americanus (2016-05-03)
### Features
- Add sprint title on search results for user stories (thanks to [@everblut](https://github.com/everblut))
### Misc
- Lots of small and not so small bugfixes.
## 2.0.0 Pulsatilla Patens (2016-04-04) ## 2.0.0 Pulsatilla Patens (2016-04-04)
### Features ### Features

View File

@ -601,6 +601,9 @@ i18nInit = (lang, $translate) ->
# i18n - moment.js # i18n - moment.js
moment.locale(lang) moment.locale(lang)
if (lang != 'en') # en is the default, the file doesn't exist
ljs.load "/#{window._version}/locales/moment-locales/" + lang + ".js"
# i18n - checksley.js # i18n - checksley.js
messages = { messages = {
defaultMessage: $translate.instant("COMMON.FORM_ERRORS.DEFAULT_MESSAGE") defaultMessage: $translate.instant("COMMON.FORM_ERRORS.DEFAULT_MESSAGE")

View File

@ -240,7 +240,7 @@ module.directive("tgMemberships", ["$tgTemplate", "$compile", MembershipsDirecti
## Member Avatar Directive ## Member Avatar Directive
############################################################################# #############################################################################
MembershipsRowAvatarDirective = ($log, $template, $translate) -> MembershipsRowAvatarDirective = ($log, $template, $translate, $compile) ->
template = $template.get("admin/memberships-row-avatar.html", true) template = $template.get("admin/memberships-row-avatar.html", true)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
@ -255,6 +255,8 @@ MembershipsRowAvatarDirective = ($log, $template, $translate) ->
} }
html = template(ctx) html = template(ctx)
html = $compile(html)($scope)
$el.html(html) $el.html(html)
if not $attrs.tgMembershipsRowAvatar? if not $attrs.tgMembershipsRowAvatar?
@ -269,7 +271,7 @@ MembershipsRowAvatarDirective = ($log, $template, $translate) ->
return {link: link} return {link: link}
module.directive("tgMembershipsRowAvatar", ["$log", "$tgTemplate", '$translate', MembershipsRowAvatarDirective]) module.directive("tgMembershipsRowAvatar", ["$log", "$tgTemplate", '$translate', "$compile", MembershipsRowAvatarDirective])
############################################################################# #############################################################################
@ -393,9 +395,7 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
</div> </div>
<a class="delete" href="" <a class="delete" href=""
title="{{ 'ADMIN.MEMBERSHIP.DELETE_MEMBER' | translate }}"> title="{{ 'ADMIN.MEMBERSHIP.DELETE_MEMBER' | translate }}">
<svg class="icon icon-trash"> <tg-svg svg-icon="icon-trash"></tg-svg>
<use xlink:href="#icon-trash">
</svg>
</a> </a>
""" """
@ -406,9 +406,7 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
</a> </a>
<a class="delete" href="" <a class="delete" href=""
title="{{ 'ADMIN.MEMBERSHIP.DELETE_MEMBER' | translate }}"> title="{{ 'ADMIN.MEMBERSHIP.DELETE_MEMBER' | translate }}">
<svg class="icon icon-trash"> <tg-svg svg-icon="icon-trash"></tg-svg>
<use xlink:href="#icon-trash">
</svg>
</a> </a>
""" """

View File

@ -228,7 +228,7 @@ ProjectModulesDirective = ($repo, $confirm, $loading, projectService) ->
event.preventDefault() event.preventDefault()
submit() submit()
$el.on "click", ".icon-save", (event) -> $el.on "click", ".save", (event) ->
event.preventDefault() event.preventDefault()
submit() submit()

View File

@ -137,22 +137,31 @@ ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame, $tra
itemEl = null itemEl = null
tdom = $el.find(".sortable") tdom = $el.find(".sortable")
tdom.sortable({ drake = dragula([tdom[0]], {
handle: ".row.table-main.visualization", direction: 'vertical',
dropOnEmpty: true copySortSource: false,
connectWith: ".project-values-body" copy: false,
revert: 400 mirrorContainer: tdom[0],
axis: "y" moves: (item) -> return $(item).is('div[tg-bind-scope]')
}) })
tdom.on "sortstop", (event, ui) -> drake.on 'dragend', (item) ->
itemEl = ui.item itemEl = $(item)
itemValue = itemEl.scope().value itemValue = itemEl.scope().value
itemIndex = itemEl.index() itemIndex = itemEl.index()
$scope.$broadcast("admin:project-values:move", itemValue, itemIndex) $scope.$broadcast("admin:project-values:move", itemValue, itemIndex)
scroll = autoScroll(window, {
margin: 20,
pixels: 30,
scrollWhenOutside: true,
autoScroll: () ->
return this.down && drake.dragging;
})
$scope.$on "$destroy", -> $scope.$on "$destroy", ->
$el.off() $el.off()
drake.destroy()
## Value Link ## Value Link
@ -441,7 +450,7 @@ class ProjectCustomAttributesController extends mixOf(taiga.Controller, taiga.Pa
loadCustomAttributes: => loadCustomAttributes: =>
return @rs.customAttributes[@scope.type].list(@scope.projectId).then (customAttributes) => return @rs.customAttributes[@scope.type].list(@scope.projectId).then (customAttributes) =>
@scope.customAttributes = customAttributes @scope.customAttributes = customAttributes
@scope.maxOrder = _.maxBy(customAttributes, "order").order @scope.maxOrder = _.maxBy(customAttributes, "order")?.order
return customAttributes return customAttributes
createCustomAttribute: (attrValues) => createCustomAttribute: (attrValues) =>
@ -483,16 +492,16 @@ ProjectCustomAttributesDirective = ($log, $confirm, animationFrame, $translate)
# Drag & Drop # Drag & Drop
################################## ##################################
sortableEl = $el.find(".js-sortable") sortableEl = $el.find(".js-sortable")
drake = dragula([sortableEl[0]], {
sortableEl.sortable({ direction: 'vertical',
handle: ".js-view-custom-field", copySortSource: false,
dropOnEmpty: true copy: false,
revert: 400 mirrorContainer: sortableEl[0],
axis: "y" moves: (item) -> return $(item).is('div[tg-bind-scope]')
}) })
sortableEl.on "sortstop", (event, ui) -> drake.on 'dragend', (item) ->
itemEl = ui.item itemEl = $(item)
itemAttr = itemEl.scope().attr itemAttr = itemEl.scope().attr
itemIndex = itemEl.index() itemIndex = itemEl.index()
$ctrl.moveCustomAttributes(itemAttr, itemIndex) $ctrl.moveCustomAttributes(itemAttr, itemIndex)

View File

@ -162,8 +162,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
subtitle = @translate.instant("ADMIN.ROLES.DISABLE_COMPUTABLE_ALERT_SUBTITLE", { subtitle = @translate.instant("ADMIN.ROLES.DISABLE_COMPUTABLE_ALERT_SUBTITLE", {
roleName: @scope.role.name roleName: @scope.role.name
}) })
message = @translate.instant("ADMIN.ROLES.DISABLE_COMPUTABLE_ALERT_MESSAGE") return @confirm.ask(title, subtitle, "").then askOnSuccess, askOnError
return @confirm.ask(title, subtitle, message).then askOnSuccess, askOnError
toggleComputable: debounce 2000, -> toggleComputable: debounce 2000, ->
if not @scope.role.computable if not @scope.role.computable
@ -292,9 +291,7 @@ RolePermissionsDirective = ($rootscope, $repo, $confirm, $compile) ->
title="{{ '<%- permission.name %>' | translate }}"></div> title="{{ '<%- permission.name %>' | translate }}"></div>
<% }) %> <% }) %>
</div> </div>
<svg class="icon icon-arrow-right"> <tg-svg svg-icon="icon-arrow-right"></tg-svg>
<use xlink:href="#icon-arrow-right">
</svg>
""") """)
categoryTemplate = _.template(""" categoryTemplate = _.template("""

View File

@ -275,6 +275,13 @@ LoginDirective = ($auth, $confirm, $location, $config, $routeParams, $navUrls, $
onError = (response) -> onError = (response) ->
$confirm.notify("light-error", $translate.instant("LOGIN_FORM.ERROR_AUTH_INCORRECT")) $confirm.notify("light-error", $translate.instant("LOGIN_FORM.ERROR_AUTH_INCORRECT"))
$scope.onKeyUp = (event) ->
target = angular.element(event.currentTarget)
value = target.val()
$scope.iscapsLockActivated = false
if value != value.toLowerCase()
$scope.iscapsLockActivated = true
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()

View File

@ -38,9 +38,9 @@ module = angular.module("taigaBacklog")
## Issues Filters Directive ## Issues Filters Directive
############################################################################# #############################################################################
BacklogFiltersDirective = ($q, $log, $location, $templates) -> BacklogFiltersDirective = ($q, $log, $location, $template, $compile) ->
template = $templates.get("backlog/filters.html", true) template = $template.get("backlog/filters.html", true)
templateSelected = $templates.get("backlog/filter-selected.html", true) templateSelected = $template.get("backlog/filter-selected.html", true)
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
currentFiltersType = '' currentFiltersType = ''
@ -78,6 +78,8 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
f.style = "border-left: 3px solid #{f.color}" f.style = "border-left: 3px solid #{f.color}"
html = templateSelected({filters: selectedFilters}) html = templateSelected({filters: selectedFilters})
html = $compile(html)($scope)
$el.find(".filters-applied").html(html) $el.find(".filters-applied").html(html)
renderFilters = (filters) -> renderFilters = (filters) ->
@ -86,6 +88,7 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
f.style = "border-left: 3px solid #{f.color}" f.style = "border-left: 3px solid #{f.color}"
html = template({filters:filters}) html = template({filters:filters})
html = $compile(html)($scope)
$el.find(".filter-list").html(html) $el.find(".filter-list").html(html)
getFiltersType = () -> getFiltersType = () ->
@ -94,7 +97,7 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
reloadUserstories = () -> reloadUserstories = () ->
currentFiltersType = getFiltersType() currentFiltersType = getFiltersType()
$q.all([$ctrl.loadUserstories(), $ctrl.generateFilters()]).then () -> $q.all([$ctrl.loadUserstories(true), $ctrl.generateFilters()]).then () ->
currentFilters = $scope.filters[currentFiltersType] currentFilters = $scope.filters[currentFiltersType]
renderFilters(_.reject(currentFilters, "selected")) renderFilters(_.reject(currentFilters, "selected"))
@ -158,9 +161,9 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
event.preventDefault() event.preventDefault()
showCategories() showCategories()
$el.on "click", ".filters-applied a", (event) -> $el.on "click", ".remove-filter", (event) ->
event.preventDefault() event.preventDefault()
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget).parent()
id = target.data("id") id = target.data("id")
type = target.data("type") type = target.data("type")
toggleFilterSelection(type, id) toggleFilterSelection(type, id)
@ -179,4 +182,4 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
return {link:link} return {link:link}
module.directive("tgBacklogFilters", ["$q", "$log", "$tgLocation", "$tgTemplate", BacklogFiltersDirective]) module.directive("tgBacklogFilters", ["$q", "$log", "$tgLocation", "$tgTemplate", "$compile", BacklogFiltersDirective])

View File

@ -62,6 +62,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@location, @appMetaService, @navUrls, @events, @analytics, @translate, @loading, @rs2) -> @location, @appMetaService, @navUrls, @events, @analytics, @translate, @loading, @rs2) ->
bindMethods(@) bindMethods(@)
@.page = 1
@.disablePagination = false
@scope.userstories = []
@scope.sectionName = @translate.instant("BACKLOG.SECTION_NAME") @scope.sectionName = @translate.instant("BACKLOG.SECTION_NAME")
@showTags = false @showTags = false
@activeFilters = false @activeFilters = false
@ -90,7 +94,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
initializeEventHandlers: -> initializeEventHandlers: ->
@scope.$on "usform:bulk:success", => @scope.$on "usform:bulk:success", =>
@.loadUserstories() @.loadUserstories(true)
@.loadProjectStats() @.loadProjectStats()
@analytics.trackEvent("userstory", "create", "bulk create userstory on backlog", 1) @analytics.trackEvent("userstory", "create", "bulk create userstory on backlog", 1)
@ -100,7 +104,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@analytics.trackEvent("sprint", "create", "create sprint on backlog", 1) @analytics.trackEvent("sprint", "create", "create sprint on backlog", 1)
@scope.$on "usform:new:success", => @scope.$on "usform:new:success", =>
@.loadUserstories() @.loadUserstories(true)
@.loadProjectStats() @.loadProjectStats()
@rootscope.$broadcast("filters:update") @rootscope.$broadcast("filters:update")
@ -112,20 +116,25 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@scope.$on "sprintform:remove:success", (event, sprint) => @scope.$on "sprintform:remove:success", (event, sprint) =>
@.loadSprints() @.loadSprints()
@.loadProjectStats() @.loadProjectStats()
@.loadUserstories() @.loadUserstories(true)
if sprint.closed if sprint.closed
@.loadClosedSprints() @.loadClosedSprints()
@rootscope.$broadcast("filters:update") @rootscope.$broadcast("filters:update")
@scope.$on "usform:edit:success", => @scope.$on "usform:edit:success", (event, data) =>
@.loadUserstories() index = _.findIndex @scope.userstories, (us) ->
return us.id == data.id
@scope.userstories[index] = data
@rootscope.$broadcast("filters:update") @rootscope.$broadcast("filters:update")
@scope.$on("sprint:us:move", @.moveUs) @scope.$on("sprint:us:move", @.moveUs)
@scope.$on("sprint:us:moved", @.loadSprints) @scope.$on "sprint:us:moved", () =>
@scope.$on("sprint:us:moved", @.loadProjectStats) @.loadSprints()
@.loadProjectStats()
@scope.$on("backlog:load-closed-sprints", @.loadClosedSprints) @scope.$on("backlog:load-closed-sprints", @.loadClosedSprints)
@scope.$on("backlog:unload-closed-sprints", @.unloadClosedSprints) @scope.$on("backlog:unload-closed-sprints", @.unloadClosedSprints)
@ -248,18 +257,37 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@.loadUserstories() @.loadUserstories()
loadUserstories: -> loadUserstories: (resetPagination = false)->
@.loadingUserstories = true
@.disablePagination = true
@scope.httpParams = @.getUrlFilters() @scope.httpParams = @.getUrlFilters()
@rs.userstories.storeQueryParams(@scope.projectId, @scope.httpParams) @rs.userstories.storeQueryParams(@scope.projectId, @scope.httpParams)
if resetPagination
@.page = 1
@scope.httpParams.page = @.page
promise = @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams) promise = @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams)
return promise.then (userstories) => return promise.then (result) =>
userstories = result[0]
header = result[1]
if resetPagination
@scope.userstories = []
# NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files # NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files
@scope.userstories = _.sortBy(userstories, "backlog_order") @scope.userstories = @scope.userstories.concat(_.sortBy(userstories, "backlog_order"))
@.setSearchDataFilters() @.setSearchDataFilters()
@.loadingUserstories = false
if header('x-pagination-next')
@.disablePagination = false
@.page++
# The broadcast must be executed when the DOM has been fully reloaded. # The broadcast must be executed when the DOM has been fully reloaded.
# We can't assure when this exactly happens so we need a defer # We can't assure when this exactly happens so we need a defer
scopeDefer @scope, => scopeDefer @scope, =>
@ -362,8 +390,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
# Persist in bulk all affected # Persist in bulk all affected
# userstories with order change # userstories with order change
@rs.userstories.bulkUpdateBacklogOrder(project, data).then => @rs.userstories.bulkUpdateBacklogOrder(project, data).then =>
for us in usList @rootscope.$broadcast("sprint:us:moved")
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
# For sprint # For sprint
else else
@ -374,8 +401,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
# Persist in bulk all affected # Persist in bulk all affected
# userstories with order change # userstories with order change
@rs.userstories.bulkUpdateSprintOrder(project, data).then => @rs.userstories.bulkUpdateSprintOrder(project, data).then =>
for us in usList @rootscope.$broadcast("sprint:us:moved")
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
return promise return promise
@ -402,7 +428,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
items = @.resortUserStories(@scope.userstories, "backlog_order") items = @.resortUserStories(@scope.userstories, "backlog_order")
data = @.prepareBulkUpdateData(items, "backlog_order") data = @.prepareBulkUpdateData(items, "backlog_order")
return @rs.userstories.bulkUpdateBacklogOrder(us.project, data).then => return @rs.userstories.bulkUpdateBacklogOrder(us.project, data).then =>
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId) @rootscope.$broadcast("sprint:us:moved")
if movedFromClosedSprint if movedFromClosedSprint
@rootscope.$broadcast("backlog:load-closed-sprints") @rootscope.$broadcast("backlog:load-closed-sprints")
@ -415,17 +441,15 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
# From backlog to sprint # From backlog to sprint
if oldSprintId == null if oldSprintId == null
us.milestone = newSprintId for us in usList us.milestone = newSprintId for us in usList
args = [newUsIndex, 0].concat(usList)
@scope.$apply => # Add moving us to sprint user stories list
args = [newUsIndex, 0].concat(usList) Array.prototype.splice.apply(newSprint.user_stories, args)
# Add moving us to sprint user stories list # Remove moving us from backlog userstories lists.
Array.prototype.splice.apply(newSprint.user_stories, args) for us, key in usList
r = @scope.userstories.indexOf(us)
# Remove moving us from backlog userstories lists. @scope.userstories.splice(r, 1)
for us, key in usList
r = @scope.userstories.indexOf(us)
@scope.userstories.splice(r, 1)
# From sprint to sprint # From sprint to sprint
else else
@ -442,21 +466,20 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
r = sprint.user_stories.indexOf(us) r = sprint.user_stories.indexOf(us)
sprint.user_stories.splice(r, 1) sprint.user_stories.splice(r, 1)
# Persist the milestone change of userstory #Persist the milestone change of userstory
promises = _.map usList, (us) => @repo.save(us) promises = _.map usList, (us) => @repo.save(us)
# Rehash userstories order field #Rehash userstories order field
# and persist in bulk all changes. #and persist in bulk all changes.
promise = @q.all(promises).then => promise = @q.all(promises).then =>
items = @.resortUserStories(newSprint.user_stories, "sprint_order") items = @.resortUserStories(newSprint.user_stories, "sprint_order")
data = @.prepareBulkUpdateData(items, "sprint_order") data = @.prepareBulkUpdateData(items, "sprint_order")
@rs.userstories.bulkUpdateSprintOrder(project, data).then (result) => @rs.userstories.bulkUpdateSprintOrder(project, data).then (result) =>
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId) @rootscope.$broadcast("sprint:us:moved")
@rs.userstories.bulkUpdateBacklogOrder(project, data).then => @rs.userstories.bulkUpdateBacklogOrder(project, data).then =>
for us in usList @rootscope.$broadcast("sprint:us:moved")
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
if movedToClosedSprint || movedFromClosedSprint if movedToClosedSprint || movedFromClosedSprint
@scope.$broadcast("backlog:load-closed-sprints") @scope.$broadcast("backlog:load-closed-sprints")
@ -583,7 +606,11 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
promise = @.repo.remove(us) promise = @.repo.remove(us)
promise.then => promise.then =>
askResponse.finish() askResponse.finish()
@.loadBacklog()
@q.all([
@.loadProjectStats(),
@.loadSprints()
])
promise.then null, => promise.then null, =>
askResponse.finish(false) askResponse.finish(false)
@confirm.notify("error") @confirm.notify("error")
@ -652,7 +679,7 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
return _.map(rowElements, (x) -> angular.element(x)) return _.map(rowElements, (x) -> angular.element(x))
$scope.$on("userstories:loaded", reloadDoomLine) $scope.$on("userstories:loaded", reloadDoomLine)
$scope.$watch "stats", reloadDoomLine $scope.$watch("stats", reloadDoomLine)
## Move to current sprint link ## Move to current sprint link
@ -807,8 +834,6 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
linkFilters($scope, $el, $attrs, $ctrl) linkFilters($scope, $el, $attrs, $ctrl)
linkDoomLine($scope, $el, $attrs, $ctrl) linkDoomLine($scope, $el, $attrs, $ctrl)
$el.find(".backlog-table-body").disableSelection()
filters = $ctrl.getUrlFilters() filters = $ctrl.getUrlFilters()
if filters.status || if filters.status ||
filters.tags || filters.tags ||
@ -843,7 +868,7 @@ UsRolePointsSelectorDirective = ($rootscope, $template, $compile, $translate) ->
if numberOfRoles > 1 if numberOfRoles > 1
$el.append($compile(selectionTemplate({"roles": roles}))($scope)) $el.append($compile(selectionTemplate({"roles": roles}))($scope))
else else
$el.find(".icon-arrow-bottom").remove() $el.find(".icon-arrow-down").remove()
$el.find(".header-points").addClass("not-clickable") $el.find(".header-points").addClass("not-clickable")
$scope.$on "uspoints:select", (ctx, roleId, roleName) -> $scope.$on "uspoints:select", (ctx, roleId, roleName) ->

View File

@ -38,187 +38,117 @@ module = angular.module("taigaBacklog")
############################################################################# #############################################################################
deleteElement = (el) -> deleteElement = (el) ->
el.scope().$destroy() $(el).scope().$destroy()
el.off() $(el).off()
el.remove() $(el).remove()
BacklogSortableDirective = ($repo, $rs, $rootscope, $tgConfirm, $translate) -> BacklogSortableDirective = ($repo, $rs, $rootscope, $tgConfirm, $translate) ->
# Notes about jquery bug:
# http://stackoverflow.com/questions/5791886/jquery-draggable-shows-
# helper-in-wrong-place-when-scrolled-down-page
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
getUsIndex = (us) =>
return $(us).index(".backlog-table-body .row")
bindOnce $scope, "project", (project) -> bindOnce $scope, "project", (project) ->
# If the user has not enough permissions we don't enable the sortable # If the user has not enough permissions we don't enable the sortable
if not (project.my_permissions.indexOf("modify_us") > -1) if not (project.my_permissions.indexOf("modify_us") > -1)
return return
initIsBacklog = false
filterError = -> filterError = ->
text = $translate.instant("BACKLOG.SORTABLE_FILTER_ERROR") text = $translate.instant("BACKLOG.SORTABLE_FILTER_ERROR")
$tgConfirm.notify("error", text) $tgConfirm.notify("error", text)
$el.sortable({ drake = dragula([$el[0], $('.empty-backlog')[0]], {
items: ".us-item-row", copySortSource: false,
cancel: ".popover" copy: false,
connectWith: ".sprint" isContainer: (el) -> return el.classList.contains('sprint-table'),
dropOnEmpty: true moves: (item) ->
placeholder: "row us-item-row us-item-drag sortable-placeholder" if !$(item).hasClass('row')
scroll: true return false
disableHorizontalScroll: true
# A consequence of length of backlog user story item
# the default tolerance ("intersection") not works properly.
tolerance: "pointer"
# Revert on backlog is disabled bacause it works bad. Something
# on the current taiga backlog structure or style makes jquery ui
# works unexpectly (in some circumstances calculates wrong
# position for revert).
revert: false
start: () ->
$(document.body).addClass("drag-active")
stop: () ->
$(document.body).removeClass("drag-active")
if $el.hasClass("active-filters") # it doesn't move is the filter is open
$el.sortable("cancel") parent = $(item).parent()
initIsBacklog = parent.hasClass('backlog-table-body')
if initIsBacklog && $el.hasClass("active-filters")
filterError() filterError()
return false
return true
}) })
$el.on "multiplesortreceive", (event, ui) -> drake.on 'drag', (item, container) ->
if $el.hasClass("active-filters") parent = $(item).parent()
ui.source.sortable("cancel") initIsBacklog = parent.hasClass('backlog-table-body')
filterError()
return $(document.body).addClass("drag-active")
itemUs = ui.item.scope().us isChecked = $(item).find("input[type='checkbox']").is(":checked")
itemIndex = getUsIndex(ui.item)
deleteElement(ui.item) window.dragMultiple.start(item, container)
$scope.$emit("sprint:us:move", [itemUs], itemIndex, null) drake.on 'cloned', (item) ->
ui.item.find('a').removeClass('noclick') $(item).addClass('backlog-us-mirror')
$el.on "multiplesortstop", (event, ui) -> drake.on 'dragend', (item) ->
# When parent not exists, do nothing $('.doom-line').remove()
if $(ui.items[0]).parent().length == 0
return
if $el.hasClass("active-filters") parent = $(item).parent()
return isBacklog = parent.hasClass('backlog-table-body') || parent.hasClass('empty-backlog')
items = _.sortBy ui.items, (item) -> sameContainer = (initIsBacklog == isBacklog)
return $(item).index()
index = _.min _.map items, (item) -> dragMultipleItems = window.dragMultiple.stop()
return getUsIndex(item)
us = _.map items, (item) -> $(document.body).removeClass("drag-active")
item = $(item)
itemUs = item.scope().us
# HACK: setTimeout prevents that firefox click items = $(item).parent().find('.row')
# event fires just after drag ends
setTimeout ( =>
item.find('a').removeClass('noclick')
), 300
return itemUs sprint = null
$scope.$emit("sprint:us:move", us, index, null) firstElement = if dragMultipleItems.length then dragMultipleItems[0] else item
$el.on "sortstart", (event, ui) -> if isBacklog
ui.item.find('a').addClass('noclick') index = $(firstElement).index(".backlog-table-body .row")
else
index = $(firstElement).index()
sprint = parent.scope().sprint.id
$scope.$on "$destroy", -> if !sameContainer
$el.off() if dragMultipleItems.length
usList = _.map dragMultipleItems, (item) ->
return {link: link} return item = $(item).scope().us
else
BacklogEmptySortableDirective = ($repo, $rs, $rootscope) -> usList = [$(item).scope().us]
# Notes about jquery bug:
# http://stackoverflow.com/questions/5791886/jquery-draggable-shows-
# helper-in-wrong-place-when-scrolled-down-page
link = ($scope, $el, $attrs) ->
bindOnce $scope, "project", (project) ->
# If the user has not enough permissions we don't enable the sortable
if project.my_permissions.indexOf("modify_us") > -1
$el.sortable({
items: ".us-item-row",
dropOnEmpty: true
})
$el.on "sortreceive", (event, ui) ->
itemUs = ui.item.scope().us
itemIndex = ui.item.index()
deleteElement(ui.item)
$scope.$emit("sprint:us:move", [itemUs], itemIndex, null)
ui.item.find('a').removeClass('noclick')
$scope.$on "$destroy", ->
$el.off()
return {link: link}
SprintSortableDirective = ($repo, $rs, $rootscope) ->
link = ($scope, $el, $attrs) ->
bindOnce $scope, "project", (project) ->
# If the user has not enough permissions we don't enable the sortable
if project.my_permissions.indexOf("modify_us") > -1
$el.sortable({
scroll: true
dropOnEmpty: true
items: ".sprint-table .milestone-us-item-row"
disableHorizontalScroll: true
connectWith: ".sprint,.backlog-table-body,.empty-backlog"
placeholder: "row us-item-row sortable-placeholder"
forcePlaceholderSize:true
})
$el.on "multiplesortreceive", (event, ui) ->
items = _.sortBy ui.items, (item) ->
return $(item).index()
index = _.min _.map items, (item) ->
return $(item).index()
us = _.map items, (item) ->
item = $(item)
itemUs = item.scope().us
if (dragMultipleItems.length)
_.each dragMultipleItems, (item) ->
deleteElement(item)
else
deleteElement(item) deleteElement(item)
else
if dragMultipleItems.length
usList = _.map dragMultipleItems, (item) ->
return item = $(item).scope().us
else
usList = _.map items, (item) ->
item = $(item)
itemUs = item.scope().us
return itemUs return itemUs
$scope.$emit("sprint:us:move", us, index, $scope.sprint.id) $scope.$emit("sprint:us:move", usList, index, sprint)
$el.on "multiplesortstop", (event, ui) -> scroll = autoScroll([window], {
# When parent not exists, do nothing margin: 20,
if ui.item.parent().length == 0 pixels: 30,
return scrollWhenOutside: true,
autoScroll: () ->
return this.down && drake.dragging;
})
itemUs = ui.item.scope().us $scope.$on "$destroy", ->
itemIndex = ui.item.index() $el.off()
drake.destroy()
# HACK: setTimeout prevents that firefox click
# event fires just after drag ends
setTimeout ( =>
ui.item.find('a').removeClass('noclick')
), 300
$scope.$emit("sprint:us:move", [itemUs], itemIndex, $scope.sprint.id)
$el.on "sortstart", (event, ui) ->
ui.item.find('a').addClass('noclick')
return {link:link}
return {link: link}
module.directive("tgBacklogSortable", [ module.directive("tgBacklogSortable", [
"$tgRepo", "$tgRepo",
@ -228,17 +158,3 @@ module.directive("tgBacklogSortable", [
"$translate", "$translate",
BacklogSortableDirective BacklogSortableDirective
]) ])
module.directive("tgBacklogEmptySortable", [
"$tgRepo",
"$tgResources",
"$rootScope",
BacklogEmptySortableDirective
])
module.directive("tgSprintSortable", [
"$tgRepo",
"$tgResources",
"$rootScope",
SprintSortableDirective
])

View File

@ -62,7 +62,7 @@ BacklogSprintDirective = ($repo, $rootscope) ->
$el.find(".sprint-table").slideToggle(slideOptions) $el.find(".sprint-table").slideToggle(slideOptions)
$el.on "click", ".sprint-name > .icon-edit", (event) -> $el.on "click", ".edit-sprint", (event) ->
event.preventDefault() event.preventDefault()
sprint = $scope.$eval($attrs.tgBacklogSprint) sprint = $scope.$eval($attrs.tgBacklogSprint)

View File

@ -284,39 +284,52 @@ module.factory("$tgTemplate", ["$templateCache", Template])
## Permission directive, hide elements when necessary ## Permission directive, hide elements when necessary
############################################################################# #############################################################################
Capslock = ($translate) -> Capslock = () ->
link = ($scope, $el, $attrs) -> template = """
open = false <tg-svg class="capslock" ng-if="capslockIcon && iscapsLockActivated" svg-icon='icon-capslock' svg-title='COMMON.CAPSLOCK_WARNING'></tg-svg>
"""
return {
template: template
}
warningIcon = "<svg class='icon icon-capslock' title='" + $translate.instant('COMMON.CAPSLOCK_WARNING') + "'><use xlink:href='#icon-capslock'></svg>"; module.directive("tgCapslock", [Capslock])
hideIcon = () -> LightboxClose = () ->
$('.icon-capslock').fadeOut () -> template = """
open = false <a class="close" href="" title="{{'COMMON.CLOSE' | translate}}">
<tg-svg svg-icon="icon-close"></tg-svg>
</a>
"""
$(this).remove() return {
template: template
}
showIcon = (e) -> module.directive("tgLightboxClose", [LightboxClose])
return if open
element = e.currentTarget
$(element).parent().append(warningIcon)
$('.icon-capslock').fadeIn()
open = true Svg = () ->
template = """
<svg class="{{ 'icon ' + svgIcon }}">
<use xlink:href="" ng-attr-xlink:href="{{ '#' + svgIcon }}">
<title ng-if="svgTitle">{{svgTitle}}</title>
<title
ng-if="svgTitleTranslate"
translate="{{svgTitleTranslate}}"
translate-values="{{svgTitleTranslateValues}}"
></title>
</use>
</svg>
"""
$el.on 'blur', (e) -> return {
hideIcon() scope: {
svgIcon: "@",
svgTitle: "@",
svgTitleTranslate: "@",
svgTitleTranslateValues: "="
},
template: template
}
$el.on 'keyup.capslock, focus', (e) -> module.directive("tgSvg", [Svg])
if $el.val() == $el.val().toLowerCase()
hideIcon(e)
else
showIcon(e)
$scope.$on "$destroy", ->
$el.off('.capslock')
return {link:link}
module.directive("tgCapslock", ["$translate", Capslock])

View File

@ -173,14 +173,17 @@ class ConfirmService extends taiga.Service
if icon.type == "img" if icon.type == "img"
detailImage = $('<img>').addClass('lb-icon').attr('src', icon.name) detailImage = $('<img>').addClass('lb-icon').attr('src', icon.name)
else if icon.type == "svg" else if icon.type == "svg"
detailImage = document.createElement("div")
taiga.addClass(detailImage, "icon")
taiga.addClass(detailImage, icon.name)
taiga.addClass(detailImage, "lb-icon")
svgContainer = document.createElementNS("http://www.w3.org/2000/svg", "svg")
useSVG = document.createElementNS('http://www.w3.org/2000/svg', 'use') useSVG = document.createElementNS('http://www.w3.org/2000/svg', 'use')
useSVG.setAttributeNS('http://www.w3.org/1999/xlink','href', '#' + icon.name) useSVG.setAttributeNS('http://www.w3.org/1999/xlink','href', '#' + icon.name)
detailImage = document.createElementNS("http://www.w3.org/2000/svg", "svg") detailImage.appendChild(svgContainer).appendChild(useSVG)
detailImage.classList.add("icon")
detailImage.classList.add("lb-icon")
detailImage.classList.add(icon.name)
detailImage.appendChild(useSVG)
if detailImage if detailImage
el.find('section').prepend(detailImage) el.find('section').prepend(detailImage)

View File

@ -117,7 +117,7 @@ CustomAttributesValuesDirective = ($templates, $storage) ->
$ctrl.initialize($attrs.type, value.id) $ctrl.initialize($attrs.type, value.id)
$ctrl.loadCustomAttributesValues() $ctrl.loadCustomAttributesValues()
$el.on "click", ".custom-fields-header .icon", -> $el.on "click", ".custom-fields-header .collapse", ->
hash = collapsedHash($attrs.type) hash = collapsedHash($attrs.type)
collapsed = not($storage.get(hash) or false) collapsed = not($storage.get(hash) or false)
$storage.set(hash, collapsed) $storage.set(hash, collapsed)

View File

@ -421,7 +421,7 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c
# Events # Events
$el.on "click", ".add-comment button.button-green", debounce 2000, (event) -> $el.on "click", ".add-comment .button-green", debounce 2000, (event) ->
event.preventDefault() event.preventDefault()
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget)
@ -467,11 +467,11 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c
$el.on "focus", ".add-comment textarea", (event) -> $el.on "focus", ".add-comment textarea", (event) ->
$(this).addClass('active') $(this).addClass('active')
$el.on "click", ".history-tabs li a", (event) -> $el.on "click", ".history-tabs a", (event) ->
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget)
$el.find(".history-tabs li a").removeClass("active") $el.find(".history-tabs li").removeClass("active")
target.addClass("active") target.parent().addClass("active")
$el.find(".history section").addClass("hidden") $el.find(".history section").addClass("hidden")
$el.find(".history section.#{target.data('section-class')}").removeClass("hidden") $el.find(".history section.#{target.data('section-class')}").removeClass("hidden")

View File

@ -51,7 +51,12 @@ class LightboxService extends taiga.Service
@animationFrame.add -> @animationFrame.add ->
$el.addClass("open") $el.addClass("open")
$el.one "transitionend", => $el.one "transitionend", =>
$el.find('input,textarea').first().focus() firstField = $el.find('input,textarea').first()
if firstField.length
$el.find('input,textarea').first().focus()
else if document.activeElement
$(document.activeElement).blur()
@animationFrame.add => @animationFrame.add =>
lightboxContent.show() lightboxContent.show()
@ -79,7 +84,7 @@ class LightboxService extends taiga.Service
if $el.hasClass("remove-on-close") if $el.hasClass("remove-on-close")
scope = $el.data("scope") scope = $el.data("scope")
scope.$destroy() scope.$destroy() if scope
$el.remove() $el.remove()
closeAll: -> closeAll: ->

View File

@ -158,6 +158,10 @@ RelatedTaskStatusDirective = ($repo, $template) ->
$scope.$eval($attrs.onUpdate) $scope.$eval($attrs.onUpdate)
$scope.$emit("related-tasks:status-changed") $scope.$emit("related-tasks:status-changed")
$scope.$watch $attrs.tgRelatedTaskStatus, () ->
task = $scope.$eval($attrs.tgRelatedTaskStatus)
updateTaskStatus($el, task, $scope.taskStatusById)
taiga.bindOnce $scope, "project", (project) -> taiga.bindOnce $scope, "project", (project) ->
$el.append(selectionTemplate({ 'statuses': project.task_statuses })) $el.append(selectionTemplate({ 'statuses': project.task_statuses }))
updateTaskStatus($el, task, $scope.taskStatusById) updateTaskStatus($el, task, $scope.taskStatusById)

View File

@ -108,6 +108,8 @@ LbTagLineDirective = ($rs, $template, $compile) ->
templateTags = $template.get("common/tag/lb-tag-line-tags.html", true) templateTags = $template.get("common/tag/lb-tag-line-tags.html", true)
autocomplete = null
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
## Render ## Render
renderTags = (tags, tagsColors) -> renderTags = (tags, tagsColors) ->
@ -130,7 +132,7 @@ LbTagLineDirective = ($rs, $template, $compile) ->
resetInput = -> resetInput = ->
$el.find("input").val("") $el.find("input").val("")
$el.find("input").autocomplete("close") autocomplete.close()
## Aux methods ## Aux methods
addValue = (value) -> addValue = (value) ->
@ -190,22 +192,15 @@ LbTagLineDirective = ($rs, $template, $compile) ->
deleteValue(value) deleteValue(value)
bindOnce $scope, "project", (project) -> bindOnce $scope, "project", (project) ->
positioningFunction = (position, elements) -> input = $el.find("input")
menu = elements.element.element
menu.css("width", elements.target.width)
menu.css("top", position.top)
menu.css("left", position.left)
$el.find("input").autocomplete({ autocomplete = new Awesomplete(input[0], {
source: _.keys(project.tags_colors) list: _.keys(project.tags_colors)
position: { });
my: "left top",
using: positioningFunction input.on "awesomplete-selectcomplete", () ->
} addValue(input.val())
select: (event, ui) -> input.val("")
addValue(ui.item.value)
ui.item.value = ""
})
$scope.$watch $attrs.ngModel, (tags) -> $scope.$watch $attrs.ngModel, (tags) ->
tagsColors = $scope.project?.tags_colors or [] tagsColors = $scope.project?.tags_colors or []
@ -235,6 +230,8 @@ TagLineDirective = ($rootScope, $repo, $rs, $confirm, $qqueue, $template, $compi
templateTags = $template.get("common/tag/tags-line-tags.html", true) templateTags = $template.get("common/tag/tags-line-tags.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
autocomplete = null
isEditable = -> isEditable = ->
if $attrs.requiredPerm? if $attrs.requiredPerm?
return $scope.project.my_permissions.indexOf($attrs.requiredPerm) != -1 return $scope.project.my_permissions.indexOf($attrs.requiredPerm) != -1
@ -268,7 +265,8 @@ TagLineDirective = ($rootScope, $repo, $rs, $confirm, $qqueue, $template, $compi
hideInput = -> $el.find("input").addClass("hidden").blur() hideInput = -> $el.find("input").addClass("hidden").blur()
resetInput = -> resetInput = ->
$el.find("input").val("") $el.find("input").val("")
$el.find("input").autocomplete("close")
autocomplete.close()
## Aux methods ## Aux methods
addValue = $qqueue.bindAdd (value) -> addValue = $qqueue.bindAdd (value) ->
@ -366,22 +364,15 @@ TagLineDirective = ($rootScope, $repo, $rs, $confirm, $qqueue, $template, $compi
showAddTagButton() showAddTagButton()
positioningFunction = (position, elements) -> input = $el.find("input")
menu = elements.element.element
menu.css("width", elements.target.width)
menu.css("top", position.top)
menu.css("left", position.left)
$el.find("input").autocomplete({ autocomplete = new Awesomplete(input[0], {
source: _.keys(tags_colors) list: _.keys(tags_colors)
position: { });
my: "left top",
using: positioningFunction input.on "awesomplete-selectcomplete", () ->
} addValue(input.val())
select: (event, ui) -> input.val("")
addValue(ui.item.value)
ui.item.value = ""
})
$scope.$watch $attrs.ngModel, (model) -> $scope.$watch $attrs.ngModel, (model) ->
return if not model return if not model

View File

@ -584,20 +584,20 @@ IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $templat
unwatchIssues() unwatchIssues()
# Dom Event Handlers # Dom Event Handlers
$el.on "click", ".filters-cats > ul > li > a", (event) -> $el.on "click", ".filters-cat-single", (event) ->
event.preventDefault() event.preventDefault()
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget)
tags = $scope.filters[target.data("type")] tags = $scope.filters[target.data("type")]
renderFilters(_.reject(tags, "selected")) renderFilters(_.reject(tags, "selected"))
showFilters(target.attr("title"), target.data("type")) showFilters(target.attr("title"), target.data("type"))
$el.on "click", ".filters-inner > .filters-step-cat > .breadcrumb > .back", (event) -> $el.on "click", ".back", (event) ->
event.preventDefault() event.preventDefault()
showCategories($el) showCategories($el)
$el.on "click", ".filters-applied a", (event) -> $el.on "click", ".filters-applied .remove-filter", (event) ->
event.preventDefault() event.preventDefault()
target = angular.element(event.currentTarget) target = angular.element(event.currentTarget).parent()
id = target.data("id") or null id = target.data("id") or null
type = target.data("type") type = target.data("type")
@ -617,7 +617,7 @@ IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $templat
toggleFilterSelection(type, id) toggleFilterSelection(type, id)
$el.on "click", ".filter-list .single-filter .remove-filter", (event) -> $el.on "click", ".filter-list .remove-filter", (event) ->
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()

View File

@ -329,7 +329,7 @@ KanbanArchivedStatusHeaderDirective = ($rootscope, $translate) ->
status = $scope.$eval($attrs.tgKanbanArchivedStatusHeader) status = $scope.$eval($attrs.tgKanbanArchivedStatusHeader)
hidden = true hidden = true
$scope.class = "icon-open-eye" $scope.class = "icon-watch"
$scope.title = showArchivedText $scope.title = showArchivedText
$el.on "click", (event) -> $el.on "click", (event) ->
@ -337,12 +337,12 @@ KanbanArchivedStatusHeaderDirective = ($rootscope, $translate) ->
$scope.$apply -> $scope.$apply ->
if hidden if hidden
$scope.class = "icon-open-eye" $scope.class = "icon-watch"
$scope.title = showArchivedText $scope.title = showArchivedText
$rootscope.$broadcast("kanban:hide-userstories-for-status", status.id) $rootscope.$broadcast("kanban:hide-userstories-for-status", status.id)
else else
$scope.class = "icon-closed-eye" $scope.class = "icon-unwatch"
$scope.title = hideArchivedText $scope.title = hideArchivedText
$rootscope.$broadcast("kanban:show-userstories-for-status", status.id) $rootscope.$broadcast("kanban:show-userstories-for-status", status.id)
@ -418,15 +418,13 @@ module.directive("tgKanbanArchivedStatusIntro", ["$translate", KanbanArchivedSta
KanbanUserstoryDirective = ($rootscope, $loading, $rs, $rs2) -> KanbanUserstoryDirective = ($rootscope, $loading, $rs, $rs2) ->
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
$el.disableSelection()
$scope.$watch "us", (us) -> $scope.$watch "us", (us) ->
if us.is_blocked and not $el.hasClass("blocked") if us.is_blocked and not $el.hasClass("blocked")
$el.addClass("blocked") $el.addClass("blocked")
else if not us.is_blocked and $el.hasClass("blocked") else if not us.is_blocked and $el.hasClass("blocked")
$el.removeClass("blocked") $el.removeClass("blocked")
$el.on 'click', '.icon-edit', (event) -> $el.on 'click', '.edit-us', (event) ->
if $el.find(".icon-edit").hasClass("noclick") if $el.find(".icon-edit").hasClass("noclick")
return return
@ -498,8 +496,6 @@ module.directive("tgKanbanSquishColumn", ["$tgResources", KanbanSquishColumnDire
KanbanWipLimitDirective = -> KanbanWipLimitDirective = ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$el.disableSelection()
status = $scope.$eval($attrs.tgKanbanWipLimit) status = $scope.$eval($attrs.tgKanbanWipLimit)
redrawWipLimit = => redrawWipLimit = =>

View File

@ -55,16 +55,23 @@ KanbanSortableDirective = ($repo, $rs, $rootscope) ->
itemEl.off() itemEl.off()
itemEl.remove() itemEl.remove()
tdom.sortable({ containers = _.map $el.find('.task-column'), (item) ->
handle: ".kanban-task-inner" return item
dropOnEmpty: true
connectWith: ".kanban-uses-box" drake = dragula(containers, {
revert: 400 copySortSource: false,
copy: false,
mirrorContainer: tdom[0],
moves: (item) ->
return $(item).hasClass('kanban-task')
}) })
tdom.on "sortstop", (event, ui) -> drake.on 'drag', (item) ->
parentEl = ui.item.parent() oldParentScope = $(item).parent().scope()
itemEl = ui.item
drake.on 'dragend', (item) ->
parentEl = $(item).parent()
itemEl = $(item)
itemUs = itemEl.scope().us itemUs = itemEl.scope().us
itemIndex = itemEl.index() itemIndex = itemEl.index()
newParentScope = parentEl.scope() newParentScope = parentEl.scope()
@ -78,14 +85,17 @@ KanbanSortableDirective = ($repo, $rs, $rootscope) ->
$scope.$apply -> $scope.$apply ->
$rootscope.$broadcast("kanban:us:move", itemUs, itemUs.status, newStatusId, itemIndex) $rootscope.$broadcast("kanban:us:move", itemUs, itemUs.status, newStatusId, itemIndex)
ui.item.find('a').removeClass('noclick') scroll = autoScroll(containers, {
margin: 20,
pixels: 30,
scrollWhenOutside: true,
autoScroll: () ->
return this.down && drake.dragging;
})
tdom.on "sortstart", (event, ui) -> $scope.$on "$destroy", ->
oldParentScope = ui.item.parent().scope() $el.off()
ui.item.find('a').addClass('noclick') drake.destroy()
$scope.$on "$destroy", ->
$el.off()
return {link: link} return {link: link}

View File

@ -35,10 +35,6 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
$scope.templates = [] $scope.templates = []
currentLoading = null currentLoading = null
$auth.refresh()
$scope.canCreatePrivateProjects = currentUserService.canCreatePrivateProjects()
$scope.canCreatePublicProjects = currentUserService.canCreatePublicProjects()
form = $el.find("form").checksley({"onlyOneErrorElement": true}) form = $el.find("form").checksley({"onlyOneErrorElement": true})
onSuccessSubmit = (response) -> onSuccessSubmit = (response) ->
@ -88,6 +84,9 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
else else
$scope.data.creation_template = _.head(_.filter($scope.templates, (x) -> x.slug == "scrum")).id $scope.data.creation_template = _.head(_.filter($scope.templates, (x) -> x.slug == "scrum")).id
$scope.canCreatePrivateProjects = currentUserService.canCreatePrivateProjects()
$scope.canCreatePublicProjects = currentUserService.canCreatePublicProjects()
lightboxService.open($el) lightboxService.open($el)
submitButton = $el.find(".submit-button") submitButton = $el.find(".submit-button")
@ -101,7 +100,8 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
$scope.$on "$destroy", -> $scope.$on "$destroy", ->
$el.off() $el.off()
openLightbox() $auth.refresh().then () ->
openLightbox()
directive = { directive = {
link: link, link: link,

View File

@ -117,16 +117,14 @@ module.directive("tgRelatedTaskRow", ["$tgRepo", "$compile", "$tgConfirm", "$roo
"$tgTemplate", "$translate", RelatedTaskRowDirective]) "$tgTemplate", "$translate", RelatedTaskRowDirective])
RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $analytics, $template) -> RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $analytics) ->
template = $template.get("task/related-task-create-form.html", true)
newTask = { newTask = {
subject: "" subject: ""
assigned_to: null assigned_to: null
} }
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
createTask = debounce 2000, (task) -> createTask = (task) ->
task.subject = $el.find('input').val() task.subject = $el.find('input').val()
task.assigned_to = $scope.newTask.assigned_to task.assigned_to = $scope.newTask.assigned_to
task.status = $scope.newTask.status task.status = $scope.newTask.status
@ -152,48 +150,53 @@ RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading,
close = () -> close = () ->
$el.off() $el.off()
$el.html("")
$scope.newRelatedTaskFormOpen = false $scope.openNewRelatedTask = false
reset = () ->
newTask = {
subject: ""
assigned_to: null
}
newTask["status"] = $scope.project.default_task_status
newTask["project"] = $scope.project.id
newTask["user_story"] = $scope.us.id
$scope.newTask = $tgmodel.make_model("tasks", newTask)
render = -> render = ->
$scope.newRelatedTaskFormOpen = true $scope.openNewRelatedTask = true
$el.html($compile(template())($scope))
$el.find('input').focus().select()
$el.addClass('active')
$el.on "keyup", "input", (event)-> $el.on "keyup", "input", (event)->
if event.keyCode == 13 if event.keyCode == 13
createTask(newTask).then -> createTask(newTask).then ->
render() reset()
$el.find('input').focus()
else if event.keyCode == 27 else if event.keyCode == 27
$scope.$apply () -> close() $scope.$apply () -> close()
$el.on "click", ".icon-close", (event)-> $scope.save = () ->
$scope.$apply () -> close() createTask(newTask).then ->
close()
$el.on "click", ".icon-save", (event)-> taiga.bindOnce $scope, "us", reset
createTask(newTask).then ->
close()
taiga.bindOnce $scope, "us", (val) ->
newTask["status"] = $scope.project.default_task_status
newTask["project"] = $scope.project.id
newTask["user_story"] = $scope.us.id
$scope.newTask = $tgmodel.make_model("tasks", newTask)
$el.html("")
$scope.$on "related-tasks:show-form", -> $scope.$on "related-tasks:show-form", ->
render() $scope.$apply(render)
$scope.$on "$destroy", -> $scope.$on "$destroy", ->
$el.off() $el.off()
return {link: link} return {
scope: true,
link: link,
templateUrl: 'task/related-task-create-form.html'
}
module.directive("tgRelatedTaskCreateForm", ["$tgRepo", "$compile", "$tgConfirm", "$tgModel", "$tgLoading", module.directive("tgRelatedTaskCreateForm", ["$tgRepo", "$compile", "$tgConfirm", "$tgModel", "$tgLoading",
"$tgAnalytics", "$tgTemplate", RelatedTaskCreateFormDirective]) "$tgAnalytics", RelatedTaskCreateFormDirective])
RelatedTaskCreateButtonDirective = ($repo, $compile, $confirm, $tgmodel, $template) -> RelatedTaskCreateButtonDirective = ($repo, $compile, $confirm, $tgmodel, $template) ->
@ -287,6 +290,10 @@ RelatedTaskAssignedToInlineEditionDirective = ($repo, $rootscope, $translate) ->
notAutoSave = $scope.$eval($attrs.notAutoSave) notAutoSave = $scope.$eval($attrs.notAutoSave)
autoSave = !notAutoSave autoSave = !notAutoSave
$scope.$watch $attrs.tgRelatedTaskAssignedToInlineEdition, () ->
task = $scope.$eval($attrs.tgRelatedTaskAssignedToInlineEdition)
updateRelatedTask(task)
updateRelatedTask(task) updateRelatedTask(task)
$el.on "click", ".task-assignedto", (event) -> $el.on "click", ".task-assignedto", (event) ->

View File

@ -51,7 +51,9 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
params = {"project": projectId, "milestone": "null"} params = {"project": projectId, "milestone": "null"}
params = _.extend({}, params, filters or {}) params = _.extend({}, params, filters or {})
service.storeQueryParams(projectId, params) service.storeQueryParams(projectId, params)
return $repo.queryMany("userstories", params) return $repo.queryMany("userstories", params, {
enablePagination: true
}, true)
service.listAll = (projectId, filters) -> service.listAll = (projectId, filters) ->
params = {"project": projectId} params = {"project": projectId}

View File

@ -309,24 +309,22 @@ module.directive("tgTaskboard", ["$rootScope", TaskboardDirective])
TaskboardTaskDirective = ($rootscope, $loading, $rs, $rs2) -> TaskboardTaskDirective = ($rootscope, $loading, $rs, $rs2) ->
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
$el.disableSelection()
$scope.$watch "task", (task) -> $scope.$watch "task", (task) ->
if task.is_blocked and not $el.hasClass("blocked") if task.is_blocked and not $el.hasClass("blocked")
$el.addClass("blocked") $el.addClass("blocked")
else if not task.is_blocked and $el.hasClass("blocked") else if not task.is_blocked and $el.hasClass("blocked")
$el.removeClass("blocked") $el.removeClass("blocked")
$el.find(".icon-edit").on "click", (event) -> $el.find(".edit-task").on "click", (event) ->
if $el.find('.icon-edit').hasClass('noclick') if $el.find('.edit-task').hasClass('noclick')
return return
$scope.$apply -> $scope.$apply ->
target = $(event.target) target = $(event.target)
currentLoading = $loading() currentLoading = $loading()
.target(target) .target(target)
.timeout(200) .timeout(200)
.removeClasses("icon-edit")
.start() .start()
task = $scope.task task = $scope.task

View File

@ -39,9 +39,9 @@ module = angular.module("taigaBacklog")
TaskboardSortableDirective = ($repo, $rs, $rootscope) -> TaskboardSortableDirective = ($repo, $rs, $rootscope) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
bindOnce $scope, "project", (project) -> bindOnce $scope, "tasks", (xx) ->
# If the user has not enough permissions we don't enable the sortable # If the user has not enough permissions we don't enable the sortable
if not (project.my_permissions.indexOf("modify_us") > -1) if not ($scope.project.my_permissions.indexOf("modify_us") > -1)
return return
oldParentScope = null oldParentScope = null
@ -55,16 +55,22 @@ TaskboardSortableDirective = ($repo, $rs, $rootscope) ->
itemEl.off() itemEl.off()
itemEl.remove() itemEl.remove()
tdom.sortable({ containers = _.map $el.find('.task-column'), (item) ->
handle: ".taskboard-task-inner", return item
dropOnEmpty: true
connectWith: ".taskboard-tasks-box" drake = dragula(containers, {
revert: 400 copySortSource: false,
copy: false,
mirrorContainer: $el[0],
moves: (item) -> return $(item).hasClass('taskboard-task')
}) })
tdom.on "sortstop", (event, ui) -> drake.on 'drag', (item) ->
parentEl = ui.item.parent() oldParentScope = $(item).parent().scope()
itemEl = ui.item
drake.on 'dragend', (item) ->
parentEl = $(item).parent()
itemEl = $(item)
itemTask = itemEl.scope().task itemTask = itemEl.scope().task
itemIndex = itemEl.index() itemIndex = itemEl.index()
newParentScope = parentEl.scope() newParentScope = parentEl.scope()
@ -80,14 +86,17 @@ TaskboardSortableDirective = ($repo, $rs, $rootscope) ->
$scope.$apply -> $scope.$apply ->
$rootscope.$broadcast("taskboard:task:move", itemTask, newUsId, newStatusId, itemIndex) $rootscope.$broadcast("taskboard:task:move", itemTask, newUsId, newStatusId, itemIndex)
ui.item.find('a').removeClass('noclick') scroll = autoScroll(containers, {
margin: 20,
pixels: 30,
scrollWhenOutside: true,
autoScroll: () ->
return this.down && drake.dragging;
})
tdom.on "sortstart", (event, ui) -> $scope.$on "$destroy", ->
oldParentScope = ui.item.parent().scope() $el.off()
ui.item.find('a').addClass('noclick') drake.destroy()
$scope.$on "$destroy", ->
$el.off()
return {link: link} return {link: link}

View File

@ -117,6 +117,13 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
loadWikiLinks: -> loadWikiLinks: ->
return @rs.wiki.listLinks(@scope.projectId).then (wikiLinks) => return @rs.wiki.listLinks(@scope.projectId).then (wikiLinks) =>
@scope.wikiLinks = wikiLinks @scope.wikiLinks = wikiLinks
for link in @scope.wikiLinks
link.url = @navUrls.resolve("project-wiki-page", {
project: @scope.projectSlug
slug: link.href
})
selectedWikiLink = _.find(wikiLinks, {href: @scope.wikiSlug}) selectedWikiLink = _.find(wikiLinks, {href: @scope.wikiSlug})
@scope.wikiTitle = selectedWikiLink.title if selectedWikiLink? @scope.wikiTitle = selectedWikiLink.title if selectedWikiLink?
@ -258,8 +265,9 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $
currentLoading.finish() currentLoading.finish()
$el.on "click", "a", (event) -> $el.on "click", "a", (event) ->
target = angular.element(event.target) target = angular.element(event.currentTarget)
href = target.attr('href') href = target.attr('href')
if href.indexOf("#") == 0 if href.indexOf("#") == 0
event.preventDefault() event.preventDefault()
$('body').scrollTop($(href).offset().top) $('body').scrollTop($(href).offset().top)

View File

@ -35,7 +35,8 @@ module = angular.module("taigaWiki")
## Wiki Main Directive ## Wiki Main Directive
############################################################################# #############################################################################
WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $loading, $template, $compile, $translate) -> WikiNavDirective = ($tgrepo, $log, $location, $confirm, $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()
@ -59,18 +60,6 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l
$el.off() $el.off()
$el.html(html) $el.html(html)
$el.on "click", ".wiki-link .link-title", (event) ->
event.preventDefault()
target = angular.element(event.currentTarget)
linkId = target.parents('.wiki-link').data('id')
linkSlug = $scope.wikiLinks[linkId].href
$scope.$apply ->
ctx = {
project: $scope.projectSlug
slug: linkSlug
}
$location.path($navUrls.resolve("project-wiki-page", ctx))
$el.on "click", ".add-button", (event) -> $el.on "click", ".add-button", (event) ->
event.preventDefault() event.preventDefault()
$el.find(".new").removeClass("hidden") $el.find(".new").removeClass("hidden")
@ -146,5 +135,5 @@ 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", "$tgAnalytics",
"$tgAnalytics", "$tgLoading", "$tgTemplate", "$compile", "$translate", WikiNavDirective]) "$tgLoading", "$tgTemplate", "$compile", "$translate", WikiNavDirective])

View File

@ -22,6 +22,12 @@
# File: utils.coffee # File: utils.coffee
### ###
addClass = (el, className) ->
if (el.classList)
el.classList.add(className)
else
el.className += ' ' + className
nl2br = (str) => nl2br = (str) =>
breakTag = '<br />' breakTag = '<br />'
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2') return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2')
@ -222,6 +228,7 @@ patch = (oldImmutable, newImmutable) ->
return pathObj return pathObj
taiga = @.taiga taiga = @.taiga
taiga.addClass = addClass
taiga.nl2br = nl2br taiga.nl2br = nl2br
taiga.bindMethods = bindMethods taiga.bindMethods = bindMethods
taiga.bindOnce = bindOnce taiga.bindOnce = bindOnce

573
app/js/dom-autoscroller.js Normal file
View File

@ -0,0 +1,573 @@
// The MIT License (MIT)
// Copyright (c) 2016 Quentin Engles
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
(function() {
// more_events
function MoreEvents(context){
this.listeners = {};
this.__context = context || this;
}
MoreEvents.prototype = {
constructor: MoreEvents,
on: function(event, listener){
this.listeners[event] = this.listeners[event] || [];
this.listeners[event].push(listener);
return this;
},
one: function(event, listener){
function onceListener(){
listener.apply(this, arguments);
this.off(event, onceListener);
return this;
}
return this.on(event, onceListener);
},
emit: function(event){
if(typeof this.listeners[event] === 'undefined' || !this.listeners[event].length)
return this;
var args = Array.prototype.slice.call(arguments, 1),
canRun = this.listeners[event].length;
do{
this.listeners[event][--canRun].apply(this.__context, args);
}while(canRun);
return this;
},
off: function(event, listener){
if(this.listeners[event] === undefined || !this.listeners[event].length)
return this;
this.listeners[event] = this.listeners[event].filter(function(item){
return item !== listener;
});
return this;
},
dispose: function(){
for(var n in this){
this[n] = null;
}
}
};
// pointer_point
var Emitter = MoreEvents;
if(!Date.now){ Date.now = function(){ return new Date().getTime() } }
function LocalDimensions(point, rect){
for(var n in rect)
setProp(this, n, rect[n]);
setProp(this, 'x', point.x - rect.left+1);
setProp(this, 'y', point.y - rect.top+1);
setProp(this, 'north', (((rect.bottom - rect.top) / 2)-this.y));
setProp(this, 'south', ((-(rect.bottom - rect.top) / 2)+this.y));
setProp(this, 'east', (((rect.right - rect.left) / 2)-this.x));
setProp(this, 'west', ((-(rect.right - rect.left) / 2)+this.x));
function setProp(self, name, value){
Object.defineProperty(self, name, {
value: value,
configurable: true,
writable: false
});
}
}
function Point(elements){
var self = this, el = [];
if(typeof elements.length === 'undefined'){
elements = [elements];
}
for(var i=0; i<elements.length; i++){
if(elements[i] !== undefined){
if(typeof elements[i] === 'string'){
try{
el.push(document.querySelector(e));
}catch(err){
throw new Error(e + ' is not a valid selector used by pointer.');
}
}else{
el.push(elements[i]);
}
}
}
var pos = {}, direction = {}, rect, local,
lastmousex=-1, lastmousey=-1, timestamp, mousetravel = 0,
startX=-1, startY=-1, scrolling = false, buf = 10, timeOut = false,
downTime;
var special = {
hold: []
};
this.emitter = new Emitter(this);
this.origin = null;
this.current = null;
this.previous = null;
window.addEventListener('mousedown', onDown, false);
window.addEventListener('mousemove', onMove, false);
window.addEventListener("mouseup", onUp, false);
window.addEventListener('touchstart', onDown, false);
window.addEventListener('touchmove', onMove, false);
window.addEventListener('touchend', onUp, false);
window.addEventListener('scroll', function(e){
scrolling = true;
clearTimeout(timeOut)
timeOut = setTimeout(function(){
scrolling = false;
}, 100)
});
function onDown(e){
downTime = Date.now();
toPoint(e);
self.down = true;
self.up = false;
if(self.current){
self.origin = self.current;
self.emitter.emit('down', self.current, local);
}
startX = self.x;
startY = self.y;
}
function onMove(e){
toPoint(e);
self.emitter.emit('move', self.current, local);
if(self.down && self.current){
self.emitter.emit('stroke', self.current, local);
}
}
function onUp(e){
self.down = false;
self.up = true;
if(self.current){
self.emitter.emit('up', self.current, local);
}
if(e.targetTouches){
//Allow click within buf. A 20x20 square.
if(!(self.y > (startY - buf) && self.y < (startY + buf) &&
self.x > (startX - buf) && self.x < (startX + buf))){
//If there is scrolling there was a touch flick.
if(!scrolling){
//No touch flick so
self.previous = null;
self.origin = null;
e.preventDefault();
return false;
}
}
}
scrolling = false;
self.previous = null;
self.origin = null;
}
function toPoint(event){
var dot, eventDoc, doc, body, pageX, pageY;
var target, newTarget = null, leaving = null;
event = event || window.event; // IE-ism
target = event.target || event.srcElement;
//Supporting touch
//http://www.creativebloq.com/javascript/make-your-site-work-touch-devices-51411644
if(event.targetTouches) {
event.pageX = event.targetTouches[0].clientX;
event.pageY = event.targetTouches[0].clientY;
event.clientX = event.targetTouches[0].clientX;
event.clientY = event.targetTouches[0].clientY;
}else
// If pageX/Y aren't available and clientX/Y are,
// calculate pageX/Y - logic taken from jQuery.
// (This is to support old IE)
if (event.pageX === null && event.clientX !== null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
if(self.x && self.y){
if(event.pageX < self.x)
direction.h = 'left';
else if(event.pageX > self.x)
direction.h = 'right';
if(event.pageY < self.y)
direction.v = 'up';
else if(event.pageY > self.y)
direction.v = 'down';
lastmousex = self.x;
lastmousey = self.y;
}
pos = {};
//Prefer the viewport with clientX, and clientY.
//pageX, and pageY change too often.
pos.x = event.clientX;//event.pageX;
pos.y = event.clientY;//event.pageY;
if(self.current === null || self.outside(self.current)){
for(var i=0; i<el.length; i++){
//console.log('inside el['+i+'] '+self.inside(el[i]));
if(el[i] === target || self.inside(el[i])){
//if(el[i] === target){
newTarget = el[i];
break;
}
}
leaving = self.current;
if(newTarget){
self.previous = self.current;
self.current = newTarget;
}
}
rect = self.current ? getRect(self.current) : null;
local = rect ? new LocalDimensions(self, rect) : null;
if(leaving){
if(!newTarget)
self.current = null;
self.emitter.emit('leave', leaving, local);
}
if(newTarget){
self.emitter.emit('enter', self.current, local);
}
}
//Get speed
//http://stackoverflow.com/questions/6417036/track-mouse-speed-with-js
Object.defineProperty(this, 'speedX', {
get: function(){
var now = Date.now() / 1000;
var dt = now - timestamp;
var dx = self.x - lastmousex;
timestamp = now;
return Math.round(dx / dt);// * 1000);
}
});
Object.defineProperty(this, 'speedY', {
get: function(){
var now = Date.now() / 1000;
var dt = now - timestamp;
var dy = self.y - lastmousey;
timestamp = now;
return Math.round(dy / dt);// * 1000);
}
});
Object.defineProperty(this, 'x', {
get: function(){
return pos.x;
}
});
Object.defineProperty(this, 'y', {
get: function(){
return pos.y;
}
});
Object.defineProperty(this, 'h', {
get: function(){
return direction.h;
}
});
Object.defineProperty(this, 'v', {
get: function(){
return direction.v;
}
});
this.emitter.on('up', function(el, rect){
if(downTime){
for(var i=0; i<special.hold.length; i++){
if(Date.now() > downTime + (special.hold[i].data || 2000)){
special.hold[i].callback.call(this, el, rect);
}
}
}
downTime = 0;
});
function removeSpecial(event, cb){
for(var i=0; i<special[event].length; i++){
if(special[event][i].callback === cb){
special[event].splice(i, 1);
return;
}
}
}
function addSpecial(event, data, cb){
if(typeof cb === 'undefined'){
cb = data;
data = null;
}
special[event].push({
data: data,
callback: cb
})
}
this.on = function(event, cb){
if(special[event]){
addSpecial(event, cb, arguments[2]);
return this;
}
this.emitter.on(event, cb);
return this;
};
this.off = function(event, cb){
if(special[event]){
removeSpecial(event, cb);
return this;
}
this.emitter.off(event, cb);
return this;
};
this.add = function(element){
if(typeof element === 'string'){
try{
el.push(document.querySelector(e));
}catch(err){
throw new Error(e + ' is not a valid selector, and can\'t be used add to pointer.');
}
}else if(!element){
throw new Error(e + ' can not be added to pointer.');
}
el.push(element);
};
this.destroy = function(){
window.removeEventListener('mousedown', onDown, false);
window.removeEventListener('mousemove', onMove, false);
window.removeEventListener('mouseup', onUp, false);
window.removeEventListener('touchstart', onDown, false);
window.removeEventListener('touchmove', onMove, false);
window.removeEventListener('touchend', onUp, false);
el = null;
self = null;
pos = null;
direction = null;
};
}
Point.prototype = {
constructor: Point,
inside: function(el){
if(!el) throw new TypeError('Cannot be inside '+el);
var rect = getRect(el);
return (this.y > rect.top && this.y < rect.bottom &&
this.x > rect.left && this.x < rect.right);
},
outside: function(el){
if(!el) throw new TypeError('Cannot be outside '+el);
return !this.inside(el);
}
};
function elementFromPoint(x, y){
if(document.getElementFromPoint)
return document.getElementFromPoint(x, y);
else
return document.elementFromPoint(x, y);
return null;
}
function safeObject(src){
var obj = {};
for(var n in src)
obj[n] = src[n];
return obj;
}
function getRect(el){
if(el === window){
return {
top: 0,
left: 0,
right: window.innerWidth,
bottom: window.innerHeight,
width: window.innerWidth,
height: window.innerHeight
};
}else{
return el.getBoundingClientRect();
}
}
var pointer = function(element){
return new Point(element);
};
// Autscroller
function AutoScrollerFactory(element, options){
return new AutoScroller(element, options);
}
function AutoScroller(elements, options){
var self = this, pixels = 2;
options = options || {};
this.margin = options.margin || -1;
this.scrolling = false;
this.scrollWhenOutside = options.scrollWhenOutside || false;
this.point = pointer(elements);
if(!isNaN(options.pixels)){
pixels = options.pixels;
}
if(typeof options.autoScroll === 'boolean'){
this.autoScroll = options.autoScroll ? function(){return true;} : function(){return false;};
}else if(typeof options.autoScroll === 'undefined'){
this.autoScroll = function(){return false;};
}else if(typeof options.autoScroll === 'function'){
this.autoScroll = options.autoScroll;
}
this.destroy = function() {
this.point.destroy();
};
Object.defineProperties(this, {
down: {
get: function(){ return self.point.down; }
},
interval: {
get: function(){ return 1/pixels * 1000; }
},
pixels: {
set: function(i){ pixels = i; },
get: function(){ return pixels; }
}
});
this.point.on('move', function(el, rect){
if(!el) return;
if(!self.autoScroll()) return;
if(!self.scrollWhenOutside && this.outside(el)) return;
if(self.point.y < rect.top + self.margin){
autoScrollV(el, -1, rect);
}else if(self.point.y > rect.bottom - self.margin){
autoScrollV(el, 1, rect);
}
if(self.point.x < rect.left + self.margin){
autoScrollH(el, -1, rect);
}else if(self.point.x > rect.right - self.margin){
autoScrollH(el, 1, rect);
}
});
function autoScrollV(el, amount, rect){
//if(!self.down) return;
if(!self.autoScroll()) return;
if(!self.scrollWhenOutside && self.point.outside(el)) return;
if(el === window){
window.scrollTo(el.pageXOffset, el.pageYOffset + amount);
}else{
el.scrollTop = el.scrollTop + amount;
}
setTimeout(function(){
if(self.point.y < rect.top + self.margin){
autoScrollV(el, amount, rect);
}else if(self.point.y > rect.bottom - self.margin){
autoScrollV(el, amount, rect);
}
}, self.interval);
}
function autoScrollH(el, amount, rect){
//if(!self.down) return;
if(!self.autoScroll()) return;
if(!self.scrollWhenOutside && self.point.outside(el)) return;
if(el === window){
window.scrollTo(el.pageXOffset + amount, el.pageYOffset);
}else{
el.scrollLeft = el.scrollLeft + amount;
}
setTimeout(function(){
if(self.point.x < rect.left + self.margin){
autoScrollH(el, amount, rect);
}else if(self.point.x > rect.right - self.margin){
autoScrollH(el, amount, rect);
}
}, self.interval);
}
}
window.autoScroll = AutoScrollerFactory;
}());

View File

@ -0,0 +1,221 @@
(function() {
var multipleSortableClass = 'ui-multisortable-multiple';
var mainClass = 'main-drag-item';
var inProgress = false;
var reset = function(elm) {
$(elm)
.removeAttr('style')
.removeClass('tg-backlog-us-mirror')
.removeClass('backlog-us-mirror')
.data('dragMultipleIndex', null)
.data('dragMultipleActive', false);
};
var sort = function(positions) {
var current = dragMultiple.items.elm;
positions.after.reverse();
$.each(positions.after, function () {
reset(this);
current.after(this);
});
$.each(positions.before, function () {
reset(this);
current.before(this);
});
};
var drag = function() {
var current = dragMultiple.items.elm;
var container = dragMultiple.items.container;
var shadow = dragMultiple.items.shadow;
// following the drag element
var currentLeft = shadow.position().left;
var currentTop = shadow.position().top;
var height = shadow.outerHeight();
_.forEach(dragMultiple.items.draggingItems, function(elm, index) {
var elmIndex = parseInt(elm.data('dragMultipleIndex'), 10);
var top = currentTop + (elmIndex * height);
elm
.css({
top: top,
left: currentLeft
});
});
};
var stop = function() {
inProgress = false;
refreshOriginal();
var current = dragMultiple.items.elm;
var container = dragMultiple.items.container;
$(window).off('mousemove.dragmultiple');
// reset
dragMultiple.items = {};
$('.' + mainClass).removeClass(mainClass);
$('.tg-backlog-us-mirror').remove();
$('.backlog-us-mirror').removeClass('backlog-us-mirror');
$('.tg-backlog-us-dragging')
.removeClass('tg-backlog-us-dragging')
.show();
return $('.' + multipleSortableClass);
};
var refreshOriginal = function() {
var index = parseInt(dragMultiple.items.elm.data('dragMultipleIndex'), 10);
var after = [];
var before = [];
_.forEach(dragMultiple.items.draggedItemsOriginal, function(item) {
if (parseInt($(item).data('dragMultipleIndex'), 10) > index) {
after.push(item);
} else {
before.push(item);
}
});
after.reverse();
_.forEach(after, function(item) {
$(item).insertAfter(dragMultiple.items.elm);
});
_.forEach(before, function(item) {
$(item).insertBefore(dragMultiple.items.elm);
});
};
var isMultiple = function(elm, container) {
var items = $(container).find('.' + multipleSortableClass);
if (!$(elm).hasClass(multipleSortableClass) || !(items.length > 1)) {
return false;
}
return true;
};
var setIndex = function(items) {
var before = [];
var after = [];
var mainFound = false;
_.forEach(items, function(item, index) {
if ($(item).data('dragMultipleIndex') === 0) {
mainFound = true;
return;
}
if (mainFound) {
after.push(item);
} else {
before.push(item);
}
});
before.reverse();
_.forEach(after, function(item, index) {
$(item).data('dragMultipleIndex', index + 1);
});
_.forEach(before, function(item, index) {
$(item).data('dragMultipleIndex', -index - 1);
});
};
var dragMultiple = {};
dragMultiple.prepare = function(elm, container) {
inProgress = true;
var items = $(container).find('.' + multipleSortableClass);
$(elm)
.data('dragmultiple:originalPosition', $(elm).position())
.data('dragMultipleActive', true);
dragMultiple.items = {};
dragMultiple.items.elm = $(elm);
dragMultiple.items.container = $(container);
dragMultiple.items.elm.data('dragMultipleIndex', 0);
setIndex(items);
dragMultiple.items.shadow = $('.gu-mirror');
dragMultiple.items.elm.addClass(mainClass);
items = _.filter(items, function(item) {
return !$(item).hasClass(mainClass);
});
dragMultiple.items.draggedItemsOriginal = items;
var itemsCloned = _.map(items, function (item) {
clone = $(item).clone(true);
clone
.addClass('backlog-us-mirror')
.addClass('tg-backlog-us-mirror')
.data('dragmultiple:originalPosition', $(item).position())
.data('dragMultipleActive', true)
.css({
zIndex: '9999',
opacity: '0.8',
position: 'fixed',
width: dragMultiple.items.elm.outerWidth(),
height: dragMultiple.items.elm.outerHeight()
});
$(item)
.hide()
.addClass('tg-backlog-us-dragging');
return clone;
});
dragMultiple.items.draggingItems = itemsCloned;
$(document.body).append(itemsCloned);
};
dragMultiple.start = function(item, container) {
if (isMultiple(item, container)) {
$(window).on('mousemove.dragmultiple', function() {
if (!inProgress) {
dragMultiple.prepare(item, container);
}
drag();
});
}
};
dragMultiple.stop = function() {
if (inProgress) {
return stop();
} else {
return [];
}
};
window.dragMultiple = dragMultiple;
}());

View File

@ -1,161 +0,0 @@
(function($) {
var multipleSortableClass = 'ui-multisortable-multiple';
var dragStarted = false;
var multiSort = {};
multiSort.isBelow = function(elm, compare) {
var elmOriginalPosition = elm.data('dragmultiple:originalPosition');
var compareOriginalPosition = compare.data('dragmultiple:originalPosition');
return elmOriginalPosition.top > compareOriginalPosition.top;
};
multiSort.reset = function(elm) {
$(elm)
.removeClass("ui-sortable-helper")
.removeAttr('style')
.data('dragMultipleActive', false);
};
multiSort.sort = function(current, positions) {
positions.after.reverse();
$.each(positions.after, function () {
multiSort.reset(this);
current.after(this);
});
$.each(positions.before, function () {
multiSort.reset(this);
current.before(this);
});
};
multiSort.sortPositions = function(elm, current) {
//saved if the elements are after or before the current
var insertAfter = [];
var insertBefore = [];
$(elm).find('.' + multipleSortableClass).each(function () {
var elm = $(this);
if (elm[0] === current[0] || !current.hasClass(multipleSortableClass)) return;
if (multiSort.isBelow(elm, current)) {
insertAfter.push(elm);
} else {
insertBefore.push(elm);
}
});
return {'after': insertAfter, 'before': insertBefore};
};
$.widget( "ui.sortable", $.ui.sortable, {
_mouseStart: function() {
dragStarted = false;
this._superApply( arguments );
},
_createHelper: function () {
var helper = this._superApply( arguments );
if ($(helper).hasClass(multipleSortableClass)) {
$(this.element).find('.' + multipleSortableClass).each(function () {
$(this)
.data('dragmultiple:originalPosition', $(this).position())
.data('dragMultipleActive', true);
});
}
return helper;
},
_mouseStop: function (event, ui) {
var current = this.helper;
var elms = [];
if (current.hasClass(multipleSortableClass)) {
elms = $(this.element).find('.' + multipleSortableClass);
}
if (!elms.length) {
elms = [current];
}
//save the order of the elements relative to the main
var positions = multiSort.sortPositions(this.element, current);
this._superApply( arguments );
if (this.element !== this.currentContainer.element) {
// change to another sortable list
multiSort.sort(current, positions);
$(this.currentContainer.element).trigger('multiplesortreceive', {
'item': current,
'items': elms,
'source': this.element
});
} else if (current.hasClass(multipleSortableClass)) {
// sort in the same list
multiSort.sort(current, positions);
}
$(this.element).trigger('multiplesortstop', {
'item': current,
'items': elms
});
},
_mouseDrag: function(key, value) {
this._super(key, value);
var current = this.helper;
if (!current.hasClass(multipleSortableClass)) return;
// following the drag element
var currentLeft = current.position().left;
var currentTop = current.position().top;
var currentZIndex = current.css('z-index');
var currentPosition = current.css('position');
var positions = multiSort.sortPositions(this.element, current);
positions.before.reverse();
[{'positions': positions.after, type: 'after'},
{'positions': positions.before, type: 'before'}]
.forEach(function (item) {
$.each(item.positions, function (index, elm) {
var top;
if (item.type === 'after') {
top = currentTop + ((index + 1) * current.outerHeight());
} else {
top = currentTop - ((index + 1) * current.outerHeight());
}
elm
.addClass("ui-sortable-helper")
.css({
width: elm.outerWidth(),
height: elm.outerHeight(),
position: currentPosition,
zIndex: currentZIndex,
top: top,
left: currentLeft
});
});
});
// it only refresh position the first time because
// jquery-ui has saved the old positions of the draggable elements
// and with this will remove all elements with dragMultipleActive
if (!dragStarted) {
dragStarted = true;
this.refreshPositions();
}
}
});
}(jQuery))

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "Nota de bloqueig", "BLOCKED_NOTE": "Nota de bloqueig",
"IS_BLOCKED": "està bloquejat", "IS_BLOCKED": "està bloquejat",
"REF": "Ref", "REF": "Ref",
"VOTES": "Vots" "VOTES": "Vots",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Tot" "ALL": "Tot"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Home - Taiga", "PAGE_TITLE": "Home - Taiga",
"PAGE_DESCRIPTION": "La home de Taiga amb els teus projectes principals, totes les històries d'usuari, tasques i incidències que tens assignades i aquelles que estàs Watching", "PAGE_DESCRIPTION": "La home de Taiga amb els teus projectes principals, totes les històries d'usuari, tasques i incidències que tens assignades i aquelles que estàs Watching",
"EMPTY_WORKING_ON": "<strong>Sembla buit, no?</strong> Comenceu a treballar amb Taiga i voràs ací les históries, tasques e incidències en les que estás treballant.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Segueix</strong> históries, tasques e incidéncies en els teus project i rep notificacions quan canvien :)", "EMPTY_WATCHING": "<strong>Segueix</strong> históries, tasques e incidéncies en els teus project i rep notificacions quan canvien :)",
"EMPTY_PROJECT_LIST": "No tens cap projecte encara", "EMPTY_PROJECT_LIST": "No tens cap projecte encara",
"WORKING_ON_SECTION": "En Progrés", "WORKING_ON_SECTION": "En Progrés",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Rols - {{projectName}}", "PAGE_TITLE": "Rols - {{projectName}}",
"WARNING_NO_ROLE": "Ves amb compte, cap rol en el teu projecte pot estimar punts per a les històries d'usuari", "WARNING_NO_ROLE": "Ves amb compte, cap rol en el teu projecte pot estimar punts per a les històries d'usuari",
"HELP_ROLE_ENABLED": "Si està activat, els membres assignats a aquest rol podràn estimar els punts d'històries d'usuaris", "HELP_ROLE_ENABLED": "Si està activat, els membres assignats a aquest rol podràn estimar els punts d'històries d'usuaris",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disable estimation for this role", "DISABLE_COMPUTABLE_ALERT_TITLE": "Are you sure you want to disable this role estimations?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} membres amb aquest rol", "COUNT_MEMBERS": "{{ role.members_count }} membres amb aquest rol",
"TITLE_DELETE_ROLE": "Esborrar rol", "TITLE_DELETE_ROLE": "Esborrar rol",
"REPLACEMENT_ROLE": "Tots els usuaris amb aquest rol es canviaran a", "REPLACEMENT_ROLE": "Tots els usuaris amb aquest rol es canviaran a",
@ -699,7 +699,6 @@
"ACCEPT": "Acceptar", "ACCEPT": "Acceptar",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Esciu pàgina del Wiki", "PLACEHOLDER_PAGE": "Esciu pàgina del Wiki",
"REMOVE": "Esborrar pàgina de Wiki", "REMOVE": "Esborrar pàgina de Wiki",
"DELETE_LIGHTBOX_TITLE": "Esborrar pàgina de Wiki", "DELETE_LIGHTBOX_TITLE": "Esborrar pàgina de Wiki",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Enllaços", "SECTION_NAME": "Enllaços",
"ACTION_ADD_LINK": "Afegir link" "ACTION_ADD_LINK": "Afegir link"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "Blockierungsgrund", "BLOCKED_NOTE": "Blockierungsgrund",
"IS_BLOCKED": "wird blockiert", "IS_BLOCKED": "wird blockiert",
"REF": "Ref", "REF": "Ref",
"VOTES": "Stimmen" "VOTES": "Stimmen",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Alle" "ALL": "Alle"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Home - Taiga", "PAGE_TITLE": "Home - Taiga",
"PAGE_DESCRIPTION": "Die Taiga Homepage mit Ihren wichtigsten Projekten und all Ihren zugeordneten und beobachteten User-Stories, Aufgaben und Tickets.", "PAGE_DESCRIPTION": "Die Taiga Homepage mit Ihren wichtigsten Projekten und all Ihren zugeordneten und beobachteten User-Stories, Aufgaben und Tickets.",
"EMPTY_WORKING_ON": "<strong>Hier siehts ziemlich leer aus, oder?</strong> Beginne deine Arbeit mit Taiga und wir zeigen dir hier die Stories, Tasks und Issues an denen du arbeitest.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Folge</strong> User Stories, Tasks, Issues in deinem Projekt und erhalte Benachrichtigungen, wenn sich etwas ändert. :)", "EMPTY_WATCHING": "<strong>Folge</strong> User Stories, Tasks, Issues in deinem Projekt und erhalte Benachrichtigungen, wenn sich etwas ändert. :)",
"EMPTY_PROJECT_LIST": "Sie haben noch keine Projekte", "EMPTY_PROJECT_LIST": "Sie haben noch keine Projekte",
"WORKING_ON_SECTION": "Zuletzt bearbeitet", "WORKING_ON_SECTION": "Zuletzt bearbeitet",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Rollen - {{projectName}}", "PAGE_TITLE": "Rollen - {{projectName}}",
"WARNING_NO_ROLE": "Beachten Sie, keine Rolle in Ihrem Projekt wird in der Lage sein, die Punktevergabe für User-Stories einzuschätzen.", "WARNING_NO_ROLE": "Beachten Sie, keine Rolle in Ihrem Projekt wird in der Lage sein, die Punktevergabe für User-Stories einzuschätzen.",
"HELP_ROLE_ENABLED": "Wenn Sie dies freischalten, werden Mitglieder, denen diese Rolle zugewiesen ist, in der Lage sein, die Punktevergabe für User-Stories vorzunehmen.", "HELP_ROLE_ENABLED": "Wenn Sie dies freischalten, werden Mitglieder, denen diese Rolle zugewiesen ist, in der Lage sein, die Punktevergabe für User-Stories vorzunehmen.",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Deaktiviere Estimatepoints für diese Rolle", "DISABLE_COMPUTABLE_ALERT_TITLE": "Bist du sicher, dass in dieser Rolle Estimatepoints deaktivieren möchtest?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Wenn du die Estimatepoints für die Rolle {{roleName}} deaktivierst, werden alle bisherigen gelöscht", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Wenn du die Estimatepoints für die Rolle {{roleName}} deaktivierst, werden alle bisherigen gelöscht",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Bist du sicher, dass in dieser Rolle Estimatepoints deaktivieren möchtest?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} Mitglieder mit dieser Rolle", "COUNT_MEMBERS": "{{ role.members_count }} Mitglieder mit dieser Rolle",
"TITLE_DELETE_ROLE": "Rolle löschen", "TITLE_DELETE_ROLE": "Rolle löschen",
"REPLACEMENT_ROLE": "Alle Benutzer mit dieser Rolle werden verschoben nach", "REPLACEMENT_ROLE": "Alle Benutzer mit dieser Rolle werden verschoben nach",
@ -699,7 +699,6 @@
"ACCEPT": "Akzeptieren", "ACCEPT": "Akzeptieren",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Schreiben Sie Ihre Wiki Seite", "PLACEHOLDER_PAGE": "Schreiben Sie Ihre Wiki Seite",
"REMOVE": "Diese Wiki Seite entfernen", "REMOVE": "Diese Wiki Seite entfernen",
"DELETE_LIGHTBOX_TITLE": "Wiki Seite löschen", "DELETE_LIGHTBOX_TITLE": "Wiki Seite löschen",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Links", "SECTION_NAME": "Links",
"ACTION_ADD_LINK": "Link hinzufügen" "ACTION_ADD_LINK": "Link hinzufügen"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "blocked note", "BLOCKED_NOTE": "blocked note",
"IS_BLOCKED": "is blocked", "IS_BLOCKED": "is blocked",
"REF": "Ref", "REF": "Ref",
"VOTES": "Votes" "VOTES": "Votes",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "All" "ALL": "All"
@ -224,6 +225,7 @@
"CODE_BLOCK_SAMPLE_TEXT": "Your text here...", "CODE_BLOCK_SAMPLE_TEXT": "Your text here...",
"PREVIEW_BUTTON": "Preview", "PREVIEW_BUTTON": "Preview",
"EDIT_BUTTON": "Edit", "EDIT_BUTTON": "Edit",
"ATTACH_FILE_HELP": "Attach files by dragging & dropping on the textarea above.",
"MARKDOWN_HELP": "Markdown syntax help" "MARKDOWN_HELP": "Markdown syntax help"
}, },
"PERMISIONS_CATEGORIES": { "PERMISIONS_CATEGORIES": {
@ -355,7 +357,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Home - Taiga", "PAGE_TITLE": "Home - Taiga",
"PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues", "PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues",
"EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are workin on.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)", "EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)",
"EMPTY_PROJECT_LIST": "You don't have any projects yet", "EMPTY_PROJECT_LIST": "You don't have any projects yet",
"WORKING_ON_SECTION": "Working on", "WORKING_ON_SECTION": "Working on",
@ -556,9 +558,8 @@
"PAGE_TITLE": "Roles - {{projectName}}", "PAGE_TITLE": "Roles - {{projectName}}",
"WARNING_NO_ROLE": "Be careful, no role in your project will be able to estimate the point value for user stories", "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", "HELP_ROLE_ENABLED": "When enabled, members assigned to this role will be able to estimate the point value for user stories",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disable estimation for this role", "DISABLE_COMPUTABLE_ALERT_TITLE": "Are you sure you want to disable this role estimations?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} members with this role", "COUNT_MEMBERS": "{{ role.members_count }} members with this role",
"TITLE_DELETE_ROLE": "Delete Role", "TITLE_DELETE_ROLE": "Delete Role",
"REPLACEMENT_ROLE": "All the users with this role will be moved to", "REPLACEMENT_ROLE": "All the users with this role will be moved to",
@ -699,7 +700,6 @@
"ACCEPT": "Accept", "ACCEPT": "Accept",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1413,7 @@
"PLACEHOLDER_PAGE": "Write your wiki page", "PLACEHOLDER_PAGE": "Write your wiki page",
"REMOVE": "Remove this wiki page", "REMOVE": "Remove this wiki page",
"DELETE_LIGHTBOX_TITLE": "Delete Wiki Page", "DELETE_LIGHTBOX_TITLE": "Delete Wiki Page",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Links", "SECTION_NAME": "Links",
"ACTION_ADD_LINK": "Add link" "ACTION_ADD_LINK": "Add link"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "Motivo del bloqueo", "BLOCKED_NOTE": "Motivo del bloqueo",
"IS_BLOCKED": "está bloqueada", "IS_BLOCKED": "está bloqueada",
"REF": "Ref", "REF": "Ref",
"VOTES": "Votos" "VOTES": "Votos",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Todos" "ALL": "Todos"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Inicio - Taiga", "PAGE_TITLE": "Inicio - Taiga",
"PAGE_DESCRIPTION": "Página de inicio de Taiga, con tus proyectos principales y tus historias de usuario, tareas y peticiones en progreso asignadas y las que observas.", "PAGE_DESCRIPTION": "Página de inicio de Taiga, con tus proyectos principales y tus historias de usuario, tareas y peticiones en progreso asignadas y las que observas.",
"EMPTY_WORKING_ON": "<strong>Parece vacío no?</ strong> Empiece a trabajar con Taiga y verá aquí las historias, las tareas y los incidentes en los que está trabajando.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Sigue</strong> Historias de Usuario, Tareas y Peticiones en tus proyectos y se te notificará sobre sus cambios :)", "EMPTY_WATCHING": "<strong>Sigue</strong> Historias de Usuario, Tareas y Peticiones en tus proyectos y se te notificará sobre sus cambios :)",
"EMPTY_PROJECT_LIST": "Todavía no tienes ningún proyecto", "EMPTY_PROJECT_LIST": "Todavía no tienes ningún proyecto",
"WORKING_ON_SECTION": "Trabajando en", "WORKING_ON_SECTION": "Trabajando en",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Roles - {{projectName}}", "PAGE_TITLE": "Roles - {{projectName}}",
"WARNING_NO_ROLE": "Ojo, ningún rol en tu proyecto podrá estimar historias de usuario", "WARNING_NO_ROLE": "Ojo, ningún rol en tu proyecto podrá estimar historias de usuario",
"HELP_ROLE_ENABLED": "Si lo activas, los miembros que posean este rol serán capaces de estimar las histórias de usuario", "HELP_ROLE_ENABLED": "Si lo activas, los miembros que posean este rol serán capaces de estimar las histórias de usuario",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Deshabilitar las estimaciones para este rol", "DISABLE_COMPUTABLE_ALERT_TITLE": "¿Seguro de que deseas deshabilitar las estimaciones para este rol?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Si desactivas los permisos de estimación para el rol {{roleName}} todas las estimaciones previas hechas por ese rol se eliminarán", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Si desactivas los permisos de estimación para el rol {{roleName}} todas las estimaciones previas hechas por ese rol se eliminarán",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>¿Seguro de que deseas deshabilitar las estimaciones para este rol?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} miembros con este rol", "COUNT_MEMBERS": "{{ role.members_count }} miembros con este rol",
"TITLE_DELETE_ROLE": "Borrar Rol", "TITLE_DELETE_ROLE": "Borrar Rol",
"REPLACEMENT_ROLE": "Todos los usuarios con este rol serán movidos a", "REPLACEMENT_ROLE": "Todos los usuarios con este rol serán movidos a",
@ -699,7 +699,6 @@
"ACCEPT": "Aceptar", "ACCEPT": "Aceptar",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Escribe el contenido de tu página", "PLACEHOLDER_PAGE": "Escribe el contenido de tu página",
"REMOVE": "Eliminar esta página del wiki", "REMOVE": "Eliminar esta página del wiki",
"DELETE_LIGHTBOX_TITLE": "Eliminar Página del Wiki", "DELETE_LIGHTBOX_TITLE": "Eliminar Página del Wiki",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Enlaces", "SECTION_NAME": "Enlaces",
"ACTION_ADD_LINK": "Añadir enlace" "ACTION_ADD_LINK": "Añadir enlace"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "estetty muistiinpano", "BLOCKED_NOTE": "estetty muistiinpano",
"IS_BLOCKED": "on estetty", "IS_BLOCKED": "on estetty",
"REF": "Ref", "REF": "Ref",
"VOTES": "Ääniä" "VOTES": "Ääniä",
"SPRINT": "Kierros"
}, },
"ROLES": { "ROLES": {
"ALL": "Kaikki" "ALL": "Kaikki"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Home - Taiga", "PAGE_TITLE": "Home - Taiga",
"PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues", "PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues",
"EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are workin on.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)", "EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)",
"EMPTY_PROJECT_LIST": "You don't have any projects yet", "EMPTY_PROJECT_LIST": "You don't have any projects yet",
"WORKING_ON_SECTION": "Working on", "WORKING_ON_SECTION": "Working on",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Roles - {{projectName}}", "PAGE_TITLE": "Roles - {{projectName}}",
"WARNING_NO_ROLE": "Ole varovainen, yksikään rooli projektissasi ei voi arvioida käyttäjätarinoidesi kokoa", "WARNING_NO_ROLE": "Ole varovainen, yksikään rooli projektissasi ei voi arvioida käyttäjätarinoidesi kokoa",
"HELP_ROLE_ENABLED": "Tämän roolin omaavat jäsenet voivat arvioida käyttäjätarinoiden kokoja", "HELP_ROLE_ENABLED": "Tämän roolin omaavat jäsenet voivat arvioida käyttäjätarinoiden kokoja",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disable estimation for this role", "DISABLE_COMPUTABLE_ALERT_TITLE": "Are you sure you want to disable this role estimations?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} jäsentä joilla tämä rooli", "COUNT_MEMBERS": "{{ role.members_count }} jäsentä joilla tämä rooli",
"TITLE_DELETE_ROLE": "Poista rooli", "TITLE_DELETE_ROLE": "Poista rooli",
"REPLACEMENT_ROLE": "Kaikki käyttäjä joilla on tämä rooli siirretään", "REPLACEMENT_ROLE": "Kaikki käyttäjä joilla on tämä rooli siirretään",
@ -699,7 +699,6 @@
"ACCEPT": "Hyväksy", "ACCEPT": "Hyväksy",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Kirjoita wiki-sivu", "PLACEHOLDER_PAGE": "Kirjoita wiki-sivu",
"REMOVE": "Poista tämä wiki-sivu", "REMOVE": "Poista tämä wiki-sivu",
"DELETE_LIGHTBOX_TITLE": "Poista wiki-sivu", "DELETE_LIGHTBOX_TITLE": "Poista wiki-sivu",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Linkit", "SECTION_NAME": "Linkit",
"ACTION_ADD_LINK": "Lisää linkki" "ACTION_ADD_LINK": "Lisää linkki"

View File

@ -42,7 +42,7 @@
"CLIENT_REQUIREMENT": "Un besoin client est un nouveau besoin qui n'était pas prévu et qu'il est nécessaire d'intégrer au projet", "CLIENT_REQUIREMENT": "Un besoin client est un nouveau besoin qui n'était pas prévu et qu'il est nécessaire d'intégrer au projet",
"TEAM_REQUIREMENT": "Un besoin projet est un besoin qui est nécessaire au projet mais qui ne doit avoir aucun impact pour le client", "TEAM_REQUIREMENT": "Un besoin projet est un besoin qui est nécessaire au projet mais qui ne doit avoir aucun impact pour le client",
"OWNER": "Propriétaire du Projet", "OWNER": "Propriétaire du Projet",
"CAPSLOCK_WARNING": "Be careful! You are using capital letters in an input field that is case sensitive.", "CAPSLOCK_WARNING": "Attention ! Vous utilisez des majuscules dans un champ qui est sensible à la casse.",
"FORM_ERRORS": { "FORM_ERRORS": {
"DEFAULT_MESSAGE": "Cette valeur semble être invalide.", "DEFAULT_MESSAGE": "Cette valeur semble être invalide.",
"TYPE_EMAIL": "Cette valeur devrait être une adresse courriel valide.", "TYPE_EMAIL": "Cette valeur devrait être une adresse courriel valide.",
@ -67,8 +67,8 @@
"MAX_CHECK": "Vous devez sélectionner %s options ou moins.", "MAX_CHECK": "Vous devez sélectionner %s options ou moins.",
"RANGE_CHECK": "Vous devez sélectionner parmi les choix %s et %s.", "RANGE_CHECK": "Vous devez sélectionner parmi les choix %s et %s.",
"EQUAL_TO": "Cette valeur doit être identique.", "EQUAL_TO": "Cette valeur doit être identique.",
"LINEWIDTH": "One or more lines is perhaps too long. Try to keep under %s characters.", "LINEWIDTH": "Une ou plusieurs lignes est peut-être trop long. Essayez de rester en dessous de %s caractères.",
"PIKADAY": "Invalid date format, please use DD MMM YYYY (like 23 Mar 1984)" "PIKADAY": "Format de date non valide, merci d'utiliser JJ MMM AAAA (comme 23 mar 1984)"
}, },
"PICKERDATE": { "PICKERDATE": {
"FORMAT": "DD MMM YYYY", "FORMAT": "DD MMM YYYY",
@ -140,7 +140,8 @@
"BLOCKED_NOTE": "note bloquée", "BLOCKED_NOTE": "note bloquée",
"IS_BLOCKED": "est bloqué", "IS_BLOCKED": "est bloqué",
"REF": "Réf.", "REF": "Réf.",
"VOTES": "Votes" "VOTES": "Votes",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Tout" "ALL": "Tout"
@ -283,7 +284,7 @@
}, },
"LOGIN_COMMON": { "LOGIN_COMMON": {
"HEADER": "J'ai déjà un identifiant Taiga", "HEADER": "J'ai déjà un identifiant Taiga",
"PLACEHOLDER_AUTH_NAME": "Nom d'utilisateur ou adresse courriel (sensible à la casse)", "PLACEHOLDER_AUTH_NAME": "Nom d'utilisateur ou courriel (sensible à la casse)",
"LINK_FORGOT_PASSWORD": "Mot de passe oublié ?", "LINK_FORGOT_PASSWORD": "Mot de passe oublié ?",
"TITLE_LINK_FORGOT_PASSWORD": "Avez-vous oublié votre mot de passe ?", "TITLE_LINK_FORGOT_PASSWORD": "Avez-vous oublié votre mot de passe ?",
"ACTION_ENTER": "Entrer", "ACTION_ENTER": "Entrer",
@ -318,8 +319,8 @@
"PLACEHOLDER_FIELD": "Nom d'utilisateur ou adresse courriel", "PLACEHOLDER_FIELD": "Nom d'utilisateur ou adresse courriel",
"ACTION_RESET_PASSWORD": "Réinitialiser le mot de passe", "ACTION_RESET_PASSWORD": "Réinitialiser le mot de passe",
"LINK_CANCEL": "Nan, ramenez-moi en arrière. Je crois que je m'en souviens.", "LINK_CANCEL": "Nan, ramenez-moi en arrière. Je crois que je m'en souviens.",
"SUCCESS_TITLE": "Check your inbox!", "SUCCESS_TITLE": "Consultez votre boîte aux lettres !",
"SUCCESS_TEXT": "We sent you an email with the instructions to set a new password", "SUCCESS_TEXT": "Nous vous avons envoyé un courriel avec les instructions pour définir un nouveau mot de passe",
"ERROR": "D'après nos Oompa Loompas, vous n'êtes pas encore enregistré." "ERROR": "D'après nos Oompa Loompas, vous n'êtes pas encore enregistré."
}, },
"CHANGE_PASSWORD": { "CHANGE_PASSWORD": {
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Accueil - Taiga", "PAGE_TITLE": "Accueil - Taiga",
"PAGE_DESCRIPTION": "La page d'accueil de Taiga sur laquelle apparaissent vos projets principaux et toutes les récits utilisateur, tâches et tickets qui vont sont assignés et surveillés.", "PAGE_DESCRIPTION": "La page d'accueil de Taiga sur laquelle apparaissent vos projets principaux et toutes les récits utilisateur, tâches et tickets qui vont sont assignés et surveillés.",
"EMPTY_WORKING_ON": "<strong>C'est un peu vide, n'est-ce pas ?</strong> Commencez à utiliser Taiga et vous verrez ici les récits, tâches et tickets sur lesquels vous travaillez.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Suivez</strong> des récits utilisateur, des tâches, des tickets dans vos projets et soyez prévenu des modifications :)", "EMPTY_WATCHING": "<strong>Suivez</strong> des récits utilisateur, des tâches, des tickets dans vos projets et soyez prévenu des modifications :)",
"EMPTY_PROJECT_LIST": "Vous n'avez aucun projet pour l'instant", "EMPTY_PROJECT_LIST": "Vous n'avez aucun projet pour l'instant",
"WORKING_ON_SECTION": "Projets en cours", "WORKING_ON_SECTION": "Projets en cours",
@ -434,9 +435,9 @@
"BACKLOG": "Backlog", "BACKLOG": "Backlog",
"BACKLOG_DESCRIPTION": "Gérez votre récits utilisateur pour garder une vue organisée des travaux à venir et priorisés.", "BACKLOG_DESCRIPTION": "Gérez votre récits utilisateur pour garder une vue organisée des travaux à venir et priorisés.",
"NUMBER_SPRINTS": "Nombre prévu de sprints", "NUMBER_SPRINTS": "Nombre prévu de sprints",
"NUMBER_SPRINTS_HELP": "0 for an undetermined number", "NUMBER_SPRINTS_HELP": "0 pour un nombre indéterminé",
"NUMBER_US_POINTS": "Total prévu de points d'histoire", "NUMBER_US_POINTS": "Total prévu de points d'histoire",
"NUMBER_US_POINTS_HELP": "0 for an undetermined number", "NUMBER_US_POINTS_HELP": "0 pour un nombre indéterminé",
"KANBAN": "Kanban", "KANBAN": "Kanban",
"KANBAN_DESCRIPTION": "Organisez votre projet de manière agile avec ce tableau.", "KANBAN_DESCRIPTION": "Organisez votre projet de manière agile avec ce tableau.",
"ISSUES": "Tickets", "ISSUES": "Tickets",
@ -474,15 +475,15 @@
"MAX_PRIVATE_PROJECTS_MEMBERS": "The maximum number of members for private projects has been exceeded", "MAX_PRIVATE_PROJECTS_MEMBERS": "The maximum number of members for private projects has been exceeded",
"MAX_PUBLIC_PROJECTS": "Unfortunately, you've reached the maximum number of public projects allowed by your current plan", "MAX_PUBLIC_PROJECTS": "Unfortunately, you've reached the maximum number of public projects allowed by your current plan",
"MAX_PUBLIC_PROJECTS_MEMBERS": "The project exceeds your maximum number of members for public projects", "MAX_PUBLIC_PROJECTS_MEMBERS": "The project exceeds your maximum number of members for public projects",
"PROJECT_OWNER": "Project owner", "PROJECT_OWNER": "Propriétaire du projet",
"REQUEST_OWNERSHIP": "Request ownership", "REQUEST_OWNERSHIP": "Demander la propriété",
"REQUEST_OWNERSHIP_CONFIRMATION_TITLE": "Do you want to become the new project owner?", "REQUEST_OWNERSHIP_CONFIRMATION_TITLE": "Voulez-vous devenir le nouveau propriétaire du projet ?",
"REQUEST_OWNERSHIP_DESC": "Request that current project owner {{name}} transfer ownership of this project to you.", "REQUEST_OWNERSHIP_DESC": "Demander que le propriétaire actuel du projet {{name}} vous transfert la propriété.",
"REQUEST_OWNERSHIP_BUTTON": "Requête", "REQUEST_OWNERSHIP_BUTTON": "Requête",
"REQUEST_OWNERSHIP_SUCCESS": "We'll notify the project owner", "REQUEST_OWNERSHIP_SUCCESS": "Nous allons prévenir le propriétaire du projet",
"CHANGE_OWNER": "Change owner", "CHANGE_OWNER": "Changer le propriétaire",
"CHANGE_OWNER_SUCCESS_TITLE": "Ok, your request has been sent!", "CHANGE_OWNER_SUCCESS_TITLE": "Ok, votre demande a été envoyée !",
"CHANGE_OWNER_SUCCESS_DESC": "We will notify you by email if the project ownership request is accepted or declined" "CHANGE_OWNER_SUCCESS_DESC": "Nous vous préviendrons par courriel si la demande de propriété du projet est acceptée ou refusée"
}, },
"REPORTS": { "REPORTS": {
"TITLE": "Rapports", "TITLE": "Rapports",
@ -556,13 +557,12 @@
"PAGE_TITLE": "Rôles - {{projectName}}", "PAGE_TITLE": "Rôles - {{projectName}}",
"WARNING_NO_ROLE": "Attention, aucun rôle dans votre projet ne pourra estimer la valeur du point pour les récits utilisateurs", "WARNING_NO_ROLE": "Attention, aucun rôle dans votre projet ne pourra estimer la valeur du point pour les récits utilisateurs",
"HELP_ROLE_ENABLED": "Si activé, les membres affectés à ce rôle pourront estimer la valeur du point pour les récits utilisateurs", "HELP_ROLE_ENABLED": "Si activé, les membres affectés à ce rôle pourront estimer la valeur du point pour les récits utilisateurs",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Désactiver les estimations pour ce rôle", "DISABLE_COMPUTABLE_ALERT_TITLE": "Êtes-vous sûr de vouloir désactiver les estimations de ce rôle ?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Si vous désactivez les estimations pour le rôle {{roleName}} toutes les estimations précédentes faites par ce rôle seront supprimées", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Si vous désactivez les estimations pour le rôle {{roleName}} toutes les estimations précédentes faites par ce rôle seront supprimées",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Êtes-vous sûr de vouloir désactiver les estimations de ce rôle ?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} membres avec ce rôle", "COUNT_MEMBERS": "{{ role.members_count }} membres avec ce rôle",
"TITLE_DELETE_ROLE": "Supprimer des rôles", "TITLE_DELETE_ROLE": "Supprimer des rôles",
"REPLACEMENT_ROLE": "Tous les utilisateurs avec ce rôle seront déplacés dans", "REPLACEMENT_ROLE": "Tous les utilisateurs avec ce rôle seront déplacés dans",
"WARNING_DELETE_ROLE": "Be careful! All role estimations will be removed", "WARNING_DELETE_ROLE": "Attention ! Toutes les estimations du rôle vont être supprimées",
"ERROR_DELETE_ALL": "Vous ne pouvez pas supprimer toutes les valeurs", "ERROR_DELETE_ALL": "Vous ne pouvez pas supprimer toutes les valeurs",
"EXTERNAL_USER": "Utilisateur externe" "EXTERNAL_USER": "Utilisateur externe"
}, },
@ -692,21 +692,20 @@
"TITLE": "Services" "TITLE": "Services"
}, },
"PROJECT_TRANSFER": { "PROJECT_TRANSFER": {
"DO_YOU_ACCEPT_PROJECT_OWNERNSHIP": "Would you like to become the new project owner?", "DO_YOU_ACCEPT_PROJECT_OWNERNSHIP": "Voudriez-vous devenir le nouveau propriétaire du projet ?",
"PRIVATE": "Private", "PRIVATE": "Privé",
"ACCEPTED_PROJECT_OWNERNSHIP": "Congratulations! You're now the new project owner.", "ACCEPTED_PROJECT_OWNERNSHIP": "Félicitations ! Vous êtes maintenant le nouveau propriétaire du projet.",
"REJECTED_PROJECT_OWNERNSHIP": "OK. We'll contact the current project owner", "REJECTED_PROJECT_OWNERNSHIP": "OK. Nous allons contacter le propriétaire actuel du projet",
"ACCEPT": "Accepter", "ACCEPT": "Accepter",
"REJECT": "Reject", "REJECT": "Rejeter",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, le propriétaire actuel du projet <strong>{{project}}</strong> a demandé à ce que vous soyez le nouveau propriétaire.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?", "ADD_COMMENT": "Voulez-vous ajouter un commentaire pour le propriétaire du projet ?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "UNLIMITED_PROJECTS": "Illimité",
"UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
"PRIVATE": "Please remember that you can own up to <strong>{{maxProjects}}</strong> private projects. You currently own <strong>{{currentProjects}}</strong> private projects", "PRIVATE": "Please remember that you can own up to <strong>{{maxProjects}}</strong> private projects. You currently own <strong>{{currentProjects}}</strong> private projects",
"PUBLIC": "Please remember that you can own up to <strong>{{maxProjects}}</strong> public projects. You currently own <strong>{{currentProjects}}</strong> public projects" "PUBLIC": "Please remember that you can own up to <strong>{{maxProjects}}</strong> public projects. You currently own <strong>{{currentProjects}}</strong> public projects"
}, },
"CANT_BE_OWNED": "At the moment you cannot become an owner of a project of this type. If you would like to become the owner of this project, please contact the administrator so they change your account settings to enable project ownership.", "CANT_BE_OWNED": "Pour le moment, vous ne pouvez devenir propriétaire d'un projet de ce type. Si vous voulez devenir propriétaire de ce projet, merci de contacter l'administrateur afin qu'il puisse modifier les paramètres de votre compte pour autoriser la propriété de projet.",
"CHANGE_MY_PLAN": "Change my plan" "CHANGE_MY_PLAN": "Change my plan"
} }
}, },
@ -771,7 +770,7 @@
"BLOCKED_PROJECT": { "BLOCKED_PROJECT": {
"BLOCKED": "Projet bloqué", "BLOCKED": "Projet bloqué",
"THIS_PROJECT_IS_BLOCKED": "Ce projet est temporairement verrouillé", "THIS_PROJECT_IS_BLOCKED": "Ce projet est temporairement verrouillé",
"TO_UNBLOCK_CONTACT_THE_ADMIN_STAFF": "In order to unblock your projects, contact the administrator." "TO_UNBLOCK_CONTACT_THE_ADMIN_STAFF": "Pour débloquer vos projets, merci de contacter l'administrateur."
}, },
"STATS": { "STATS": {
"PROJECT": "points<br/> projet", "PROJECT": "points<br/> projet",
@ -890,7 +889,7 @@
"NEWSLETTER_LABEL_TEXT": "Je ne veux plus recevoir votre bulletin d'information", "NEWSLETTER_LABEL_TEXT": "Je ne veux plus recevoir votre bulletin d'information",
"CANCEL": "Retour aux réglages", "CANCEL": "Retour aux réglages",
"ACCEPT": "Supprimer le compte", "ACCEPT": "Supprimer le compte",
"BLOCK_PROJECT": "Note that all the projects you own projects will be <strong>blocked</strong> after you delete your account. If you do want a project blocked, transfer ownership to another member of each project prior to deleting your account.", "BLOCK_PROJECT": "Notez que tous les projets dont vous avez la propriété seront <strong>bloqués</strong> après que vous ayez supprimé votre compte. Si vous souhaitez pas qu'un projet soit bloqué, merci d'en transférer la propriété auprès d'un autre membre avant la suppression de votre compte.",
"SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :(" "SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :("
}, },
"DELETE_PROJECT": { "DELETE_PROJECT": {
@ -952,20 +951,20 @@
"LIMIT_USERS_WARNING_MESSAGE": "Unfortunately, this project can't have more than <strong>{{maxMembers}}</strong> members." "LIMIT_USERS_WARNING_MESSAGE": "Unfortunately, this project can't have more than <strong>{{maxMembers}}</strong> members."
}, },
"LEAVE_PROJECT_WARNING": { "LEAVE_PROJECT_WARNING": {
"TITLE": "Unfortunately, this project can't be left without an owner", "TITLE": "Malheureusement, ce projet ne peut pas être laissé sans propriétaire",
"CURRENT_USER_OWNER": { "CURRENT_USER_OWNER": {
"DESC": "You are the current owner of this project. Before leaving, please transfer ownership to someone else.", "DESC": "Vous êtes le propriétaire actuel de ce projet. Avant de partir, merci de transférer la propriété du projet à quelqu'un d'autre.",
"BUTTON": "Change the project owner" "BUTTON": "Changer le propriétaire du projet"
}, },
"OTHER_USER_OWNER": { "OTHER_USER_OWNER": {
"DESC": "Unfortunately, you can't delete a member who is also the current project owner. First, please assign a new project owner.", "DESC": "Malheureusement, vous ne pouvez supprimer un membre s'il est également le propriétaire actuel du projet. Merci de désigner auparavant un nouveau propriétaire.",
"BUTTON": "Request project owner change" "BUTTON": "Demander le changement de propriétaire du projet"
} }
}, },
"CHANGE_OWNER": { "CHANGE_OWNER": {
"TITLE": "Who do you want to be the new project owner?", "TITLE": "Qui voulez-vous désigner comme le nouveau propriétaire du projet ?",
"ADD_COMMENT": "Add comment", "ADD_COMMENT": "Ajouter un commentaire",
"BUTTON": "Ask this project member to become the new project owner" "BUTTON": "Demander à ce membre du projet de devenir le nouveau propriétaire"
} }
}, },
"US": { "US": {
@ -1395,7 +1394,7 @@
"WIZARD": { "WIZARD": {
"SECTION_TITLE_CREATE_PROJECT": "Créer un projet", "SECTION_TITLE_CREATE_PROJECT": "Créer un projet",
"CREATE_PROJECT_TEXT": "Tout beau, tout nouveau !", "CREATE_PROJECT_TEXT": "Tout beau, tout nouveau !",
"CHOOSE_TEMPLATE": "Which template fits your project best?", "CHOOSE_TEMPLATE": "Quel modèle convient mieux à votre projet ?",
"CHOOSE_TEMPLATE_TITLE": "Plus d'information sur les templates de projets", "CHOOSE_TEMPLATE_TITLE": "Plus d'information sur les templates de projets",
"CHOOSE_TEMPLATE_INFO": "Plus d'informations", "CHOOSE_TEMPLATE_INFO": "Plus d'informations",
"PROJECT_DETAILS": "Détails du projet", "PROJECT_DETAILS": "Détails du projet",
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Ecrivez votre page wiki", "PLACEHOLDER_PAGE": "Ecrivez votre page wiki",
"REMOVE": "Supprimer cette page wiki", "REMOVE": "Supprimer cette page wiki",
"DELETE_LIGHTBOX_TITLE": "Supprimer la page Wiki", "DELETE_LIGHTBOX_TITLE": "Supprimer la page Wiki",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Liens", "SECTION_NAME": "Liens",
"ACTION_ADD_LINK": "Ajouter un lien" "ACTION_ADD_LINK": "Ajouter un lien"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "nota bloccata", "BLOCKED_NOTE": "nota bloccata",
"IS_BLOCKED": "è bloccato", "IS_BLOCKED": "è bloccato",
"REF": "Riferimento", "REF": "Riferimento",
"VOTES": "Voti" "VOTES": "Voti",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Tutti" "ALL": "Tutti"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Home - Taiga", "PAGE_TITLE": "Home - Taiga",
"PAGE_DESCRIPTION": "La home di Taiga con i tuoi principali progetti e tutte le storie utente, i compiti e problemi assegnati e osservati. ", "PAGE_DESCRIPTION": "La home di Taiga con i tuoi principali progetti e tutte le storie utente, i compiti e problemi assegnati e osservati. ",
"EMPTY_WORKING_ON": "<strong>Dà un po' l'idea di vuoto, no?</strong> Inizia a lavorare con Taiga e qui vedrai le storie, i compiti ed i problemi su cui stai lavorando.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Ossserva</strong> Storie Utente, Compiti, Criticità nel progetto e ti verranno notificate le sue modifiche :)", "EMPTY_WATCHING": "<strong>Ossserva</strong> Storie Utente, Compiti, Criticità nel progetto e ti verranno notificate le sue modifiche :)",
"EMPTY_PROJECT_LIST": "Per ora non hai nessun progetto", "EMPTY_PROJECT_LIST": "Per ora non hai nessun progetto",
"WORKING_ON_SECTION": "Sta lavorando su", "WORKING_ON_SECTION": "Sta lavorando su",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Ruoli - {{projectName}}", "PAGE_TITLE": "Ruoli - {{projectName}}",
"WARNING_NO_ROLE": "Attento, nessun ruolo, all'interno del tuo progetto, potrà stimare i punti valore per le storie utente", "WARNING_NO_ROLE": "Attento, nessun ruolo, all'interno del tuo progetto, potrà stimare i punti valore per le storie utente",
"HELP_ROLE_ENABLED": "Una volta abilitato, chi é associato a questo ruolo sará in grado di stimare il valore dei punti per le storie utente", "HELP_ROLE_ENABLED": "Una volta abilitato, chi é associato a questo ruolo sará in grado di stimare il valore dei punti per le storie utente",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disabilita la stime per questo ruolo", "DISABLE_COMPUTABLE_ALERT_TITLE": "sei sicuro di voler disabilitare la stime di questo ruolo?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Se disabiliti i permessi di stime per {{roleName}} tutte le stime precedenti di questo ruolo saranno rimosse", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Se disabiliti i permessi di stime per {{roleName}} tutte le stime precedenti di questo ruolo saranno rimosse",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>sei sicuro di voler disabilitare la stime di questo ruolo?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} membri con questo ruolo", "COUNT_MEMBERS": "{{ role.members_count }} membri con questo ruolo",
"TITLE_DELETE_ROLE": "Elimina ruolo", "TITLE_DELETE_ROLE": "Elimina ruolo",
"REPLACEMENT_ROLE": "Tutti gli utenti con questo ruolo saranno spostati a ", "REPLACEMENT_ROLE": "Tutti gli utenti con questo ruolo saranno spostati a ",
@ -699,7 +699,6 @@
"ACCEPT": "Accetta", "ACCEPT": "Accetta",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Crea la tua pagina wiki", "PLACEHOLDER_PAGE": "Crea la tua pagina wiki",
"REMOVE": "Rimuovi questa pagina wiki", "REMOVE": "Rimuovi questa pagina wiki",
"DELETE_LIGHTBOX_TITLE": "Elimina Pagina Wiki", "DELETE_LIGHTBOX_TITLE": "Elimina Pagina Wiki",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Link", "SECTION_NAME": "Link",
"ACTION_ADD_LINK": "Aggiungi link" "ACTION_ADD_LINK": "Aggiungi link"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "geblokkeerde notitie", "BLOCKED_NOTE": "geblokkeerde notitie",
"IS_BLOCKED": "is geblokkeerd", "IS_BLOCKED": "is geblokkeerd",
"REF": "Ref", "REF": "Ref",
"VOTES": "Stemmen" "VOTES": "Stemmen",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Alles" "ALL": "Alles"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Home -Taiga", "PAGE_TITLE": "Home -Taiga",
"PAGE_DESCRIPTION": "De Taiga start pagina met jouw projecten en de aan jou toegewezen en gevolgde user stories, taken en issues", "PAGE_DESCRIPTION": "De Taiga start pagina met jouw projecten en de aan jou toegewezen en gevolgde user stories, taken en issues",
"EMPTY_WORKING_ON": "<strong>Beetje kaal, vind je niet?</strong> Als je aan de slag gaat met Taiga, zie je hier de stories, taken en issues waar je aan werkt", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Volg</strong> User Stories, Taken, Issues binnen jouw projecten en ontvang een bericht bij veranderingen :)", "EMPTY_WATCHING": "<strong>Volg</strong> User Stories, Taken, Issues binnen jouw projecten en ontvang een bericht bij veranderingen :)",
"EMPTY_PROJECT_LIST": "Je hebt nog geen projecten", "EMPTY_PROJECT_LIST": "Je hebt nog geen projecten",
"WORKING_ON_SECTION": "Werkt aan", "WORKING_ON_SECTION": "Werkt aan",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Rollen - {{projectName}}", "PAGE_TITLE": "Rollen - {{projectName}}",
"WARNING_NO_ROLE": "Wees voorzichtig, geen enkele rol in je project zal de puntenwaarde van een user story kunnen estimeren", "WARNING_NO_ROLE": "Wees voorzichtig, geen enkele rol in je project zal de puntenwaarde van een user story kunnen estimeren",
"HELP_ROLE_ENABLED": "Als dit actief is, zullen leden met deze rol de punten waarde voor user stories kunnen schatten", "HELP_ROLE_ENABLED": "Als dit actief is, zullen leden met deze rol de punten waarde voor user stories kunnen schatten",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disable estimation for this role", "DISABLE_COMPUTABLE_ALERT_TITLE": "Are you sure you want to disable this role estimations?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} leden met deze rol", "COUNT_MEMBERS": "{{ role.members_count }} leden met deze rol",
"TITLE_DELETE_ROLE": "Verwijder Rol", "TITLE_DELETE_ROLE": "Verwijder Rol",
"REPLACEMENT_ROLE": "Al de gebruikers met deze rol zullen verplaats worden naar", "REPLACEMENT_ROLE": "Al de gebruikers met deze rol zullen verplaats worden naar",
@ -699,7 +699,6 @@
"ACCEPT": "Accepteren", "ACCEPT": "Accepteren",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Schrijf je wiki pagina", "PLACEHOLDER_PAGE": "Schrijf je wiki pagina",
"REMOVE": "Verwijder deze wiki pagina", "REMOVE": "Verwijder deze wiki pagina",
"DELETE_LIGHTBOX_TITLE": "Verwijderd wiki pagina", "DELETE_LIGHTBOX_TITLE": "Verwijderd wiki pagina",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Links", "SECTION_NAME": "Links",
"ACTION_ADD_LINK": "Link toevoegen" "ACTION_ADD_LINK": "Link toevoegen"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "zablokowana notka", "BLOCKED_NOTE": "zablokowana notka",
"IS_BLOCKED": "zablokowana", "IS_BLOCKED": "zablokowana",
"REF": "Ref", "REF": "Ref",
"VOTES": "Głosy" "VOTES": "Głosy",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Wszystko" "ALL": "Wszystko"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Strona główna - Taiga", "PAGE_TITLE": "Strona główna - Taiga",
"PAGE_DESCRIPTION": "Główna strona Taiga, z Twoimi głównymi projektami i wszystkimi przypisanymi Tobie i obserwowanymi historyjkami użytkownika, zadaniami i zgłoszeniami.", "PAGE_DESCRIPTION": "Główna strona Taiga, z Twoimi głównymi projektami i wszystkimi przypisanymi Tobie i obserwowanymi historyjkami użytkownika, zadaniami i zgłoszeniami.",
"EMPTY_WORKING_ON": "<strong>Trochę tu pusto?</strong>Rozpocznij pracę z Taigą, a pojawią się tutaj historie, zadania oraz zgłoszone błędy, nad którymi pracujesz.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)", "EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)",
"EMPTY_PROJECT_LIST": "Nie masz jeszcze żadnych projektów", "EMPTY_PROJECT_LIST": "Nie masz jeszcze żadnych projektów",
"WORKING_ON_SECTION": "Pracujesz nad", "WORKING_ON_SECTION": "Pracujesz nad",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Role - {{projectName}}", "PAGE_TITLE": "Role - {{projectName}}",
"WARNING_NO_ROLE": "Bez przydzielenia ról w projekcie nie ma możliwości oceniania historyjek użytkownika. Umpa Lumpy nie będą wiedziały komu wolno to zrobić :)", "WARNING_NO_ROLE": "Bez przydzielenia ról w projekcie nie ma możliwości oceniania historyjek użytkownika. Umpa Lumpy nie będą wiedziały komu wolno to zrobić :)",
"HELP_ROLE_ENABLED": "Jeśli aktywne użytkownicy pełniący tę rolę będą mogli szacować wartości historyjek", "HELP_ROLE_ENABLED": "Jeśli aktywne użytkownicy pełniący tę rolę będą mogli szacować wartości historyjek",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disable estimation for this role", "DISABLE_COMPUTABLE_ALERT_TITLE": "Are you sure you want to disable this role estimations?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} użytkowników pełniących tę rolę w projekcie", "COUNT_MEMBERS": "{{ role.members_count }} użytkowników pełniących tę rolę w projekcie",
"TITLE_DELETE_ROLE": "Usuń rolę", "TITLE_DELETE_ROLE": "Usuń rolę",
"REPLACEMENT_ROLE": "Wszyscy użytkownicy pełniący tę rolę zostaną przeniesieni do", "REPLACEMENT_ROLE": "Wszyscy użytkownicy pełniący tę rolę zostaną przeniesieni do",
@ -699,7 +699,6 @@
"ACCEPT": "Akceptuj", "ACCEPT": "Akceptuj",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Napisz swoje Wiki", "PLACEHOLDER_PAGE": "Napisz swoje Wiki",
"REMOVE": "Usuń tą stronę Wiki", "REMOVE": "Usuń tą stronę Wiki",
"DELETE_LIGHTBOX_TITLE": "Usuń tą stronę Wiki", "DELETE_LIGHTBOX_TITLE": "Usuń tą stronę Wiki",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Linki", "SECTION_NAME": "Linki",
"ACTION_ADD_LINK": "Dodaj link" "ACTION_ADD_LINK": "Dodaj link"

View File

@ -41,7 +41,7 @@
"IOCAINE_TEXT": "Se sentindo sobrecarregado por uma tarefa? Assegure-se de que os outros saibam disso clicando em Iocaine quando estiver editando a tarefa. É possível se tornar imune a essse veneno mortal (fictício) consumindo pequenas quantidades ao longo do tempo, assim como é possível ficar melhor no que faz, ocasionalmente, por assumir desafios extras!", "IOCAINE_TEXT": "Se sentindo sobrecarregado por uma tarefa? Assegure-se de que os outros saibam disso clicando em Iocaine quando estiver editando a tarefa. É possível se tornar imune a essse veneno mortal (fictício) consumindo pequenas quantidades ao longo do tempo, assim como é possível ficar melhor no que faz, ocasionalmente, por assumir desafios extras!",
"CLIENT_REQUIREMENT": "Client requirement is new requirement that was not previously expected and it is required to be part of the project", "CLIENT_REQUIREMENT": "Client requirement is new requirement that was not previously expected and it is required to be part of the project",
"TEAM_REQUIREMENT": "Team requirement is a requirement that must exist in the project but should have no cost for the client", "TEAM_REQUIREMENT": "Team requirement is a requirement that must exist in the project but should have no cost for the client",
"OWNER": "Project Owner", "OWNER": "Dono do Projeto",
"CAPSLOCK_WARNING": "Be careful! You are using capital letters in an input field that is case sensitive.", "CAPSLOCK_WARNING": "Be careful! You are using capital letters in an input field that is case sensitive.",
"FORM_ERRORS": { "FORM_ERRORS": {
"DEFAULT_MESSAGE": "Este valor parece ser inválido.", "DEFAULT_MESSAGE": "Este valor parece ser inválido.",
@ -140,7 +140,8 @@
"BLOCKED_NOTE": "Nota de bloqueio", "BLOCKED_NOTE": "Nota de bloqueio",
"IS_BLOCKED": "está bloqueada", "IS_BLOCKED": "está bloqueada",
"REF": "Ref", "REF": "Ref",
"VOTES": "Votos" "VOTES": "Votos",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Tudo" "ALL": "Tudo"
@ -318,8 +319,8 @@
"PLACEHOLDER_FIELD": "Nome de usuário ou email", "PLACEHOLDER_FIELD": "Nome de usuário ou email",
"ACTION_RESET_PASSWORD": "Resetar Senha", "ACTION_RESET_PASSWORD": "Resetar Senha",
"LINK_CANCEL": "Nããão, me leve de volta. Acho que me lembrei.", "LINK_CANCEL": "Nããão, me leve de volta. Acho que me lembrei.",
"SUCCESS_TITLE": "Check your inbox!", "SUCCESS_TITLE": "Verifique sua caixa de entrada!",
"SUCCESS_TEXT": "We sent you an email with the instructions to set a new password", "SUCCESS_TEXT": "Nós lhe enviamos um e-mail com instruções para definição de uma nova senha.",
"ERROR": "Segundo nossos Oompa Loompas, você ainda não está inscrito." "ERROR": "Segundo nossos Oompa Loompas, você ainda não está inscrito."
}, },
"CHANGE_PASSWORD": { "CHANGE_PASSWORD": {
@ -355,8 +356,8 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Início - Taiga", "PAGE_TITLE": "Início - Taiga",
"PAGE_DESCRIPTION": "A página inicial do Taiga com seus principais projetos e todas as estórias atribuídas ou observadas por você, tarefas e problemas", "PAGE_DESCRIPTION": "A página inicial do Taiga com seus principais projetos e todas as estórias atribuídas ou observadas por você, tarefas e problemas",
"EMPTY_WORKING_ON": "<strong>Isso parece vazio não acha?</strong> Comece a trabalhar com Taiga para começar a ver estórias, tarefas e problemas em que está trabalhando.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Siga</strong> Estórias, Tarefas e Problemas nos seus projetos e seja notificado das mudanças :)", "EMPTY_WATCHING": "<strong>Siga</strong> Estórias, Tarefas e Casos nos seus projetos e seja notificado das mudanças :)",
"EMPTY_PROJECT_LIST": "Você ainda não tem projetos", "EMPTY_PROJECT_LIST": "Você ainda não tem projetos",
"WORKING_ON_SECTION": "Trabalhando em", "WORKING_ON_SECTION": "Trabalhando em",
"WATCHING_SECTION": "Observando", "WATCHING_SECTION": "Observando",
@ -476,7 +477,7 @@
"MAX_PUBLIC_PROJECTS_MEMBERS": "The project exceeds your maximum number of members for public projects", "MAX_PUBLIC_PROJECTS_MEMBERS": "The project exceeds your maximum number of members for public projects",
"PROJECT_OWNER": "Project owner", "PROJECT_OWNER": "Project owner",
"REQUEST_OWNERSHIP": "Request ownership", "REQUEST_OWNERSHIP": "Request ownership",
"REQUEST_OWNERSHIP_CONFIRMATION_TITLE": "Do you want to become the new project owner?", "REQUEST_OWNERSHIP_CONFIRMATION_TITLE": "Gostaria de se tornar o novo dono do projeto?",
"REQUEST_OWNERSHIP_DESC": "Request that current project owner {{name}} transfer ownership of this project to you.", "REQUEST_OWNERSHIP_DESC": "Request that current project owner {{name}} transfer ownership of this project to you.",
"REQUEST_OWNERSHIP_BUTTON": "Solicitação", "REQUEST_OWNERSHIP_BUTTON": "Solicitação",
"REQUEST_OWNERSHIP_SUCCESS": "We'll notify the project owner", "REQUEST_OWNERSHIP_SUCCESS": "We'll notify the project owner",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Funções - {{projectName}}", "PAGE_TITLE": "Funções - {{projectName}}",
"WARNING_NO_ROLE": "Seja cuidadoso, nenhuma função em seu projeto será capaz de estimar o valor dos pontos para as user stories", "WARNING_NO_ROLE": "Seja cuidadoso, nenhuma função em seu projeto será capaz de estimar o valor dos pontos para as user stories",
"HELP_ROLE_ENABLED": "Quando habilitado, membros atribuídos a esta função serão capazes de estimar valores para user stories", "HELP_ROLE_ENABLED": "Quando habilitado, membros atribuídos a esta função serão capazes de estimar valores para user stories",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Desativar estimativa para esta permissão", "DISABLE_COMPUTABLE_ALERT_TITLE": "Você tem certeza que quer desativar esta permissão de estimativas?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Se você desativar a permissão de estimativas para esta regra {{roleName}} todas estimativas feitas anteriormente por esta regra serão removidas.", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Se você desativar a permissão de estimativas para esta regra {{roleName}} todas estimativas feitas anteriormente por esta regra serão removidas.",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Você tem certeza que quer desativar esta permissão de estimativas?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} membros com a mesma função", "COUNT_MEMBERS": "{{ role.members_count }} membros com a mesma função",
"TITLE_DELETE_ROLE": "Apagar Função", "TITLE_DELETE_ROLE": "Apagar Função",
"REPLACEMENT_ROLE": "Todos os usuários com essa função serão movidos para", "REPLACEMENT_ROLE": "Todos os usuários com essa função serão movidos para",
@ -699,7 +699,6 @@
"ACCEPT": "Aceitar", "ACCEPT": "Aceitar",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -888,8 +887,8 @@
"SECTION_NAME": "Apagar conta no Taiga", "SECTION_NAME": "Apagar conta no Taiga",
"CONFIRM": "Você tem certeza que quer apagar sua conta Taiga?", "CONFIRM": "Você tem certeza que quer apagar sua conta Taiga?",
"NEWSLETTER_LABEL_TEXT": "Eu não quero receber mais os informativos", "NEWSLETTER_LABEL_TEXT": "Eu não quero receber mais os informativos",
"CANCEL": "Back to settings", "CANCEL": "Voltar para configurações",
"ACCEPT": "Delete account", "ACCEPT": "Remover conta",
"BLOCK_PROJECT": "Note that all the projects you own projects will be <strong>blocked</strong> after you delete your account. If you do want a project blocked, transfer ownership to another member of each project prior to deleting your account.", "BLOCK_PROJECT": "Note that all the projects you own projects will be <strong>blocked</strong> after you delete your account. If you do want a project blocked, transfer ownership to another member of each project prior to deleting your account.",
"SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :(" "SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :("
}, },
@ -1399,8 +1398,8 @@
"CHOOSE_TEMPLATE_TITLE": "More info about project templates", "CHOOSE_TEMPLATE_TITLE": "More info about project templates",
"CHOOSE_TEMPLATE_INFO": "More info", "CHOOSE_TEMPLATE_INFO": "More info",
"PROJECT_DETAILS": "Project Details", "PROJECT_DETAILS": "Project Details",
"PUBLIC_PROJECT": "Public Project", "PUBLIC_PROJECT": "Projeto Público",
"PRIVATE_PROJECT": "Private Project", "PRIVATE_PROJECT": "Projeto Privado",
"CREATE_PROJECT": "Criar projeto", "CREATE_PROJECT": "Criar projeto",
"MAX_PRIVATE_PROJECTS": "You've reached the maximum number of private projects", "MAX_PRIVATE_PROJECTS": "You've reached the maximum number of private projects",
"MAX_PUBLIC_PROJECTS": "Unfortunately, you've reached the maximum number of public projects", "MAX_PUBLIC_PROJECTS": "Unfortunately, you've reached the maximum number of public projects",
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Escreve sua página wiki", "PLACEHOLDER_PAGE": "Escreve sua página wiki",
"REMOVE": "Remover essa página wiki", "REMOVE": "Remover essa página wiki",
"DELETE_LIGHTBOX_TITLE": "Apagar página Wiki", "DELETE_LIGHTBOX_TITLE": "Apagar página Wiki",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Links", "SECTION_NAME": "Links",
"ACTION_ADD_LINK": "Adicionar link" "ACTION_ADD_LINK": "Adicionar link"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "Пояснение блокировки", "BLOCKED_NOTE": "Пояснение блокировки",
"IS_BLOCKED": "заблокирован", "IS_BLOCKED": "заблокирован",
"REF": "Ссылка", "REF": "Ссылка",
"VOTES": "Голоса" "VOTES": "Голоса",
"SPRINT": "Спринт"
}, },
"ROLES": { "ROLES": {
"ALL": "Все" "ALL": "Все"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Домашняя страница - Taiga", "PAGE_TITLE": "Домашняя страница - Taiga",
"PAGE_DESCRIPTION": "Главная страница Taiga с вашими основными проектами, назначенными и отслеживаемыми ПИ, задачами и запросами", "PAGE_DESCRIPTION": "Главная страница Taiga с вашими основными проектами, назначенными и отслеживаемыми ПИ, задачами и запросами",
"EMPTY_WORKING_ON": "<strong>Пустовато, не правда ли?</strong> Начните работать в Taiga - и тут появятся ПИ, задачи и запросы, над которыми вы работаете.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Следите</strong> за пользовательскими историями, задачами, запросами в ваших проектах и будьте уведомлены об изменениях :)", "EMPTY_WATCHING": "<strong>Следите</strong> за пользовательскими историями, задачами, запросами в ваших проектах и будьте уведомлены об изменениях :)",
"EMPTY_PROJECT_LIST": "У Вас пока нет проектов", "EMPTY_PROJECT_LIST": "У Вас пока нет проектов",
"WORKING_ON_SECTION": "Работает над", "WORKING_ON_SECTION": "Работает над",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Роли - {{projectName}}", "PAGE_TITLE": "Роли - {{projectName}}",
"WARNING_NO_ROLE": "Осторожнее: ни с какими ролями на вашем проекте участники не смогут оценить очки для пользовательских историй.", "WARNING_NO_ROLE": "Осторожнее: ни с какими ролями на вашем проекте участники не смогут оценить очки для пользовательских историй.",
"HELP_ROLE_ENABLED": "Когда включено, участники, назначенные на эту роль, смогут оценивать очки для пользовательских историй", "HELP_ROLE_ENABLED": "Когда включено, участники, назначенные на эту роль, смогут оценивать очки для пользовательских историй",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Отключить оценку очков для этой роли", "DISABLE_COMPUTABLE_ALERT_TITLE": "Вы уверены, что хотите отключить оценку очков для этой роли?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Вы уверены, что хотите отключить оценку очков для этой роли?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} участников с этой ролью", "COUNT_MEMBERS": "{{ role.members_count }} участников с этой ролью",
"TITLE_DELETE_ROLE": "Удалить Роль", "TITLE_DELETE_ROLE": "Удалить Роль",
"REPLACEMENT_ROLE": "Все пользователи этой роли будут перемещены в", "REPLACEMENT_ROLE": "Все пользователи этой роли будут перемещены в",
@ -699,7 +699,6 @@
"ACCEPT": "Принимаю", "ACCEPT": "Принимаю",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Создать вики страницу", "PLACEHOLDER_PAGE": "Создать вики страницу",
"REMOVE": "Удалить эту вики страницу", "REMOVE": "Удалить эту вики страницу",
"DELETE_LIGHTBOX_TITLE": "Удалить вики страницу", "DELETE_LIGHTBOX_TITLE": "Удалить вики страницу",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Ссылки", "SECTION_NAME": "Ссылки",
"ACTION_ADD_LINK": "Добавить ссылку" "ACTION_ADD_LINK": "Добавить ссылку"

View File

@ -35,7 +35,7 @@
"ONE_ITEM_LINE": "En post per rad ...", "ONE_ITEM_LINE": "En post per rad ...",
"NEW_BULK": "Lägg till flera nya", "NEW_BULK": "Lägg till flera nya",
"RELATED_TASKS": "Besläktade uppgifter", "RELATED_TASKS": "Besläktade uppgifter",
"LOGOUT": "Logg ut", "LOGOUT": "Logga ut",
"EXTERNAL_USER": "en extern användare", "EXTERNAL_USER": "en extern användare",
"GENERIC_ERROR": "En av våra Oompa Loompier säger {{error}}.", "GENERIC_ERROR": "En av våra Oompa Loompier säger {{error}}.",
"IOCAINE_TEXT": "Känner du dig lite bortkommen med en uppgift? Försäkra dig om att andra känner till uppgiften när du klickar på Iocaine-knappen när du ändrar uppgiften. Det är möjligt att bli immun till det här (påhittade) dödliga giftet om du tar små mängder över tid - och du kan även så småningom om bli bättre på vad du gör när du då och då tar på dig större utmaningar!", "IOCAINE_TEXT": "Känner du dig lite bortkommen med en uppgift? Försäkra dig om att andra känner till uppgiften när du klickar på Iocaine-knappen när du ändrar uppgiften. Det är möjligt att bli immun till det här (påhittade) dödliga giftet om du tar små mängder över tid - och du kan även så småningom om bli bättre på vad du gör när du då och då tar på dig större utmaningar!",
@ -140,20 +140,21 @@
"BLOCKED_NOTE": "blockerad notering", "BLOCKED_NOTE": "blockerad notering",
"IS_BLOCKED": "är blockerad", "IS_BLOCKED": "är blockerad",
"REF": "Ref. ", "REF": "Ref. ",
"VOTES": "Röster" "VOTES": "Röster",
"SPRINT": "Sprint"
}, },
"ROLES": { "ROLES": {
"ALL": "Alla" "ALL": "Alla"
}, },
"ASSIGNED_TO": { "ASSIGNED_TO": {
"NOT_ASSIGNED": "Ej tilldelad", "NOT_ASSIGNED": "Ej tilldelad",
"ASSIGN": "Assign", "ASSIGN": "Tilldela",
"DELETE_ASSIGNMENT": "Ta bort tilldelning", "DELETE_ASSIGNMENT": "Ta bort tilldelning",
"REMOVE_ASSIGNED": "Ta bort tilldelning", "REMOVE_ASSIGNED": "Ta bort tilldelning",
"TOO_MANY": "... för många användare, fortsätter filtreringen", "TOO_MANY": "... för många användare, fortsätter filtreringen",
"CONFIRM_UNASSIGNED": "Vill du lämna det utan att tilldela det? ", "CONFIRM_UNASSIGNED": "Vill du lämna det utan att tilldela det? ",
"TITLE_ACTION_EDIT_ASSIGNMENT": "Redigera tilldelning", "TITLE_ACTION_EDIT_ASSIGNMENT": "Redigera tilldelning",
"SELF": "Assign to me" "SELF": "Tilldela mig"
}, },
"STATUS": { "STATUS": {
"CLOSED": "Stängd", "CLOSED": "Stängd",
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "Hem - Taiga", "PAGE_TITLE": "Hem - Taiga",
"PAGE_DESCRIPTION": "Taiga hemsida med dina viktigaste projekt, alla dina tilldelade användaruppgifter, uppdrag och frågor", "PAGE_DESCRIPTION": "Taiga hemsida med dina viktigaste projekt, alla dina tilldelade användaruppgifter, uppdrag och frågor",
"EMPTY_WORKING_ON": "<strong>Känns tråkigt utan innehåll, eller hur?`</strong> Börja att arbeta med Taiga och du vill se uppgifter, uppdrag och ärenden du arbetar med. ", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)", "EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)",
"EMPTY_PROJECT_LIST": "Du har inte än några projekt", "EMPTY_PROJECT_LIST": "Du har inte än några projekt",
"WORKING_ON_SECTION": "Arbetar med", "WORKING_ON_SECTION": "Arbetar med",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Roller - {{projectName}}", "PAGE_TITLE": "Roller - {{projectName}}",
"WARNING_NO_ROLE": "Var försiktig. Inga roller i ditt projekt kan estimera poängvärden för användarhistorier", "WARNING_NO_ROLE": "Var försiktig. Inga roller i ditt projekt kan estimera poängvärden för användarhistorier",
"HELP_ROLE_ENABLED": "När det är aktivt, vill medlemmarna tilldelad den här rollen kunna estimera punktvärlden för användarhistorier", "HELP_ROLE_ENABLED": "När det är aktivt, vill medlemmarna tilldelad den här rollen kunna estimera punktvärlden för användarhistorier",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Avaktivera beräkningar för den här rollen", "DISABLE_COMPUTABLE_ALERT_TITLE": "ÄR du säker på att du vill avvaktivera den här rollens beräkningar?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Om du avaktiverar behörigheter för beräkning för rollen {{roleName}} vill alla tidigare beräkningar gjord av den här rollen tas bort. ", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "Om du avaktiverar behörigheter för beräkning för rollen {{roleName}} vill alla tidigare beräkningar gjord av den här rollen tas bort. ",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>ÄR du säker på att du vill avvaktivera den här rollens beräkningar?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} medlemmar med den här rollen", "COUNT_MEMBERS": "{{ role.members_count }} medlemmar med den här rollen",
"TITLE_DELETE_ROLE": "Ta bort rollen", "TITLE_DELETE_ROLE": "Ta bort rollen",
"REPLACEMENT_ROLE": "Alla användarna med den här rollen vill flyttas till", "REPLACEMENT_ROLE": "Alla användarna med den här rollen vill flyttas till",
@ -693,13 +693,12 @@
}, },
"PROJECT_TRANSFER": { "PROJECT_TRANSFER": {
"DO_YOU_ACCEPT_PROJECT_OWNERNSHIP": "Would you like to become the new project owner?", "DO_YOU_ACCEPT_PROJECT_OWNERNSHIP": "Would you like to become the new project owner?",
"PRIVATE": "Private", "PRIVATE": "Privat",
"ACCEPTED_PROJECT_OWNERNSHIP": "Congratulations! You're now the new project owner.", "ACCEPTED_PROJECT_OWNERNSHIP": "Congratulations! You're now the new project owner.",
"REJECTED_PROJECT_OWNERNSHIP": "OK. We'll contact the current project owner", "REJECTED_PROJECT_OWNERNSHIP": "OK. We'll contact the current project owner",
"ACCEPT": "Acceptera", "ACCEPT": "Acceptera",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -795,24 +794,24 @@
"PLACEHOLDER_SEARCH": "Sök i ...", "PLACEHOLDER_SEARCH": "Sök i ...",
"ACTION_CREATE_PROJECT": "Skapa projekt", "ACTION_CREATE_PROJECT": "Skapa projekt",
"ACTION_IMPORT_PROJECT": "Importerar projekt", "ACTION_IMPORT_PROJECT": "Importerar projekt",
"MANAGE_PROJECTS": "Manage projects", "MANAGE_PROJECTS": "Hantera projekt",
"TITLE_CREATE_PROJECT": "Skapa projekt", "TITLE_CREATE_PROJECT": "Skapa projekt",
"TITLE_IMPORT_PROJECT": "Importerar projekt", "TITLE_IMPORT_PROJECT": "Importerar projekt",
"TITLE_PRVIOUS_PROJECT": "Visa tidigare projekt", "TITLE_PRVIOUS_PROJECT": "Visa tidigare projekt",
"TITLE_NEXT_PROJECT": "Visa nästa projekt", "TITLE_NEXT_PROJECT": "Visa nästa projekt",
"HELP_TITLE": "Taiga hjälpsida", "HELP_TITLE": "Taiga hjälpsida",
"HELP": "Hjälp", "HELP": "Hjälp",
"HOMEPAGE": "Homepage", "HOMEPAGE": "Webbplats",
"FEEDBACK_TITLE": "Skicka återkoppling", "FEEDBACK_TITLE": "Skicka återkoppling",
"FEEDBACK": "Återkokppling", "FEEDBACK": "Återkoppling",
"NOTIFICATIONS_TITLE": "Ändra inställningar för dina notifieringar", "NOTIFICATIONS_TITLE": "Ändra inställningar för dina notifieringar",
"NOTIFICATIONS": "Notifieringar", "NOTIFICATIONS": "Notifieringar",
"ORGANIZATIONS_TITLE": "Ändra dina organisationer", "ORGANIZATIONS_TITLE": "Ändra dina organisationer",
"ORGANIZATIONS": "Ändra organizationer", "ORGANIZATIONS": "Ändra organizationer",
"SETTINGS_TITLE": "Ändra inställningarna", "SETTINGS_TITLE": "Ändra inställningarna",
"SETTINGS": "Inställningar", "SETTINGS": "Inställningar",
"VIEW_PROFILE_TITLE": "Vis profil", "VIEW_PROFILE_TITLE": "Visa profil",
"VIEW_PROFILE": "Vis profil", "VIEW_PROFILE": "Visa profil",
"EDIT_PROFILE_TITLE": "Ändra din profil", "EDIT_PROFILE_TITLE": "Ändra din profil",
"EDIT_PROFILE": "Ändra profil", "EDIT_PROFILE": "Ändra profil",
"CHANGE_PASSWORD_TITLE": "Byt lösenord", "CHANGE_PASSWORD_TITLE": "Byt lösenord",
@ -889,7 +888,7 @@
"CONFIRM": "Är du säker på att du vill radera kontot?", "CONFIRM": "Är du säker på att du vill radera kontot?",
"NEWSLETTER_LABEL_TEXT": "Jag vill inte motta flera nyhetsbrev", "NEWSLETTER_LABEL_TEXT": "Jag vill inte motta flera nyhetsbrev",
"CANCEL": "Back to settings", "CANCEL": "Back to settings",
"ACCEPT": "Delete account", "ACCEPT": "Ta bort konto",
"BLOCK_PROJECT": "Note that all the projects you own projects will be <strong>blocked</strong> after you delete your account. If you do want a project blocked, transfer ownership to another member of each project prior to deleting your account.", "BLOCK_PROJECT": "Note that all the projects you own projects will be <strong>blocked</strong> after you delete your account. If you do want a project blocked, transfer ownership to another member of each project prior to deleting your account.",
"SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :(" "SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :("
}, },
@ -964,7 +963,7 @@
}, },
"CHANGE_OWNER": { "CHANGE_OWNER": {
"TITLE": "Who do you want to be the new project owner?", "TITLE": "Who do you want to be the new project owner?",
"ADD_COMMENT": "Add comment", "ADD_COMMENT": "Lägg till kommentar",
"BUTTON": "Ask this project member to become the new project owner" "BUTTON": "Ask this project member to become the new project owner"
} }
}, },
@ -1368,7 +1367,7 @@
"USER_PROFILE": "Användarprofil", "USER_PROFILE": "Användarprofil",
"CHANGE_PASSWORD": "Ändra lösenord", "CHANGE_PASSWORD": "Ändra lösenord",
"NOTIFICATIONS": "Notifieringar", "NOTIFICATIONS": "Notifieringar",
"FEEDBACK": "Återkokppling", "FEEDBACK": "Återkoppling",
"TITLE_AVATAR": "Inställningar för användare" "TITLE_AVATAR": "Inställningar för användare"
} }
}, },
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Skriv din wiki-sida", "PLACEHOLDER_PAGE": "Skriv din wiki-sida",
"REMOVE": "Ta bort den här wiki-sidan", "REMOVE": "Ta bort den här wiki-sidan",
"DELETE_LIGHTBOX_TITLE": "Ta bort Wiki-sida", "DELETE_LIGHTBOX_TITLE": "Ta bort Wiki-sida",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Länkar", "SECTION_NAME": "Länkar",
"ACTION_ADD_LINK": "Lägg till länk" "ACTION_ADD_LINK": "Lägg till länk"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "engel notu", "BLOCKED_NOTE": "engel notu",
"IS_BLOCKED": "engellendi ", "IS_BLOCKED": "engellendi ",
"REF": "Ref", "REF": "Ref",
"VOTES": "Oylar" "VOTES": "Oylar",
"SPRINT": "Koşu"
}, },
"ROLES": { "ROLES": {
"ALL": "Hepsi" "ALL": "Hepsi"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "AnaSayfa - Taiga", "PAGE_TITLE": "AnaSayfa - Taiga",
"PAGE_DESCRIPTION": "Atanmış ve izlenen kullanıcı hikayeleri, işler ve sorunların yanı sıra ana projeleriniz için Taiga ana sayfanız", "PAGE_DESCRIPTION": "Atanmış ve izlenen kullanıcı hikayeleri, işler ve sorunların yanı sıra ana projeleriniz için Taiga ana sayfanız",
"EMPTY_WORKING_ON": "<strong>Bomboş hissettiriyor degil mi?</strong> Taiga ile çalışmaya başlayın ve burada üzerinde çalıştığınız hikayeleri, işleri ve sorunları göreceksiniz.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "Projelerinizdeki Kullanıcı Hikayelerini, İşleri ve Sorunları <strong>takip edin</strong> ve değişikliklerden haberdar olun :) ", "EMPTY_WATCHING": "Projelerinizdeki Kullanıcı Hikayelerini, İşleri ve Sorunları <strong>takip edin</strong> ve değişikliklerden haberdar olun :) ",
"EMPTY_PROJECT_LIST": "Henüz bir projeniz yok", "EMPTY_PROJECT_LIST": "Henüz bir projeniz yok",
"WORKING_ON_SECTION": "Üzerinde çalışılıyor", "WORKING_ON_SECTION": "Üzerinde çalışılıyor",
@ -556,9 +557,8 @@
"PAGE_TITLE": "Roller - {{projectName}}", "PAGE_TITLE": "Roller - {{projectName}}",
"WARNING_NO_ROLE": "Dikkat edin, projenizdeki rollerden hiçbiri kullanıcı hikayeleri için puan değeri kestirimi yapma yetkisine sahip değil.", "WARNING_NO_ROLE": "Dikkat edin, projenizdeki rollerden hiçbiri kullanıcı hikayeleri için puan değeri kestirimi yapma yetkisine sahip değil.",
"HELP_ROLE_ENABLED": "Etkileştirildiğinde, bu role atanan üyeler kullanıcı hikayeleri için puan kestirimi yapabilecek", "HELP_ROLE_ENABLED": "Etkileştirildiğinde, bu role atanan üyeler kullanıcı hikayeleri için puan kestirimi yapabilecek",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Bu rol için kestirimi kapat", "DISABLE_COMPUTABLE_ALERT_TITLE": "Bu role ait kestirimleri kapatmak istediğinizden emin misiniz?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "{{roleName}} görevi için tahmin izinlerini kaldırırsanız, bu görevdekiler tarafından daha önce yapılmış tüm tahminler silinir", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "{{roleName}} görevi için tahmin izinlerini kaldırırsanız, bu görevdekiler tarafından daha önce yapılmış tüm tahminler silinir",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Bu role ait kestirimleri kapatmak istediğinizden emin misiniz?</strong>",
"COUNT_MEMBERS": "bu roldeki üyelerin sayısı {{ role.members_count }} ", "COUNT_MEMBERS": "bu roldeki üyelerin sayısı {{ role.members_count }} ",
"TITLE_DELETE_ROLE": "Rol Sil", "TITLE_DELETE_ROLE": "Rol Sil",
"REPLACEMENT_ROLE": "Bu role sahip kullanıcıların taşınacağı", "REPLACEMENT_ROLE": "Bu role sahip kullanıcıların taşınacağı",
@ -699,7 +699,6 @@
"ACCEPT": "Kabul et", "ACCEPT": "Kabul et",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "Wiki sayfanı yaz ", "PLACEHOLDER_PAGE": "Wiki sayfanı yaz ",
"REMOVE": "Bu wiki sayfasını sil", "REMOVE": "Bu wiki sayfasını sil",
"DELETE_LIGHTBOX_TITLE": "Wiki Sayfası Sil", "DELETE_LIGHTBOX_TITLE": "Wiki Sayfası Sil",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "Bağlantılar", "SECTION_NAME": "Bağlantılar",
"ACTION_ADD_LINK": "Bağlantı ekle" "ACTION_ADD_LINK": "Bağlantı ekle"

View File

@ -140,7 +140,8 @@
"BLOCKED_NOTE": "已封鎖之筆記", "BLOCKED_NOTE": "已封鎖之筆記",
"IS_BLOCKED": "封鎖", "IS_BLOCKED": "封鎖",
"REF": "Ref", "REF": "Ref",
"VOTES": "投票數" "VOTES": "投票數",
"SPRINT": "衝刺任務"
}, },
"ROLES": { "ROLES": {
"ALL": "所有" "ALL": "所有"
@ -355,7 +356,7 @@
"HOME": { "HOME": {
"PAGE_TITLE": "首頁 - Taiga", "PAGE_TITLE": "首頁 - Taiga",
"PAGE_DESCRIPTION": "Taiga 首頁,你的主要專案以及任命,觀看使用者故事,任務與問題。", "PAGE_DESCRIPTION": "Taiga 首頁,你的主要專案以及任命,觀看使用者故事,任務與問題。",
"EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are workin on.", "EMPTY_WORKING_ON": "<strong>It feels empty, doesn't it?</strong> Start working with Taiga and you'll see here the stories, tasks and issues you are working on.",
"EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)", "EMPTY_WATCHING": "<strong>Follow</strong> User Stories, Tasks, Issues in your projects and be notified about its changes :)",
"EMPTY_PROJECT_LIST": "你尚無任何專案", "EMPTY_PROJECT_LIST": "你尚無任何專案",
"WORKING_ON_SECTION": "進行中", "WORKING_ON_SECTION": "進行中",
@ -556,9 +557,8 @@
"PAGE_TITLE": "角色- {{projectName}}", "PAGE_TITLE": "角色- {{projectName}}",
"WARNING_NO_ROLE": "注意,你的專案中無角色可以評估使用者故事的點數", "WARNING_NO_ROLE": "注意,你的專案中無角色可以評估使用者故事的點數",
"HELP_ROLE_ENABLED": "當啟動時,被指派此角色的成員將可以評估使用者故事點數", "HELP_ROLE_ENABLED": "當啟動時,被指派此角色的成員將可以評估使用者故事點數",
"DISABLE_COMPUTABLE_ALERT_TITLE": "Disable estimation for this role", "DISABLE_COMPUTABLE_ALERT_TITLE": "Are you sure you want to disable this role estimations?",
"DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed", "DISABLE_COMPUTABLE_ALERT_SUBTITLE": "If you disable estimation permissions for role {{roleName}} all previous estimations made by this role will be removed",
"DISABLE_COMPUTABLE_ALERT_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
"COUNT_MEMBERS": "{{ role.members_count }} 這類角色的成員", "COUNT_MEMBERS": "{{ role.members_count }} 這類角色的成員",
"TITLE_DELETE_ROLE": "删除角色", "TITLE_DELETE_ROLE": "删除角色",
"REPLACEMENT_ROLE": "和此角色有關的使用者都將遭移除 ", "REPLACEMENT_ROLE": "和此角色有關的使用者都將遭移除 ",
@ -699,7 +699,6 @@
"ACCEPT": "接受", "ACCEPT": "接受",
"REJECT": "Reject", "REJECT": "Reject",
"PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.", "PROPOSE_OWNERSHIP": "<strong>{{owner}}</strong>, the current owner of the project <strong>{{project}}</strong> has asked that you become the new project owner.",
"ADD_COMMENT_QUESTION": "Would you like to send a question to the project owner?",
"ADD_COMMENT": "Would you like to add a comment for the project owner?", "ADD_COMMENT": "Would you like to add a comment for the project owner?",
"UNLIMITED_PROJECTS": "Unlimited", "UNLIMITED_PROJECTS": "Unlimited",
"OWNER_MESSAGE": { "OWNER_MESSAGE": {
@ -1413,6 +1412,7 @@
"PLACEHOLDER_PAGE": "編寫你的維基頁", "PLACEHOLDER_PAGE": "編寫你的維基頁",
"REMOVE": "移除此維基頁 ", "REMOVE": "移除此維基頁 ",
"DELETE_LIGHTBOX_TITLE": "刪除維基頁", "DELETE_LIGHTBOX_TITLE": "刪除維基頁",
"DELETE_LINK_TITLE": "Delete Wiki link",
"NAVIGATION": { "NAVIGATION": {
"SECTION_NAME": "連結", "SECTION_NAME": "連結",
"ACTION_ADD_LINK": "新增連結" "ACTION_ADD_LINK": "新增連結"

View File

@ -14,7 +14,7 @@
} }
} }
.attachment-name { .attachment-name {
@extend %light; @include font-type(light);
@include ellipsis(175px); @include ellipsis(175px);
display: inline-block; display: inline-block;
} }

View File

@ -51,10 +51,12 @@
opacity: 0; opacity: 0;
} }
.editable-settings { .editable-settings {
display: block;
opacity: 1; opacity: 1;
} }
svg { svg {
fill: $gray-light; fill: $gray-light;
pointer-events: none;
} }
.icon-edit, .icon-edit,
.icon-save { .icon-save {

View File

@ -1,5 +1,20 @@
.attachments { .attachments {
margin-bottom: 2rem; margin-bottom: 4rem;
.gu-transit {
background: $whitish;
height: 40px;
* {
display: none;
}
}
.gu-mirror {
opacity: 1;
form {
background: lighten($primary, 60%);
box-shadow: 1px 1px 10px rgba($black, .1);
transition: background .2s ease-in;
}
}
} }
.attachments-header { .attachments-header {
@ -10,8 +25,8 @@
justify-content: space-between; justify-content: space-between;
min-height: 36px; min-height: 36px;
.attachments-title { .attachments-title {
@extend %medium; @include font-type(bold);
@extend %bold; @include font-size(medium);
color: $grayer; color: $grayer;
line-height: 36px; line-height: 36px;
padding: 0 1rem; padding: 0 1rem;
@ -55,8 +70,8 @@
} }
} }
.size-info { .size-info {
@extend %light; @include font-size(small);
@extend %small; @include font-type(light);
color: $gray; color: $gray;
padding-left: 1rem; padding-left: 1rem;
} }
@ -66,8 +81,8 @@
} }
.attachments-empty { .attachments-empty {
@extend %large; @include font-size(large);
@extend %bold; @include font-type(bold);
border: 3px dashed $whitish; border: 3px dashed $whitish;
color: $gray-light; color: $gray-light;
margin-top: .5rem; margin-top: .5rem;
@ -76,19 +91,10 @@
} }
.single-attachment { .single-attachment {
@extend %small; @include font-size(small);
background: rgba($white, .9); background: rgba($white, .9);
&.ui-sortable-helper {
background: lighten($primary, 60%);
box-shadow: 1px 1px 10px rgba($black, .1);
transition: background .2s ease-in;
}
&.sortable-placeholder {
background: $whitish;
height: 40px;
}
.attachment-name { .attachment-name {
@extend %bold; @include font-type(bold);
padding-right: 1rem; padding-right: 1rem;
svg { svg {
fill: $gray; fill: $gray;
@ -103,7 +109,7 @@
} }
.more-attachments { .more-attachments {
@extend %small; @include font-size(small);
border-bottom: 1px solid $gray-light; border-bottom: 1px solid $gray-light;
display: block; display: block;
padding: 1rem 0 1rem 1rem; padding: 1rem 0 1rem 1rem;

View File

@ -34,5 +34,4 @@
title="{{'COMMON.DELETE' | translate}}" title="{{'COMMON.DELETE' | translate}}"
ng-click="vm.delete()" ng-click="vm.delete()"
) )
svg.icon.icon-trash tg-svg(svg-icon="icon-trash")
use(xlink:href="#icon-trash")

View File

@ -12,8 +12,7 @@ form.single-attachment(
target="_blank" target="_blank"
download="{{::vm.attachment.getIn(['file', 'name'])}}" download="{{::vm.attachment.getIn(['file', 'name'])}}"
) )
svg.icon.icon-attachment tg-svg(svg-icon="icon-attachment")
use(xlink:href="#icon-attachment")
span {{::vm.attachment.getIn(['file', 'name'])}} span {{::vm.attachment.getIn(['file', 'name'])}}
.attachment-comments(ng-if="!vm.attachment.get('editable') && vm.attachment.getIn(['file', 'description'])") .attachment-comments(ng-if="!vm.attachment.get('editable') && vm.attachment.getIn(['file', 'description'])")
@ -47,44 +46,39 @@ form.single-attachment(
.attachment-settings(ng-if="vm.attachment.get('editable')") .attachment-settings(ng-if="vm.attachment.get('editable')")
div(tg-loading="vm.attachment.get('loading')") div(tg-loading="vm.attachment.get('loading')")
a.editable-settings( a.editable-settings.e2e-save(
href="" href=""
title="{{'COMMON.SAVE' | translate}}" title="{{'COMMON.SAVE' | translate}}"
ng-click="vm.save()" ng-click="vm.save()"
) )
svg.drag.icon.icon-save tg-svg(svg-icon="icon-save")
use(xlink:href="#icon-save")
div div
a.editable-settings( a.editable-settings.e2e-cancel(
href="" href=""
title="{{'COMMON.CANCEL' | translate}}" title="{{'COMMON.CANCEL' | translate}}"
ng-click="vm.editMode(false)" ng-click="vm.editMode(false)"
) )
svg.drag.icon.icon-close tg-svg(svg-icon="icon-close")
use(xlink:href="#icon-close")
.attachment-settings( .attachment-settings(
ng-if="!vm.attachment.get('editable')" ng-if="!vm.attachment.get('editable')"
tg-check-permission="modify_{{vm.type}}" tg-check-permission="modify_{{vm.type}}"
) )
a.settings( a.settings.e2e-edit(
href="" href=""
title="{{'COMMON.EDIT' | translate}}" title="{{'COMMON.EDIT' | translate}}"
ng-click="vm.editMode(true)" ng-click="vm.editMode(true)"
) )
svg.drag.icon.icon-edit tg-svg.drag(svg-icon="icon-edit")
use(xlink:href="#icon-edit") a.settings.e2e-delete(
a.settings(
href="" href=""
title="{{'COMMON.DELETE' | translate}}" title="{{'COMMON.DELETE' | translate}}"
ng-click="vm.delete()" ng-click="vm.delete()"
) )
svg.drag.icon.icon-trash tg-svg.drag(svg-icon="icon-trash")
use(xlink:href="#icon-trash")
a.settings( a.settings(
href="" href=""
title="{{'COMMON.DRAG' | translate}}" title="{{'COMMON.DRAG' | translate}}"
) )
svg.drag.icon.icon-drag tg-svg.drag(svg-icon="icon-drag")
use(xlink:href="#icon-drag")

View File

@ -11,24 +11,21 @@ section.attachments(
ng-click="vm.setMode('gallery')" ng-click="vm.setMode('gallery')"
title="{{ 'ATTACHMENT.GALLERY_VIEW_MODE' | translate }}" title="{{ 'ATTACHMENT.GALLERY_VIEW_MODE' | translate }}"
) )
svg.icon.icon-gallery tg-svg(svg-icon="icon-gallery")
use(xlink:href="#icon-gallery")
button.view-list( button.view-list(
ng-class="{'is-active': vm.mode == 'list'}" ng-class="{'is-active': vm.mode == 'list'}"
ng-if="vm.attachments.size" ng-if="vm.attachments.size"
ng-click="vm.setMode('list')" ng-click="vm.setMode('list')"
title="{{ 'ATTACHMENT.LIST_VIEW_MODE' | translate }}" title="{{ 'ATTACHMENT.LIST_VIEW_MODE' | translate }}"
) )
svg.icon.icon-list tg-svg(svg-icon="icon-list")
use(xlink:href="#icon-list")
.add-attach( .add-attach(
tg-check-permission="modify_{{vm.type}}" tg-check-permission="modify_{{vm.type}}"
title!="{{'ATTACHMENT.ADD' | translate}}" title!="{{'ATTACHMENT.ADD' | translate}}"
) )
label.add-attachment-button(for="add-attach") label.add-attachment-button(for="add-attach")
svg.icon.icon-add tg-svg(svg-icon="icon-add")
use(xlink:href="#icon-add")
input( input(
id="add-attach", id="add-attach",
@ -55,8 +52,7 @@ section.attachments(
.single-attachment(ng-repeat="file in vm.uploadingAttachments()") .single-attachment(ng-repeat="file in vm.uploadingAttachments()")
.attachment-name .attachment-name
svg.icon.icon-attachment tg-svg(svg-icon="icon-attachment")
use(xlink:href="#icon-attachment")
span {{file.name}} span {{file.name}}
.attachment-size .attachment-size
span {{file.size | sizeFormat}} span {{file.size | sizeFormat}}

View File

@ -5,8 +5,7 @@ section.attachments(tg-attachments-drop="vm.addAttachments(files)")
h3.attachments-title #[span.attachments-num {{vm.attachments.size}}] #[span.attachments-text(translate="ATTACHMENT.SECTION_NAME")] h3.attachments-title #[span.attachments-num {{vm.attachments.size}}] #[span.attachments-text(translate="ATTACHMENT.SECTION_NAME")]
.add-attach(title!="{{'ATTACHMENT.ADD' | translate}}") .add-attach(title!="{{'ATTACHMENT.ADD' | translate}}")
label.add-attachment-button(for="add-attach") label.add-attachment-button(for="add-attach")
svg.icon.icon-add tg-svg(svg-icon="icon-add")
use(xlink:href="#icon-add")
input( input(
id="add-attach" id="add-attach"
type="file" type="file"
@ -19,8 +18,7 @@ section.attachments(tg-attachments-drop="vm.addAttachments(files)")
.attachment-body.attachment-list .attachment-body.attachment-list
.single-attachment(tg-repeat="attachment in vm.attachments track by $index") .single-attachment(tg-repeat="attachment in vm.attachments track by $index")
.attachment-name .attachment-name
svg.icon.icon-attachment tg-svg(svg-icon="icon-attachment")
use(xlink:href="#icon-attachment")
span {{attachment.get('name')}} span {{attachment.get('name')}}
.attachment-size .attachment-size
span {{attachment.get('size') | sizeFormat}} span {{attachment.get('size') | sizeFormat}}
@ -31,5 +29,4 @@ section.attachments(tg-attachments-drop="vm.addAttachments(files)")
title="{{'COMMON.DELETE' | translate}}" title="{{'COMMON.DELETE' | translate}}"
ng-click="vm.deleteAttachment(attachment)" ng-click="vm.deleteAttachment(attachment)"
) )
svg.icon.icon-trash tg-svg(svg-icon="icon-trash")
use(xlink:href="#icon-trash")

View File

@ -21,25 +21,34 @@ AttachmentSortableDirective = ($parse) ->
link = (scope, el, attrs) -> link = (scope, el, attrs) ->
callback = $parse(attrs.tgAttachmentsSortable) callback = $parse(attrs.tgAttachmentsSortable)
el.sortable({ drake = dragula([el[0]], {
items: "div[tg-bind-scope]" copySortSource: false,
handle: ".settings .icon" copy: false,
containment: ".attachments" mirrorContainer: el[0],
dropOnEmpty: true moves: (item) -> return $(item).is('div[tg-bind-scope]')
helper: 'clone'
scroll: false
tolerance: "pointer"
placeholder: "sortable-placeholder single-attachment"
}) })
el.on "sortstop", (event, ui) -> drake.on 'dragend', (item) ->
attachment = ui.item.scope().attachment item = $(item)
newIndex = ui.item.index()
attachment = item.scope().attachment
newIndex = item.index()
scope.$apply () -> scope.$apply () ->
callback(scope, {attachment: attachment, index: newIndex}) callback(scope, {attachment: attachment, index: newIndex})
scope.$on "$destroy", -> el.off() scroll = autoScroll(window, {
margin: 20,
pixels: 30,
scrollWhenOutside: true,
autoScroll: () ->
return this.down && drake.dragging;
})
scope.$on "$destroy", ->
el.off()
drake.destroy()
return { return {
link: link link: link

View File

@ -7,7 +7,6 @@
a.close( a.close(
ng-click="vm.close()" ng-click="vm.close()"
href="" href=""
title="{{ COMMON.CLOSE | translate }}" ng-title="COMMON.CLOSE | translate"
) )
svg.icon.icon-close tg-svg(svg-icon="icon-close")
use(xlink:href="#icon-close")

View File

@ -43,26 +43,27 @@
width: 100%; width: 100%;
} }
.title { .title {
@extend %bold; @include font-type(bold);
@extend %larger; @include font-size(larger);
color: $tribe-secondary; color: $tribe-secondary;
margin-bottom: .5rem; margin-bottom: .5rem;
} }
.warning { .warning {
color: $tribe-secondary; color: $tribe-secondary;
a { a {
@extend %bold; @include font-type(bold);
color: $tribe-secondary; color: $tribe-secondary;
} }
} }
.close { .close {
height: 2.5rem; display: block;
position: absolute; position: absolute;
right: 0; right: 0;
top: 1rem; top: 1rem;
width: 2.5rem;
svg { svg {
@include svg-size(2rem);
fill: lighten($tribe-secondary, 15%); fill: lighten($tribe-secondary, 15%);
pointer-events: none;
transition: fill .2s; transition: fill .2s;
&:hover { &:hover {
fill: $tribe-secondary; fill: $tribe-secondary;

View File

@ -1,105 +1,96 @@
nav.menu( nav.menu(
ng-if="vm.project" ng-if="vm.project"
ng-class="{'menu-fixed': vm.fixed}", ng-class="{'menu-fixed': vm.fixed}",
) )
div(class="menu-container") .menu-container
ul(class="main-nav") ul.main-nav
li(id="nav-search") li#nav-search
a( a(
href="" href=""
ng-click="vm.search()" ng-click="vm.search()"
ng-class="{active: vm.active == 'search'}" ng-class="{active: vm.active == 'search'}"
aria-label="{{'PROJECT.SECTION.SEARCH' | translate}}" aria-label="{{'PROJECT.SECTION.SEARCH' | translate}}"
tabindex="1" tabindex="1"
) )
svg.icon.icon-search tg-svg(svg-icon="icon-search")
use(xlink:href="#icon-search") span.helper(translate="PROJECT.SECTION.SEARCH")
span.helper(translate="PROJECT.SECTION.SEARCH")
li(id="nav-timeline") li#nav-timeline
a( a(
tg-nav="project:project=vm.project.get('slug')" tg-nav="project:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'project-timeline'}" ng-class="{active: vm.active == 'project-timeline'}"
aria-label="{{'PROJECT.SECTION.TIMELINE' | translate}}" aria-label="{{'PROJECT.SECTION.TIMELINE' | translate}}"
tabindex="2" tabindex="2"
) )
svg.icon.icon-timeline tg-svg(svg-icon="icon-timeline")
use(xlink:href="#icon-timeline")
span.helper(translate="PROJECT.SECTION.TIMELINE") span.helper(translate="PROJECT.SECTION.TIMELINE")
li(id="nav-backlog", ng-if="vm.menu.get('backlog')") li#nav-backlog(ng-if="vm.menu.get('backlog')")
a( a(
tg-nav="project-backlog:project=vm.project.get('slug')" tg-nav="project-backlog:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'backlog'}" ng-class="{active: vm.active == 'backlog'}"
aria-label="{{'PROJECT.SECTION.BACKLOG' | translate}}" aria-label="{{'PROJECT.SECTION.BACKLOG' | translate}}"
tabindex="2" tabindex="2"
) )
svg.icon.icon-scrum tg-svg(svg-icon="icon-scrum")
use(xlink:href="#icon-scrum")
span.helper(translate="PROJECT.SECTION.BACKLOG") span.helper(translate="PROJECT.SECTION.BACKLOG")
li(id="nav-kanban", ng-if="vm.menu.get('kanban')") li#nav-kanban(ng-if="vm.menu.get('kanban')")
a( a(
tg-nav="project-kanban:project=vm.project.get('slug')" tg-nav="project-kanban:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'kanban'}" ng-class="{active: vm.active == 'kanban'}"
aria-label="{{'PROJECT.SECTION.KANBAN' | translate}}" aria-label="{{'PROJECT.SECTION.KANBAN' | translate}}"
tabindex="3" tabindex="3"
) )
svg.icon.icon-kanban tg-svg(svg-icon="icon-kanban")
use(xlink:href="#icon-kanban")
span.helper(translate="PROJECT.SECTION.KANBAN") span.helper(translate="PROJECT.SECTION.KANBAN")
li(id="nav-issues", ng-if="vm.menu.get('issues')") li#nav-issues(ng-if="vm.menu.get('issues')")
a( a(
tg-nav="project-issues:project=vm.project.get('slug')" tg-nav="project-issues:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'issues'}" ng-class="{active: vm.active == 'issues'}"
aria-label="{{'PROJECT.SECTION.ISSUES' | translate}}" aria-label="{{'PROJECT.SECTION.ISSUES' | translate}}"
tabindex="4" tabindex="4"
) )
svg.icon.icon-issues tg-svg(svg-icon="icon-issues")
use(xlink:href="#icon-issues")
span.helper(translate="PROJECT.SECTION.ISSUES") span.helper(translate="PROJECT.SECTION.ISSUES")
li(id="nav-wiki", ng-if="vm.menu.get('wiki')") li#nav-wiki(ng-if="vm.menu.get('wiki')")
a( a(
tg-nav="project-wiki:project=vm.project.get('slug')" tg-nav="project-wiki:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'wiki'}" ng-class="{active: vm.active == 'wiki'}"
aria-label="{{'PROJECT.SECTION.WIKI' | translate}}" aria-label="{{'PROJECT.SECTION.WIKI' | translate}}"
tabindex="5" tabindex="5"
) )
svg.icon.icon-wiki tg-svg(svg-icon="icon-wiki")
use(xlink:href="#icon-wiki")
span.helper(translate="PROJECT.SECTION.WIKI") span.helper(translate="PROJECT.SECTION.WIKI")
li(id="nav-team") li#nav-team
a( a(
tg-nav="project-team:project=vm.project.get('slug')" tg-nav="project-team:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'team'}" ng-class="{active: vm.active == 'team'}"
aria-label="{{'PROJECT.SECTION.TEAM' | translate}}" aria-label="{{'PROJECT.SECTION.TEAM' | translate}}"
tabindex="6" tabindex="6"
) )
svg.icon.icon-team tg-svg(svg-icon="icon-team")
use(xlink:href="#icon-team")
span.helper(translate="PROJECT.SECTION.TEAM") span.helper(translate="PROJECT.SECTION.TEAM")
li(id="nav-video", ng-if="vm.project.get('videoconferenceUrl')") li#nav-video(ng-if="vm.project.get('videoconferenceUrl')")
a( a(
ng-href="{{vm.project.get('videoconferenceUrl')}}" ng-href="{{vm.project.get('videoconferenceUrl')}}"
target="_blank" target="_blank"
aria-label="{{'PROJECT.SECTION.MEETUP' | translate}}" aria-label="{{'PROJECT.SECTION.MEETUP' | translate}}"
tabindex="7" tabindex="7"
) )
svg.icon.icon-bubble tg-svg(svg-icon="icon-bubble")
use(xlink:href="#icon-bubble")
span.helper(translate="PROJECT.SECTION.MEETUP") span.helper(translate="PROJECT.SECTION.MEETUP")
li(id="nav-admin", ng-if="vm.project.get('i_am_admin')") li#nav-admin(ng-if="vm.project.get('i_am_admin')")
a( a(
tg-nav="project-admin-home:project=vm.project.get('slug')" tg-nav="project-admin-home:project=vm.project.get('slug')"
ng-class="{active: vm.active == 'admin'}" ng-class="{active: vm.active == 'admin'}"
aria-label="{{'PROJECT.SECTION.ADMIN' | translate}}" aria-label="{{'PROJECT.SECTION.ADMIN' | translate}}"
tabindex="8" tabindex="8"
) )
svg.icon.icon-settings tg-svg(svg-icon="icon-settings")
use(xlink:href="#icon-settings")
span.helper(translate="PROJECT.SECTION.ADMIN") span.helper(translate="PROJECT.SECTION.ADMIN")

View File

@ -9,8 +9,7 @@ a.vote-inner(
ng-mouseleave="vm.showTextWhenMouseIsLeave()" ng-mouseleave="vm.showTextWhenMouseIsLeave()"
) )
span.track-icon span.track-icon
svg.icon.icon-upvote tg-svg(svg-icon="icon-upvote")
use(xlink:href="#icon-upvote")
span.track-button-counter( span.track-button-counter(
title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.total_voters||0}:'messageformat' }}", title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.total_voters||0}:'messageformat' }}",
tg-loading="vm.loading" tg-loading="vm.loading"
@ -19,8 +18,7 @@ a.vote-inner(
//- Anonymous user button //- Anonymous user button
span.vote-inner(ng-if="::!vm.user") span.vote-inner(ng-if="::!vm.user")
span.track-icon span.track-icon
svg.icon.icon-upvote tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-upvote")
span.track-button-counter( span.track-button-counter(
title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.total_voters||0}:'messageformat' }}" title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.total_voters||0}:'messageformat' }}"
) {{ ::vm.item.total_voters }} ) {{ ::vm.item.total_voters }}

View File

@ -14,17 +14,14 @@ div.ticket-watch-inner
ng-mouseleave="vm.showTextWhenMouseIsLeave()" ng-mouseleave="vm.showTextWhenMouseIsLeave()"
) )
span(ng-if="!vm.item.is_watcher") span(ng-if="!vm.item.is_watcher")
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch") span {{'COMMON.WATCH_BUTTON.WATCH' | translate}}
| {{'COMMON.WATCH_BUTTON.WATCH' | translate}}
span(ng-if="vm.item.is_watcher && !vm.isMouseOver",) span(ng-if="vm.item.is_watcher && !vm.isMouseOver",)
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch") span {{'COMMON.WATCH_BUTTON.WATCHING' | translate}}
| {{'COMMON.WATCH_BUTTON.WATCHING' | translate}}
span(ng-if="vm.item.is_watcher && vm.isMouseOver") span(ng-if="vm.item.is_watcher && vm.isMouseOver")
svg.icon.icon-unwatch tg-svg(svg-icon="icon-unwatch")
use(xlink:href="#icon-unwatch") span {{'COMMON.WATCH_BUTTON.UNWATCH' | translate}}
| {{'COMMON.WATCH_BUTTON.UNWATCH' | translate}}
a.add-watcher( a.add-watcher(
href="" href=""

View File

@ -16,8 +16,7 @@ a.track-button.watch-button.watch-container(
ng-mouseleave="vm.showTextWhenMouseIsLeave()" ng-mouseleave="vm.showTextWhenMouseIsLeave()"
) )
span.track-inner span.track-inner
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span( span(
ng-if="!vm.item.is_watcher", ng-if="!vm.item.is_watcher",
translate="COMMON.WATCH_BUTTON.WATCH" translate="COMMON.WATCH_BUTTON.WATCH"
@ -38,7 +37,6 @@ span.track-button.watch-button.watch-container(
) )
span.track-inner span.track-inner
span.track-icon span.track-icon
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span(translate="COMMON.WATCH_BUTTON.WATCHERS") span(translate="COMMON.WATCH_BUTTON.WATCHERS")
+counter +counter

View File

@ -3,8 +3,7 @@
href="#" href="#"
ng-click="vm.open()" ng-click="vm.open()"
) {{vm.currentText()}} ) {{vm.currentText()}}
svg.icon.icon-arrow-down tg-svg(svg-icon="icon-arrow-down")
use(xlink:href="#icon-arrow-down")
ul.filter-list(ng-if="vm.is_open") ul.filter-list(ng-if="vm.is_open")
li(ng-click="vm.orderBy('week')") {{ 'DISCOVER.FILTERS.WEEK' | translate }} li(ng-click="vm.orderBy('week')") {{ 'DISCOVER.FILTERS.WEEK' | translate }}

View File

@ -18,12 +18,11 @@ div.discover-header
placeholder="{{ 'DISCOVER.SEARCH.INPUT_PLACEHOLDER' | translate }}" placeholder="{{ 'DISCOVER.SEARCH.INPUT_PLACEHOLDER' | translate }}"
ng-model="vm.q" ng-model="vm.q"
) )
svg.search-button.icon.icon-search( tg-svg.search-button(
ng-click="vm.submitFilter()" ng-click="vm.submitFilter()"
href="#" svg-icon="icon-search"
title="{{ 'DISCOVER.SEARCH.ACTION_TITLE' | translate }}" svg-title-translate="DISCOVER.SEARCH.ACTION_TITLE"
) )
use(xlink:href="#icon-search")
fieldset.searchbox-filters(ng-if="vm.filter") fieldset.searchbox-filters(ng-if="vm.filter")
input( input(

View File

@ -8,12 +8,12 @@
margin: 0 auto; margin: 0 auto;
} }
.title { .title {
@extend %xxlarge; @include font-size(xxlarge);
margin-bottom: 0; margin-bottom: 0;
} }
.project-number { .project-number {
@extend %light; @include font-type(light);
@extend %large; @include font-size(large);
color: $primary; color: $primary;
} }
form { form {

View File

@ -1,8 +1,7 @@
.discover-results-header .discover-results-header
.discover-results-header-inner .discover-results-header-inner
.title .title
svg.icon.icon-search tg-svg(svg-icon="icon-search")
use(xlink:href="#icon-search")
h2 {{ 'DISCOVER.SEARCH.RESULTS' | translate }} h2 {{ 'DISCOVER.SEARCH.RESULTS' | translate }}
.filter-discover-search(ng-mouseleave="vm.toggleClose()") .filter-discover-search(ng-mouseleave="vm.toggleClose()")
@ -11,16 +10,14 @@
ng-click="vm.openLike()" ng-click="vm.openLike()"
ng-class="{active: vm.like_is_open}" ng-class="{active: vm.like_is_open}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{ 'DISCOVER.MOST_LIKED' | translate }} span {{ 'DISCOVER.MOST_LIKED' | translate }}
a.discover-search-filter( a.discover-search-filter(
href="#" href="#"
ng-click="vm.openActivity()" ng-click="vm.openActivity()"
ng-class="{active: vm.activity_is_open}" ng-class="{active: vm.activity_is_open}"
) )
svg.icon.icon-activity tg-svg(svg-icon="icon-activity")
use(xlink:href="#icon-activity")
span {{ 'DISCOVER.MOST_ACTIVE' | translate }} span {{ 'DISCOVER.MOST_ACTIVE' | translate }}
.discover-search-subfilter.most-liked-subfilter(ng-if="vm.like_is_open") .discover-search-subfilter.most-liked-subfilter(ng-if="vm.like_is_open")

View File

@ -10,8 +10,8 @@
margin-right: .25rem; margin-right: .25rem;
} }
.title { .title {
@extend %bold; @include font-type(bold);
@extend %larger; @include font-size(larger);
text-transform: uppercase; text-transform: uppercase;
} }
h2 { h2 {
@ -57,7 +57,7 @@
animation: dropdownFade .2s; animation: dropdownFade .2s;
} }
.results { .results {
@extend %small; @include font-size(small);
color: $red-light; color: $red-light;
display: block; display: block;
padding: .5rem 1rem; padding: .5rem 1rem;

View File

@ -26,31 +26,28 @@
tg-nav="project:project=project.get('slug')" tg-nav="project:project=project.get('slug')"
title="{{::project.get('name')}}" title="{{::project.get('name')}}"
) {{::project.get('name')}} ) {{::project.get('name')}}
svg.look-for-people.icon.icon-recruit( tg-svg.look-for-people(
ng-if="project.get('is_looking_for_people')" ng-if="project.get('is_looking_for_people')"
svg-icon="icon-recruit"
svg-title="{{ ::project.get('looking_for_people_note') }}"
) )
use(xlink:href="#icon-recruit")
title="{{ ::project.get('looking_for_people_note') }}"
p.project-card-description {{ ::project.get('description') | limitTo:100 }}{{ ::project.get('description').length < 100 ? '' : '...'}} p.project-card-description {{ ::project.get('description') | limitTo:100 }}{{ ::project.get('description').length < 100 ? '' : '...'}}
.project-card-statistics .project-card-statistics
span.statistic( span.statistic(
ng-class="{'active': project.get('is_fan')}" ng-class="{'active': project.get('is_fan')}"
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}" title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{::project.get('total_fans')}} span {{::project.get('total_fans')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('is_watcher')}" ng-class="{'active': project.get('is_watcher')}"
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}" title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{::project.get('total_watchers')}} span {{::project.get('total_watchers')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('i_am_member')}" ng-class="{'active': project.get('i_am_member')}"
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}" title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
) )
svg.icon.icon-team tg-svg(svg-icon="icon-team")
use(xlink:href="#icon-team")
span.statistics-num {{ ::project.get('members').size }} span.statistics-num {{ ::project.get('members').size }}

View File

@ -3,8 +3,8 @@
.featured-projects { .featured-projects {
@include centered; @include centered;
.title { .title {
@extend %bold; @include font-type(bold);
@extend %larger; @include font-size(larger);
color: $grayer; color: $grayer;
text-align: center; text-align: center;
} }

View File

@ -24,30 +24,29 @@
tg-nav="project:project=project.get('slug')" tg-nav="project:project=project.get('slug')"
title="{{::project.get('name')}}" title="{{::project.get('name')}}"
) {{::project.get('name')}} ) {{::project.get('name')}}
svg.look-for-people.icon.icon-recruit(ng-if="project.get('is_looking_for_people')") tg-svg.look-for-people(
use(xlink:href="#icon-recruit") ng-if="project.get('is_looking_for_people')"
title="{{ ::project.get('looking_for_people_note') }}" svg-icon="icon-recruit"
svg-title="{{ ::project.get('looking_for_people_note') }}"
)
.project-statistics .project-statistics
span.statistic( span.statistic(
ng-class="{'active': project.get('is_fan')}" ng-class="{'active': project.get('is_fan')}"
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}" title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{::project.get('total_fans')}} span {{::project.get('total_fans')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('is_watcher')}" ng-class="{'active': project.get('is_watcher')}"
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}" title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{::project.get('total_watchers')}} span {{::project.get('total_watchers')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('i_am_member')}" ng-class="{'active': project.get('i_am_member')}"
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}" title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
) )
svg.icon.icon-team tg-svg(svg-icon="icon-team")
use(xlink:href="#icon-team")
span.statistics-num {{ ::project.get('members').size }} span.statistics-num {{ ::project.get('members').size }}
p.project-description {{ ::project.get('description') | limitTo:150 }}{{ ::project.get('description').length < 150 ? '' : '...'}} p.project-description {{ ::project.get('description') | limitTo:150 }}{{ ::project.get('description').length < 150 ? '' : '...'}}

View File

@ -49,8 +49,8 @@
} }
} }
.title { .title {
@extend %bold; @include font-type(bold);
@extend %larger; @include font-size(larger);
color: $grayer; color: $grayer;
display: inline-block; display: inline-block;
margin: 0; margin: 0;
@ -85,7 +85,7 @@
margin: 1rem auto; margin: 1rem auto;
} }
span { span {
@extend %light; @include font-type(light);
color: $gray; color: $gray;
display: block; display: block;
} }
@ -122,7 +122,7 @@
} }
} }
li { li {
@extend %small; @include font-size(small);
color: $white; color: $white;
cursor: pointer; cursor: pointer;
min-width: 8rem; min-width: 8rem;
@ -161,8 +161,8 @@
justify-content: space-between; justify-content: space-between;
} }
.project-title { .project-title {
@extend %large; @include font-size(large);
@extend %text; @include font-type(text);
display: inline-block; display: inline-block;
margin-bottom: .5rem; margin-bottom: .5rem;
a { a {
@ -172,13 +172,8 @@
} }
} }
} }
.look-for-people {
@include svg-size();
fill: $gray-light;
margin-left: .5rem;
}
.project-description { .project-description {
@extend %small; @include font-size(small);
color: $gray; color: $gray;
margin-bottom: 0; margin-bottom: 0;
} }
@ -191,12 +186,9 @@
fill: $gray-light; fill: $gray-light;
margin-right: .25rem; margin-right: .25rem;
} }
.svg-eye-closed {
display: none;
}
} }
.statistic { .statistic {
@extend %small; @include font-size(small);
color: $gray-light; color: $gray-light;
display: inline-block; display: inline-block;
margin-right: .5rem; margin-right: .5rem;

View File

@ -1,8 +1,7 @@
.most-active(ng-if="vm.highlighted.size") .most-active(ng-if="vm.highlighted.size")
.header .header
.title-wrapper .title-wrapper
svg.icon.icon-activity tg-svg(svg-icon="icon-activity")
use(xlink:href="#icon-activity")
h1.title {{ 'DISCOVER.MOST_ACTIVE' | translate }} h1.title {{ 'DISCOVER.MOST_ACTIVE' | translate }}
tg-discover-home-order-by(on-change="vm.orderBy(orderBy)", order-by="vm.currentOrderBy") tg-discover-home-order-by(on-change="vm.orderBy(orderBy)", order-by="vm.currentOrderBy")
@ -15,6 +14,5 @@
.empty-highlighted-project( .empty-highlighted-project(
ng-if="!vm.highlighted.size" ng-if="!vm.highlighted.size"
) )
svg.icon.icon-activity tg-svg(svg-icon="icon-activity")
use(xlink:href="#icon-activity")
span {{ 'DISCOVER.MOST_ACTIVE_EMPTY' | translate }} span {{ 'DISCOVER.MOST_ACTIVE_EMPTY' | translate }}

View File

@ -1,10 +1,12 @@
.most-liked(ng-if="vm.highlighted.size") .most-liked(ng-if="vm.highlighted.size")
.header .header
.title-wrapper .title-wrapper
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
h1.title {{ 'DISCOVER.MOST_LIKED' | translate }} h1.title {{ 'DISCOVER.MOST_LIKED' | translate }}
tg-discover-home-order-by(on-change="vm.orderBy(orderBy)", order-by="vm.currentOrderBy") tg-discover-home-order-by(
on-change="vm.orderBy(orderBy)"
order-by="vm.currentOrderBy"
)
tg-highlighted( tg-highlighted(
loading="vm.loading", loading="vm.loading",
highlighted="vm.highlighted" highlighted="vm.highlighted"
@ -14,6 +16,5 @@
.empty-highlighted-project( .empty-highlighted-project(
ng-if="!vm.highlighted.size" ng-if="!vm.highlighted.size"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{ 'DISCOVER.MOST_LIKED_EMPTY' | translate }} span {{ 'DISCOVER.MOST_LIKED_EMPTY' | translate }}

View File

@ -43,9 +43,11 @@ div(tg-discover-search)
tg-nav="project:project=project.get('slug')" tg-nav="project:project=project.get('slug')"
title="{{ ::project.get('name') }}" title="{{ ::project.get('name') }}"
) {{project.get('name')}} ) {{project.get('name')}}
svg.look-for-people.icon.icon-recruit(ng-if="project.get('is_looking_for_people')") tg-svg.look-for-people(
use(xlink:href="#icon-recruit") ng-if="project.get('is_looking_for_people')"
title="{{ ::project.get('looking_for_people_note') }}" svg-icon="icon-recruit"
svg-title="{{ ::project.get('looking_for_people_note') }}"
)
p {{ ::project.get('description') | limitTo:300 }} p {{ ::project.get('description') | limitTo:300 }}
span(ng-if="::project.get('description').length > 300") ... span(ng-if="::project.get('description').length > 300") ...
.list-itemtype-project-right.project-statistics .list-itemtype-project-right.project-statistics
@ -53,22 +55,19 @@ div(tg-discover-search)
ng-class="{'active': project.get('is_fan')}" ng-class="{'active': project.get('is_fan')}"
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}" title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{::project.get('total_fans')}} span {{::project.get('total_fans')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('is_watcher')}" ng-class="{'active': project.get('is_watcher')}"
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}" title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{::project.get('total_watchers')}} span {{::project.get('total_watchers')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('i_am_member')}" ng-class="{'active': project.get('i_am_member')}"
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}" title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
) )
svg.icon.icon-team tg-svg(svg-icon="icon-team")
use(xlink:href="#icon-team")
span.statistics-num {{ ::project.get('members').size }} span.statistics-num {{ ::project.get('members').size }}
a.button-green.more-results( a.button-green.more-results(

View File

@ -71,10 +71,6 @@
flex: 1; flex: 1;
vertical-align: middle; vertical-align: middle;
} }
.look-for-people {
fill: $gray-light;
margin-left: .5rem;
}
.project-statistics { .project-statistics {
display: flex; display: flex;
flex-basis: 300px; flex-basis: 300px;
@ -84,12 +80,9 @@
fill: $gray-light; fill: $gray-light;
margin-right: .2rem; margin-right: .2rem;
} }
.svg-eye-closed {
display: none;
}
} }
.statistic { .statistic {
@extend %small; @include font-size(small);
color: $gray-light; color: $gray-light;
display: inline-block; display: inline-block;
margin-right: .5rem; margin-right: .5rem;
@ -121,8 +114,8 @@
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.title { .title {
@extend %large; @include font-size(large);
@extend %light; @include font-type(light);
margin: 0; margin: 0;
text-transform: uppercase; text-transform: uppercase;
} }

View File

@ -26,10 +26,10 @@
margin: 0; margin: 0;
} }
h3 { h3 {
@extend %large; @include font-size(large);
} }
a { a {
@extend %xsmall; @include font-size(x-small);
display: block; display: block;
} }
} }
@ -47,7 +47,7 @@
} }
p { p {
@extend %xsmall; @include font-size(x-small);
} }
} }
.user-card { .user-card {
@ -67,7 +67,7 @@
display: block; display: block;
} }
.cancel { .cancel {
@extend %small; @include font-size(small);
display: block; display: block;
margin-top: .5rem; margin-top: .5rem;
text-align: left; text-align: left;

View File

@ -16,18 +16,21 @@ a.list-itemtype-ticket(
div.list-itemtype-ticket-data div.list-itemtype-ticket-data
p p
span.ticket-project {{ ::vm.duty.get('projectName')}} span.ticket-project {{ ::vm.duty.get('projectName')}}
span.ticket-type {{ ::vm.getDutyType() }} span.ticket-type {{ ::vm.getDutyType() }}
span.ticket-status(ng-style="{'color': vm.duty.get('status_extra_info').get('color')}") {{ ::vm.duty.get('status_extra_info').get('name') }} span.ticket-status(ng-style="{'color': vm.duty.get('status_extra_info').get('color')}") {{ ::vm.duty.get('status_extra_info').get('name') }}
svg.icon.icon-blocked-project(ng-if="vm.duty.get('blockedProject')")
use(xlink:href="#icon-blocked-project") tg-svg(
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED") ng-if="vm.duty.get('blockedProject')",
svg-icon="icon-blocked-project",
svg-title-translate="PROJECT.BLOCKED_PROJECT.BLOCKED"
)
h2 h2
span.ticket-id(tg-bo-ref="duty.get('ref')") span.ticket-id(tg-bo-ref="duty.get('ref')")
span.ticket-title span.ticket-title
span.ticket-blocked( span.ticket-blocked(
ng-if="::vm.duty.get('is_blocked')" ng-if="::vm.duty.get('is_blocked')"
title="{{::vm.duty.get('blocked_note')}}" title="{{::vm.duty.get('blocked_note')}}"
) {{ 'COMMON.BLOCKED' | translate }} ) {{ 'COMMON.BLOCKED' | translate }}
span {{ ::duty.get('subject') }} span {{ ::duty.get('subject') }}

View File

@ -11,8 +11,8 @@
display: block; display: block;
} }
.title-bar { .title-bar {
@extend %light; @include font-type(light);
@extend %larger; @include font-size(larger);
align-content: center; align-content: center;
background: $whitish; background: $whitish;
display: flex; display: flex;

View File

@ -11,7 +11,10 @@ section.home-project-list(ng-if="vm.projects.size")
title="{{tag.get('name')}}" title="{{tag.get('name')}}"
tg-repeat="tag in project.get('colorized_tags') track by tag.get('name')" tg-repeat="tag in project.get('colorized_tags') track by tag.get('name')"
) )
.project-card-inner(href="#", tg-nav="project:project=project.get('slug')") .project-card-inner(
href="#"
tg-nav="project:project=project.get('slug')"
)
.project-card-header .project-card-header
a.project-card-logo( a.project-card-logo(
href="#" href="#"
@ -22,19 +25,31 @@ section.home-project-list(ng-if="vm.projects.size")
tg-project-logo-small-src="::project" tg-project-logo-small-src="::project"
alt="{{::project.get('name')}}" alt="{{::project.get('name')}}"
) )
h2.project-card-name h3.project-card-name
a.project-title( a.project-title(
href="#" href="#"
tg-nav="project:project=project.get('slug')" tg-nav="project:project=project.get('slug')"
title="{{::project.get('name')}}" title="{{::project.get('name')}}"
) {{::project.get('name')}} ) {{::project.get('name')}}
svg.look-for-people.icon.icon-recruit(ng-if="project.get('is_looking_for_people')")
use(xlink:href="#icon-recruit") tg-svg.look-for-people(
title="{{ ::project.get('looking_for_people_note') }}" ng-if="project.get('is_looking_for_people')"
svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')") svg-icon="icon-recruit"
use(xlink:href="#icon-blocked-project") svg-title="{{ ::project.get('looking_for_people_note') }}"
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED") )
tg-svg.owner-badge(
ng-if="project.get('i_am_owner')"
svg-icon="icon-badge"
svg-title="COMMON.OWNER"
)
tg-svg(
ng-if="project.get('blocked_code')"
svg-icon="icon-blocked-project"
svg-title-translate="PROJECT.BLOCKED_PROJECT.BLOCKED"
)
p.project-card-description {{::project.get('description')| limitTo:100 }} p.project-card-description {{::project.get('description')| limitTo:100 }}
span(ng-if="::project.get('description').length > 100") ... span(ng-if="::project.get('description').length > 100") ...
.project-card-statistics .project-card-statistics
@ -42,29 +57,25 @@ section.home-project-list(ng-if="vm.projects.size")
ng-class="{'active': project.get('is_fan')}" ng-class="{'active': project.get('is_fan')}"
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}" title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{::project.get('total_fans')}} span {{::project.get('total_fans')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('is_watcher')}" ng-class="{'active': project.get('is_watcher')}"
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}" title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{::project.get('total_watchers')}} span {{::project.get('total_watchers')}}
span.statistic( span.statistic(
ng-class="{'active': project.get('i_am_member')}" ng-class="{'active': project.get('i_am_member')}"
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}" title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
) )
svg.icon.icon-team tg-svg(svg-icon="icon-team")
use(xlink:href="#icon-team")
span.statistics-num {{ ::project.get('members').size }} span.statistics-num {{ ::project.get('members').size }}
span.statistic( span.statistic(
ng-if="::project.get('is_private')" ng-if="::project.get('is_private')"
title="{{ 'PROJECT.PRIVATE' | translate }}" title="{{ 'PROJECT.PRIVATE' | translate }}"
) )
svg.icon.icon-lock tg-svg(svg-icon="icon-lock")
use(xlink:href="#icon-lock")
a.see-more-projects-btn.button-gray( a.see-more-projects-btn.button-gray(
href="#", href="#",
@ -75,14 +86,18 @@ section.home-project-list(ng-if="vm.projects.size")
) )
section.projects-empty(ng-if="vm.projects != undefined && vm.projects.size === 0") section.projects-empty(ng-if="vm.projects != undefined && vm.projects.size === 0")
svg.icon.icon-project tg-svg(svg-icon="icon-project")
use(xlink:href="#icon-project")
p(translate="HOME.EMPTY_PROJECT_LIST") p(translate="HOME.EMPTY_PROJECT_LIST")
a.create-project-button.button-green(href="#", ng-click="vm.newProject()", a.create-project-button.button-green(
title="{{'PROJECT.NAVIGATION.TITLE_CREATE_PROJECT' | translate}}", href="#"
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT") ng-click="vm.newProject()"
title="{{'PROJECT.NAVIGATION.TITLE_CREATE_PROJECT' | translate}}"
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT"
)
span(tg-import-project-button) span(tg-import-project-button)
a.import-project-button.button-blackish(href="#", a.import-project-button.button-blackish(
title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}", href="#"
translate="PROJECT.NAVIGATION.ACTION_IMPORT_PROJECT") title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}"
translate="PROJECT.NAVIGATION.ACTION_IMPORT_PROJECT"
)
input.import-file.hidden(type="file") input.import-file.hidden(type="file")

View File

@ -18,7 +18,6 @@
.tags-container, .tags-container,
.project-card-logo, .project-card-logo,
.project-card-name a, .project-card-name a,
.icon-recruit,
.project-card-description, .project-card-description,
.project-card-statistics { .project-card-statistics {
opacity: .3; opacity: .3;
@ -36,8 +35,8 @@
width: 100%; width: 100%;
} }
p { p {
@extend %small; @include font-size(small);
@extend %light; @include font-type(light);
} }
.create-project-button { .create-project-button {
display: block; display: block;

View File

@ -2,7 +2,7 @@
.watching-empty { .watching-empty {
margin-bottom: 4rem; margin-bottom: 4rem;
p { p {
@extend %light; @include font-type(light);
margin: 2rem 9rem 1rem; margin: 2rem 9rem 1rem;
text-align: center; text-align: center;
} }

View File

@ -1,11 +1,9 @@
h1
span.green {{"HOME.DASHBOARD" | translate}}
section.working-on-container section.working-on-container
header header
h1 h1.title-bar.working-on-title(translate="HOME.WORKING_ON_SECTION")
span.green {{"HOME.DASHBOARD" | translate}}
.title-bar.working-on-title(translate="HOME.WORKING_ON_SECTION")
.working-on(ng-if="vm.assignedTo.size") .working-on(ng-if="vm.assignedTo.size")
.duty-single( .duty-single(
@ -17,7 +15,8 @@ section.working-on-container
include empty.jade include empty.jade
section.watching-container section.watching-container
.title-bar.watching-title(translate="HOME.WATCHING_SECTION") header
h1.title-bar.watching-title(translate="HOME.WATCHING_SECTION")
.watching(ng-if="vm.watching.size") .watching(ng-if="vm.watching.size")
.duty-single( .duty-single(

View File

@ -1,6 +1,9 @@
a(href="", title="Projects", tg-nav="projects") a(
svg.icon.icon-project href=""
use(xlink:href="#icon-project") title="Projects"
tg-nav="projects"
)
tg-svg(svg-icon="icon-project")
div.navbar-dropdown.dropdown-project-list div.navbar-dropdown.dropdown-project-list
ul ul
@ -11,9 +14,11 @@ div.navbar-dropdown.dropdown-project-list
ng-class="{'blocked-project': project.get('blocked_code')}" ng-class="{'blocked-project': project.get('blocked_code')}"
) )
span {{::project.get("name")}} span {{::project.get("name")}}
svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')") tg-svg(
use(xlink:href="#icon-blocked-project") svg-icon="icon-blocked-project"
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED") ng-if="project.get('blocked_code')"
svg-title="PROJECT.BLOCKED_PROJECT.BLOCKED"
)
a.see-more-projects-btn.button-gray( a.see-more-projects-btn.button-gray(
href="#", href="#",
@ -33,6 +38,5 @@ div.navbar-dropdown.dropdown-project-list
href="" href=""
title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}" title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}"
) )
svg.icon.icon-upload tg-svg(svg-icon="icon-upload")
use(xlink:href="#icon-upload") input.import-file.hidden(type="file")
input.import-file.hidden(type="file")

View File

@ -30,8 +30,6 @@ div.navbar-dropdown.dropdown-user
ng-class="{active: plugin.slug == currentPlugin.slug}" ng-class="{active: plugin.slug == currentPlugin.slug}"
) )
span.title {{ plugin.name }} span.title {{ plugin.name }}
span.new(translate="PROJECT.NAVIGATION.NEW_ITEM")
li li
a( a(
href="#", href="#",
@ -54,7 +52,7 @@ div.navbar-dropdown.dropdown-user
translate="PROJECT.NAVIGATION.FEEDBACK") translate="PROJECT.NAVIGATION.FEEDBACK")
li li
a( a(
href="https://taiga.io/support/", href="https://tree.taiga.io/support/",
target="_blank", target="_blank",
title="{{'PROJECT.NAVIGATION.HELP_TITLE' | translate}}", title="{{'PROJECT.NAVIGATION.HELP_TITLE' | translate}}",
translate="PROJECT.NAVIGATION.HELP") translate="PROJECT.NAVIGATION.HELP")

View File

@ -16,7 +16,7 @@ nav.navbar(ng-if="vm.isEnabledHeader")
include ../../svg/logo.svg include ../../svg/logo.svg
a( a(
href="https://taiga.io/support/", href="https://tree.taiga.io/support/",
target="_blank", target="_blank",
title="{{'PROJECT.NAVIGATION.HELP_TITLE' | translate}}", title="{{'PROJECT.NAVIGATION.HELP_TITLE' | translate}}",
translate="PROJECT.NAVIGATION.HELP" translate="PROJECT.NAVIGATION.HELP"
@ -38,21 +38,19 @@ nav.navbar(ng-if="vm.isEnabledHeader")
) )
div.nav-right(ng-if="vm.isAuthenticated") div.nav-right(ng-if="vm.isAuthenticated")
a(tg-nav="home", a(
ng-class="{active: vm.active}", tg-nav="home"
title="{{'PROJECT.NAVIGATION.DASHBOARD_TITLE' | translate}}") ng-class="{active: vm.active}"
title="{{'PROJECT.NAVIGATION.DASHBOARD_TITLE' | translate}}"
svg.icon.icon-dashboard )
use(xlink:href="#icon-dashboard") tg-svg(svg-icon="icon-dashboard")
a( a(
href="#", href="#",
tg-nav="discover", tg-nav="discover",
title="{{'PROJECT.NAVIGATION.DISCOVER_TITLE' | translate}}", title="{{'PROJECT.NAVIGATION.DISCOVER_TITLE' | translate}}",
) )
svg.icon.icon-discover tg-svg(svg-icon="icon-discover")
use(xlink:href="#icon-discover")
div.topnav-dropdown-wrapper(ng-show="vm.projects.size", tg-dropdown-project-list) div.topnav-dropdown-wrapper(ng-show="vm.projects.size", tg-dropdown-project-list)
//- div.topnav-dropdown-wrapper(tg-dropdown-organization-list)
div.topnav-dropdown-wrapper(tg-dropdown-user) div.topnav-dropdown-wrapper(tg-dropdown-user)

View File

@ -136,7 +136,7 @@ $dropdown-width: 350px;
} }
} }
.new { .new {
@extend %small; @include font-size(small);
background: $red-light; background: $red-light;
float: right; float: right;
margin-left: auto; margin-left: auto;

View File

@ -4,8 +4,7 @@ section.profile-contacts
img(src="/#{v}/svg/spinner-circle.svg", alt="Loading...") img(src="/#{v}/svg/spinner-circle.svg", alt="Loading...")
div.empty-tab(ng-if="vm.contacts && !vm.contacts.size") div.empty-tab(ng-if="vm.contacts && !vm.contacts.size")
svg.icon.icon-unwatch tg-svg(svg-icon="icon-unwatch")
use(xlink:href="#icon-unwatch")
div(ng-if="!vm.isCurrentUser") div(ng-if="!vm.isCurrentUser")
p(translate="USER.PROFILE.CONTACTS_EMPTY", translate-values="{username: vm.user.get('full_name_display')}") p(translate="USER.PROFILE.CONTACTS_EMPTY", translate-values="{username: vm.user.get('full_name_display')}")

View File

@ -18,12 +18,18 @@
tg-nav="project:project=vm.item.get('slug')" tg-nav="project:project=vm.item.get('slug')"
title="{{ ::vm.item.get('name') }}" title="{{ ::vm.item.get('name') }}"
) {{ ::vm.item.get('name') }} ) {{ ::vm.item.get('name') }}
svg.icon.icon-lock.private(ng-if="::vm.item.get('project_is_private')")
use(xlink:href="#icon-lock") tg-svg(
title {{'PROJECT.PRIVATE' | translate}}" ng-if="::vm.item.get('is_private')"
svg.icon.icon-blocked-project(ng-if="vm.item.get('project_blocked_code')") svg-icon="icon-lock"
use(xlink:href="#icon-blocked-project") svg-title-translate="PROJECT.PRIVATE"
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED") )
tg-svg(
ng-if="vm.item.get('blocked_code')"
svg-icon="icon-blocked-project"
svg-title-translate="PROJECT.BLOCKED_PROJECT.BLOCKED"
)
p.list-itemtype-project-description {{ ::vm.item.get('description') }} p.list-itemtype-project-description {{ ::vm.item.get('description') }}
.list-itemtype-track .list-itemtype-track
@ -31,14 +37,12 @@
ng-class="{'active': vm.item.get('is_fan')}" ng-class="{'active': vm.item.get('is_fan')}"
title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_fans\")||0}:'messageformat' }}" title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_fans\")||0}:'messageformat' }}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{ ::vm.item.get('total_fans') }} span {{ ::vm.item.get('total_fans') }}
span.list-itemtype-track-watchers( span.list-itemtype-track-watchers(
ng-class="{'active': vm.item.get('is_watcher')}" ng-class="{'active': vm.item.get('is_watcher')}"
title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_watchers\")||0}:'messageformat' }}" title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_watchers\")||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{ ::vm.item.get('total_watchers') }} span {{ ::vm.item.get('total_watchers') }}

View File

@ -1,4 +1,4 @@
div.list-itemtype-ticket(ng-class="{'blocked-project': vm.item.get('project_blocked_code')}") .list-itemtype-ticket(ng-class="{'blocked-project': vm.item.get('project_blocked_code')}")
a.list-itemtype-avatar( a.list-itemtype-avatar(
href="" href=""
ng-if="::vm.item.get('assigned_to')" ng-if="::vm.item.get('assigned_to')"
@ -20,7 +20,7 @@ div.list-itemtype-ticket(ng-class="{'blocked-project': vm.item.get('project_bloc
alt="{{ 'COMMON.ASSIGNED_TO.NOT_ASSIGNED'|translate }}" alt="{{ 'COMMON.ASSIGNED_TO.NOT_ASSIGNED'|translate }}"
) )
div.list-itemtype-ticket-data .list-itemtype-ticket-data
p p
span.ticket-project span.ticket-project
| {{:: vm.item.get('project_name') }} | {{:: vm.item.get('project_name') }}
@ -36,11 +36,12 @@ div.list-itemtype-ticket(ng-class="{'blocked-project': vm.item.get('project_bloc
ng-if="::vm.item.get('type') === 'issue'" ng-if="::vm.item.get('type') === 'issue'"
translate="COMMON.ISSUE" translate="COMMON.ISSUE"
) )
span.ticket-status(ng-style="::{'color': vm.item.get('status_color')}") span.ticket-status(ng-style="::{'color': vm.item.get('status_color')}") {{:: vm.item.get('status') }}
| {{:: vm.item.get('status') }} tg-svg(
svg.icon.icon-blocked-project(ng-if="vm.item.get('project_blocked_code')") ng-if="vm.item.get('project_blocked_code')"
use(xlink:href="#icon-blocked-project") svg-icon="icon-blocked-project"
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED") svgTitleTranslate: "PROJECT.BLOCKED_PROJECT.BLOCKED"
)
h2 h2
span.ticket-id(tg-bo-ref="vm.item.get('ref')") span.ticket-id(tg-bo-ref="vm.item.get('ref')")
a.ticket-title( a.ticket-title(
@ -67,14 +68,12 @@ div.list-itemtype-ticket(ng-class="{'blocked-project': vm.item.get('project_bloc
ng-class="{'active': vm.item.get('is_voter')}", ng-class="{'active': vm.item.get('is_voter')}",
title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_voters\")||0}:'messageformat' }}" title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_voters\")||0}:'messageformat' }}"
) )
svg.icon.icon-upvote tg-svg(svg-icon="icon-upvote")
use(xlink:href="#icon-upvote")
span {{ ::vm.item.get('total_voters') }} span {{ ::vm.item.get('total_voters') }}
span.list-itemtype-track-watchers( span.list-itemtype-track-watchers(
ng-class="{'active': vm.item.get('is_watcher')}" ng-class="{'active': vm.item.get('is_watcher')}"
title="{{ 'COMMON.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_watchers\")||0}:'messageformat' }}" title="{{ 'COMMON.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_watchers\")||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{ ::vm.item.get('total_watchers') }} span {{ ::vm.item.get('total_watchers') }}

View File

@ -1,8 +1,7 @@
section.profile-favs section.profile-favs
div.profile-filter div.profile-filter
div.searchbox(ng-if="::vm.enableFilterByTextQuery") div.searchbox(ng-if="::vm.enableFilterByTextQuery")
svg.icon.icon-search tg-svg(svg-icon="icon-search")
use(xlink:href="#icon-search")
input( input(
type="text" type="text"
ng-model="vm.q" ng-model="vm.q"

View File

@ -20,10 +20,10 @@
class ProfileHints class ProfileHints
HINTS: [ HINTS: [
{ #hint1 { #hint1
url: "https://taiga.io/support/import-export-projects/" url: "https://tree.taiga.io/support/admin/import-export-projects/"
}, },
{ #hint2 { #hint2
url: "https://taiga.io/support/custom-fields/" url: "https://tree.taiga.io/support/admin/custom-fields/"
}, },
{ #hint3 { #hint3
}, },

View File

@ -1,6 +1,5 @@
h4 h4
svg.icon.icon-question tg-svg(svg-icon="icon-question")
use(xlink:href="#icon-question")
span(translate="HINTS.SECTION_NAME") span(translate="HINTS.SECTION_NAME")
p {{::vm.hint.title}} p {{::vm.hint.title}}

View File

@ -4,8 +4,7 @@ section.profile-projects
img(src="/#{v}/svg/spinner-circle.svg", alt="Loading...") img(src="/#{v}/svg/spinner-circle.svg", alt="Loading...")
.empty-tab(ng-if="vm.projects && !vm.projects.size") .empty-tab(ng-if="vm.projects && !vm.projects.size")
svg.icon.icon-unwatch tg-svg(svg-icon="icon-unwatch")
use(xlink:href="#icon-unwatch")
p( p(
translate="USER.PROFILE.PROJECTS_EMPTY" translate="USER.PROFILE.PROJECTS_EMPTY"
@ -33,9 +32,12 @@ section.profile-projects
tg-nav="project:project=project.get('slug')" tg-nav="project:project=project.get('slug')"
title="{{ ::project.get('name') }}" title="{{ ::project.get('name') }}"
) {{::project.get('name')}} ) {{::project.get('name')}}
svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
use(xlink:href="#icon-blocked-project") tg-svg(
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED") ng-if="project.get('blocked_code')",
svg-icon="icon-blocked-project"
svg-title-translate="PROJECT.BLOCKED_PROJECT.BLOCKED"
)
p.project-description {{ ::project.get('description') | limitTo:300 }} p.project-description {{ ::project.get('description') | limitTo:300 }}
.list-itemtype-project-right .list-itemtype-project-right
@ -45,16 +47,14 @@ section.profile-projects
ng-class="{'active': project.get('is_fan')}" ng-class="{'active': project.get('is_fan')}"
title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:project.get(\"total_fans\")||0}:'messageformat' }}" title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:project.get(\"total_fans\")||0}:'messageformat' }}"
) )
svg.icon.icon-like tg-svg(svg-icon="icon-like")
use(xlink:href="#icon-like")
span {{ ::project.get('total_fans') }} span {{ ::project.get('total_fans') }}
span.list-itemtype-track-watchers( span.list-itemtype-track-watchers(
ng-class="{'active': project.get('is_watcher')}" ng-class="{'active': project.get('is_watcher')}"
title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:project.get(\"total_watchers\")||0}:'messageformat' }}" title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:project.get(\"total_watchers\")||0}:'messageformat' }}"
) )
svg.icon.icon-watch tg-svg(svg-icon="icon-watch")
use(xlink:href="#icon-watch")
span {{ ::project.get('total_watchers') }} span {{ ::project.get('total_watchers') }}
.list-itemtype-project-members .list-itemtype-project-members

View File

@ -28,7 +28,6 @@ ProfileTabDirective = () ->
scope.tab.title = title scope.tab.title = title
scope.tab.icon = attrs.tabIcon scope.tab.icon = attrs.tabIcon
scope.tab.iconName = '#' + attrs.tabIcon
scope.tab.active = !!attrs.tabActive scope.tab.active = !!attrs.tabActive
if scope.$eval(attrs.tabDisabled) != true if scope.$eval(attrs.tabDisabled) != true

View File

@ -7,8 +7,7 @@ div
ng-click="vm.toggleTab(tab)" ng-click="vm.toggleTab(tab)"
ng-class="{active: tab.active}" ng-class="{active: tab.active}"
) )
svg.icon(ng-class="::tab.icon") tg-svg(svg-icon="{{::tab.icon}}")
use(xlink:href="{{::tab.iconName}}")
span {{::tab.name}} span {{::tab.name}}
ng-transclude ng-transclude

View File

@ -27,7 +27,7 @@
margin: 10% auto; margin: 10% auto;
width: 3rem; width: 3rem;
img { img {
@extend %loading-spinner; @include loading-spinner;
max-height: 3rem; max-height: 3rem;
max-width: 3rem; max-width: 3rem;
} }

View File

@ -22,8 +22,8 @@
width: 100%; width: 100%;
} }
.profile-edition { .profile-edition {
@extend %large; @include font-size(large);
@extend %light; @include font-type(light);
background: rgba($black, .4); background: rgba($black, .4);
bottom: 0; bottom: 0;
color: $white; color: $white;
@ -64,8 +64,8 @@
} }
} }
h1 { h1 {
@extend %bold; @include font-type(bold);
@extend %xlarge; @include font-size(xlarge);
line-height: 1.2; line-height: 1.2;
margin-bottom: .25rem; margin-bottom: .25rem;
text-transform: none; text-transform: none;
@ -75,15 +75,15 @@
word-wrap: break-word; word-wrap: break-word;
} }
h2 { h2 {
@extend %light; @include font-type(light);
@extend %larger; @include font-size(larger);
color: $gray; color: $gray;
line-height: 1.2; line-height: 1.2;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.username { .username {
@extend %light; @include font-type(light);
@extend %large; @include font-size(large);
color: $gray-light; color: $gray-light;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
@ -112,43 +112,20 @@
text-align: center; text-align: center;
} }
.stat-number { .stat-number {
@extend %xlarge; @include font-size(xlarge);
@extend %bold; @include font-type(bold);
display: block; display: block;
line-height: 1; line-height: 1;
} }
.stat-name { .stat-name {
@extend %title; @include font-type(text);
@extend %small; @include font-size(small);
display: block; display: block;
} }
} }
.profile-organizations {
border-bottom: 1px solid $whitish;
border-top: 1px solid $whitish;
margin-bottom: 1rem;
padding: 1rem 0;
h3 {
@extend %bold;
margin-bottom: .5rem;
}
.profile-organizations-wrapper {
display: flex;
justify-content: space-between;
}
.organization {
background: $gray-light;
border-radius: 5px;
height: 45px;
margin-right: .2rem;
width: 45px;
}
}
.profile-quote { .profile-quote {
@extend %light; @include font-type(light);
@extend %large; @include font-size(large);
background: url('../images/quote.png') no-repeat top left; background: url('../images/quote.png') no-repeat top left;
line-height: 1.4; line-height: 1.4;
padding: .5rem; padding: .5rem;

View File

@ -20,63 +20,3 @@
} }
} }
} }
.profile-contact-single {
border-bottom: 1px solid $whitish;
display: flex;
flex-wrap: wrap;
padding: .8rem 1rem;
.profile-contact-picture {
flex-grow: 0;
margin-right: 1rem;
max-width: 54px;
img {
border-radius: .2rem;
width: 100%;
}
}
.profile-contact-data {
flex: 1;
h1 {
@extend %text;
@extend %large;
align-items: center;
display: flex;
line-height: 1.6;
margin-bottom: 0;
text-transform: none;
span {
@extend %text;
@extend %small;
background: $whitish;
color: $gray;
margin-left: 1rem;
padding: .1rem .3rem;
}
}
p {
color: $gray;
margin-bottom: 0;
}
.extra-info {
@extend %light;
color: $gray;
}
.position {
margin-right: .3rem;
}
}
.profile-project-stats {
display: flex;
flex-grow: 0;
margin-left: auto;
width: 100px;
div {
color: $gray-light;
margin-right: .5rem;
.icon {
margin-right: .2rem;
vertical-align: center;
}
}
}
}

View File

@ -1,6 +1,6 @@
.profile-sidebar { .profile-sidebar {
h4 { h4 {
@extend %bold; @include font-type(bold);
background: $whitish; background: $whitish;
color: $gray; color: $gray;
margin-bottom: .5rem; margin-bottom: .5rem;
@ -13,7 +13,7 @@
} }
} }
p { p {
@extend %small; @include font-size(small);
color: $gray-light; color: $gray-light;
} }
a { a {

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