Merge branch 'master' into stable
commit
af069abae5
|
@ -21,6 +21,7 @@ answer newbie questions, and generally made Taiga that much better:
|
|||
- Brett Profitt <brett.profitt@gmail.com>
|
||||
- Chris Wilson <chris.wilson@aridhia.com>
|
||||
- Daniel Koch
|
||||
- Everardo Medina <everblut@gmail.com>
|
||||
- Florian Bezagu
|
||||
- Guilhem Got <guilhem.got@gmail.com>
|
||||
- Jordan Rinke
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
# 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)
|
||||
|
||||
### Features
|
||||
|
|
|
@ -601,6 +601,9 @@ i18nInit = (lang, $translate) ->
|
|||
# i18n - moment.js
|
||||
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
|
||||
messages = {
|
||||
defaultMessage: $translate.instant("COMMON.FORM_ERRORS.DEFAULT_MESSAGE")
|
||||
|
|
|
@ -240,7 +240,7 @@ module.directive("tgMemberships", ["$tgTemplate", "$compile", MembershipsDirecti
|
|||
## Member Avatar Directive
|
||||
#############################################################################
|
||||
|
||||
MembershipsRowAvatarDirective = ($log, $template, $translate) ->
|
||||
MembershipsRowAvatarDirective = ($log, $template, $translate, $compile) ->
|
||||
template = $template.get("admin/memberships-row-avatar.html", true)
|
||||
|
||||
link = ($scope, $el, $attrs) ->
|
||||
|
@ -255,6 +255,8 @@ MembershipsRowAvatarDirective = ($log, $template, $translate) ->
|
|||
}
|
||||
|
||||
html = template(ctx)
|
||||
html = $compile(html)($scope)
|
||||
|
||||
$el.html(html)
|
||||
|
||||
if not $attrs.tgMembershipsRowAvatar?
|
||||
|
@ -269,7 +271,7 @@ MembershipsRowAvatarDirective = ($log, $template, $translate) ->
|
|||
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>
|
||||
<a class="delete" href=""
|
||||
title="{{ 'ADMIN.MEMBERSHIP.DELETE_MEMBER' | translate }}">
|
||||
<svg class="icon icon-trash">
|
||||
<use xlink:href="#icon-trash">
|
||||
</svg>
|
||||
<tg-svg svg-icon="icon-trash"></tg-svg>
|
||||
</a>
|
||||
"""
|
||||
|
||||
|
@ -406,9 +406,7 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
|
|||
</a>
|
||||
<a class="delete" href=""
|
||||
title="{{ 'ADMIN.MEMBERSHIP.DELETE_MEMBER' | translate }}">
|
||||
<svg class="icon icon-trash">
|
||||
<use xlink:href="#icon-trash">
|
||||
</svg>
|
||||
<tg-svg svg-icon="icon-trash"></tg-svg>
|
||||
</a>
|
||||
"""
|
||||
|
||||
|
|
|
@ -228,7 +228,7 @@ ProjectModulesDirective = ($repo, $confirm, $loading, projectService) ->
|
|||
event.preventDefault()
|
||||
submit()
|
||||
|
||||
$el.on "click", ".icon-save", (event) ->
|
||||
$el.on "click", ".save", (event) ->
|
||||
event.preventDefault()
|
||||
submit()
|
||||
|
||||
|
|
|
@ -137,22 +137,31 @@ ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame, $tra
|
|||
itemEl = null
|
||||
tdom = $el.find(".sortable")
|
||||
|
||||
tdom.sortable({
|
||||
handle: ".row.table-main.visualization",
|
||||
dropOnEmpty: true
|
||||
connectWith: ".project-values-body"
|
||||
revert: 400
|
||||
axis: "y"
|
||||
drake = dragula([tdom[0]], {
|
||||
direction: 'vertical',
|
||||
copySortSource: false,
|
||||
copy: false,
|
||||
mirrorContainer: tdom[0],
|
||||
moves: (item) -> return $(item).is('div[tg-bind-scope]')
|
||||
})
|
||||
|
||||
tdom.on "sortstop", (event, ui) ->
|
||||
itemEl = ui.item
|
||||
drake.on 'dragend', (item) ->
|
||||
itemEl = $(item)
|
||||
itemValue = itemEl.scope().value
|
||||
itemIndex = itemEl.index()
|
||||
$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", ->
|
||||
$el.off()
|
||||
drake.destroy()
|
||||
|
||||
## Value Link
|
||||
|
||||
|
@ -441,7 +450,7 @@ class ProjectCustomAttributesController extends mixOf(taiga.Controller, taiga.Pa
|
|||
loadCustomAttributes: =>
|
||||
return @rs.customAttributes[@scope.type].list(@scope.projectId).then (customAttributes) =>
|
||||
@scope.customAttributes = customAttributes
|
||||
@scope.maxOrder = _.maxBy(customAttributes, "order").order
|
||||
@scope.maxOrder = _.maxBy(customAttributes, "order")?.order
|
||||
return customAttributes
|
||||
|
||||
createCustomAttribute: (attrValues) =>
|
||||
|
@ -483,16 +492,16 @@ ProjectCustomAttributesDirective = ($log, $confirm, animationFrame, $translate)
|
|||
# Drag & Drop
|
||||
##################################
|
||||
sortableEl = $el.find(".js-sortable")
|
||||
|
||||
sortableEl.sortable({
|
||||
handle: ".js-view-custom-field",
|
||||
dropOnEmpty: true
|
||||
revert: 400
|
||||
axis: "y"
|
||||
drake = dragula([sortableEl[0]], {
|
||||
direction: 'vertical',
|
||||
copySortSource: false,
|
||||
copy: false,
|
||||
mirrorContainer: sortableEl[0],
|
||||
moves: (item) -> return $(item).is('div[tg-bind-scope]')
|
||||
})
|
||||
|
||||
sortableEl.on "sortstop", (event, ui) ->
|
||||
itemEl = ui.item
|
||||
drake.on 'dragend', (item) ->
|
||||
itemEl = $(item)
|
||||
itemAttr = itemEl.scope().attr
|
||||
itemIndex = itemEl.index()
|
||||
$ctrl.moveCustomAttributes(itemAttr, itemIndex)
|
||||
|
|
|
@ -162,8 +162,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
|
|||
subtitle = @translate.instant("ADMIN.ROLES.DISABLE_COMPUTABLE_ALERT_SUBTITLE", {
|
||||
roleName: @scope.role.name
|
||||
})
|
||||
message = @translate.instant("ADMIN.ROLES.DISABLE_COMPUTABLE_ALERT_MESSAGE")
|
||||
return @confirm.ask(title, subtitle, message).then askOnSuccess, askOnError
|
||||
return @confirm.ask(title, subtitle, "").then askOnSuccess, askOnError
|
||||
|
||||
toggleComputable: debounce 2000, ->
|
||||
if not @scope.role.computable
|
||||
|
@ -292,9 +291,7 @@ RolePermissionsDirective = ($rootscope, $repo, $confirm, $compile) ->
|
|||
title="{{ '<%- permission.name %>' | translate }}"></div>
|
||||
<% }) %>
|
||||
</div>
|
||||
<svg class="icon icon-arrow-right">
|
||||
<use xlink:href="#icon-arrow-right">
|
||||
</svg>
|
||||
<tg-svg svg-icon="icon-arrow-right"></tg-svg>
|
||||
""")
|
||||
|
||||
categoryTemplate = _.template("""
|
||||
|
|
|
@ -275,6 +275,13 @@ LoginDirective = ($auth, $confirm, $location, $config, $routeParams, $navUrls, $
|
|||
onError = (response) ->
|
||||
$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) =>
|
||||
event.preventDefault()
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ module = angular.module("taigaBacklog")
|
|||
## Issues Filters Directive
|
||||
#############################################################################
|
||||
|
||||
BacklogFiltersDirective = ($q, $log, $location, $templates) ->
|
||||
template = $templates.get("backlog/filters.html", true)
|
||||
templateSelected = $templates.get("backlog/filter-selected.html", true)
|
||||
BacklogFiltersDirective = ($q, $log, $location, $template, $compile) ->
|
||||
template = $template.get("backlog/filters.html", true)
|
||||
templateSelected = $template.get("backlog/filter-selected.html", true)
|
||||
|
||||
link = ($scope, $el, $attrs) ->
|
||||
currentFiltersType = ''
|
||||
|
@ -78,6 +78,8 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
|
|||
f.style = "border-left: 3px solid #{f.color}"
|
||||
|
||||
html = templateSelected({filters: selectedFilters})
|
||||
html = $compile(html)($scope)
|
||||
|
||||
$el.find(".filters-applied").html(html)
|
||||
|
||||
renderFilters = (filters) ->
|
||||
|
@ -86,6 +88,7 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
|
|||
f.style = "border-left: 3px solid #{f.color}"
|
||||
|
||||
html = template({filters:filters})
|
||||
html = $compile(html)($scope)
|
||||
$el.find(".filter-list").html(html)
|
||||
|
||||
getFiltersType = () ->
|
||||
|
@ -94,7 +97,7 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
|
|||
reloadUserstories = () ->
|
||||
currentFiltersType = getFiltersType()
|
||||
|
||||
$q.all([$ctrl.loadUserstories(), $ctrl.generateFilters()]).then () ->
|
||||
$q.all([$ctrl.loadUserstories(true), $ctrl.generateFilters()]).then () ->
|
||||
currentFilters = $scope.filters[currentFiltersType]
|
||||
renderFilters(_.reject(currentFilters, "selected"))
|
||||
|
||||
|
@ -158,9 +161,9 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
|
|||
event.preventDefault()
|
||||
showCategories()
|
||||
|
||||
$el.on "click", ".filters-applied a", (event) ->
|
||||
$el.on "click", ".remove-filter", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
target = angular.element(event.currentTarget).parent()
|
||||
id = target.data("id")
|
||||
type = target.data("type")
|
||||
toggleFilterSelection(type, id)
|
||||
|
@ -179,4 +182,4 @@ BacklogFiltersDirective = ($q, $log, $location, $templates) ->
|
|||
|
||||
return {link:link}
|
||||
|
||||
module.directive("tgBacklogFilters", ["$q", "$log", "$tgLocation", "$tgTemplate", BacklogFiltersDirective])
|
||||
module.directive("tgBacklogFilters", ["$q", "$log", "$tgLocation", "$tgTemplate", "$compile", BacklogFiltersDirective])
|
||||
|
|
|
@ -62,6 +62,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
@location, @appMetaService, @navUrls, @events, @analytics, @translate, @loading, @rs2) ->
|
||||
bindMethods(@)
|
||||
|
||||
@.page = 1
|
||||
@.disablePagination = false
|
||||
@scope.userstories = []
|
||||
|
||||
@scope.sectionName = @translate.instant("BACKLOG.SECTION_NAME")
|
||||
@showTags = false
|
||||
@activeFilters = false
|
||||
|
@ -90,7 +94,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
|
||||
initializeEventHandlers: ->
|
||||
@scope.$on "usform:bulk:success", =>
|
||||
@.loadUserstories()
|
||||
@.loadUserstories(true)
|
||||
@.loadProjectStats()
|
||||
@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)
|
||||
|
||||
@scope.$on "usform:new:success", =>
|
||||
@.loadUserstories()
|
||||
@.loadUserstories(true)
|
||||
@.loadProjectStats()
|
||||
|
||||
@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) =>
|
||||
@.loadSprints()
|
||||
@.loadProjectStats()
|
||||
@.loadUserstories()
|
||||
@.loadUserstories(true)
|
||||
|
||||
if sprint.closed
|
||||
@.loadClosedSprints()
|
||||
|
||||
@rootscope.$broadcast("filters:update")
|
||||
|
||||
@scope.$on "usform:edit:success", =>
|
||||
@.loadUserstories()
|
||||
@scope.$on "usform:edit:success", (event, data) =>
|
||||
index = _.findIndex @scope.userstories, (us) ->
|
||||
return us.id == data.id
|
||||
|
||||
@scope.userstories[index] = data
|
||||
|
||||
@rootscope.$broadcast("filters:update")
|
||||
|
||||
@scope.$on("sprint:us:move", @.moveUs)
|
||||
@scope.$on("sprint:us:moved", @.loadSprints)
|
||||
@scope.$on("sprint:us:moved", @.loadProjectStats)
|
||||
@scope.$on "sprint:us:moved", () =>
|
||||
@.loadSprints()
|
||||
@.loadProjectStats()
|
||||
|
||||
@scope.$on("backlog:load-closed-sprints", @.loadClosedSprints)
|
||||
@scope.$on("backlog:unload-closed-sprints", @.unloadClosedSprints)
|
||||
|
@ -248,18 +257,37 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
|
||||
@.loadUserstories()
|
||||
|
||||
loadUserstories: ->
|
||||
loadUserstories: (resetPagination = false)->
|
||||
@.loadingUserstories = true
|
||||
@.disablePagination = true
|
||||
@scope.httpParams = @.getUrlFilters()
|
||||
@rs.userstories.storeQueryParams(@scope.projectId, @scope.httpParams)
|
||||
|
||||
if resetPagination
|
||||
@.page = 1
|
||||
|
||||
@scope.httpParams.page = @.page
|
||||
|
||||
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
|
||||
@scope.userstories = _.sortBy(userstories, "backlog_order")
|
||||
@scope.userstories = @scope.userstories.concat(_.sortBy(userstories, "backlog_order"))
|
||||
|
||||
@.setSearchDataFilters()
|
||||
|
||||
@.loadingUserstories = false
|
||||
|
||||
if header('x-pagination-next')
|
||||
@.disablePagination = false
|
||||
@.page++
|
||||
|
||||
# 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
|
||||
scopeDefer @scope, =>
|
||||
|
@ -362,8 +390,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
# Persist in bulk all affected
|
||||
# userstories with order change
|
||||
@rs.userstories.bulkUpdateBacklogOrder(project, data).then =>
|
||||
for us in usList
|
||||
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||
@rootscope.$broadcast("sprint:us:moved")
|
||||
|
||||
# For sprint
|
||||
else
|
||||
|
@ -374,8 +401,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
# Persist in bulk all affected
|
||||
# userstories with order change
|
||||
@rs.userstories.bulkUpdateSprintOrder(project, data).then =>
|
||||
for us in usList
|
||||
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||
@rootscope.$broadcast("sprint:us:moved")
|
||||
|
||||
return promise
|
||||
|
||||
|
@ -402,7 +428,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
items = @.resortUserStories(@scope.userstories, "backlog_order")
|
||||
data = @.prepareBulkUpdateData(items, "backlog_order")
|
||||
return @rs.userstories.bulkUpdateBacklogOrder(us.project, data).then =>
|
||||
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||
@rootscope.$broadcast("sprint:us:moved")
|
||||
|
||||
if movedFromClosedSprint
|
||||
@rootscope.$broadcast("backlog:load-closed-sprints")
|
||||
|
@ -415,8 +441,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
# From backlog to sprint
|
||||
if oldSprintId == null
|
||||
us.milestone = newSprintId for us in usList
|
||||
|
||||
@scope.$apply =>
|
||||
args = [newUsIndex, 0].concat(usList)
|
||||
|
||||
# Add moving us to sprint user stories list
|
||||
|
@ -452,11 +476,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
|
|||
data = @.prepareBulkUpdateData(items, "sprint_order")
|
||||
|
||||
@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 =>
|
||||
for us in usList
|
||||
@rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId)
|
||||
@rootscope.$broadcast("sprint:us:moved")
|
||||
|
||||
if movedToClosedSprint || movedFromClosedSprint
|
||||
@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.then =>
|
||||
askResponse.finish()
|
||||
@.loadBacklog()
|
||||
|
||||
@q.all([
|
||||
@.loadProjectStats(),
|
||||
@.loadSprints()
|
||||
])
|
||||
promise.then null, =>
|
||||
askResponse.finish(false)
|
||||
@confirm.notify("error")
|
||||
|
@ -652,7 +679,7 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
|
|||
return _.map(rowElements, (x) -> angular.element(x))
|
||||
|
||||
$scope.$on("userstories:loaded", reloadDoomLine)
|
||||
$scope.$watch "stats", reloadDoomLine
|
||||
$scope.$watch("stats", reloadDoomLine)
|
||||
|
||||
## Move to current sprint link
|
||||
|
||||
|
@ -807,8 +834,6 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
|
|||
linkFilters($scope, $el, $attrs, $ctrl)
|
||||
linkDoomLine($scope, $el, $attrs, $ctrl)
|
||||
|
||||
$el.find(".backlog-table-body").disableSelection()
|
||||
|
||||
filters = $ctrl.getUrlFilters()
|
||||
if filters.status ||
|
||||
filters.tags ||
|
||||
|
@ -843,7 +868,7 @@ UsRolePointsSelectorDirective = ($rootscope, $template, $compile, $translate) ->
|
|||
if numberOfRoles > 1
|
||||
$el.append($compile(selectionTemplate({"roles": roles}))($scope))
|
||||
else
|
||||
$el.find(".icon-arrow-bottom").remove()
|
||||
$el.find(".icon-arrow-down").remove()
|
||||
$el.find(".header-points").addClass("not-clickable")
|
||||
|
||||
$scope.$on "uspoints:select", (ctx, roleId, roleName) ->
|
||||
|
|
|
@ -38,188 +38,118 @@ module = angular.module("taigaBacklog")
|
|||
#############################################################################
|
||||
|
||||
deleteElement = (el) ->
|
||||
el.scope().$destroy()
|
||||
el.off()
|
||||
el.remove()
|
||||
$(el).scope().$destroy()
|
||||
$(el).off()
|
||||
$(el).remove()
|
||||
|
||||
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) ->
|
||||
getUsIndex = (us) =>
|
||||
return $(us).index(".backlog-table-body .row")
|
||||
|
||||
bindOnce $scope, "project", (project) ->
|
||||
# If the user has not enough permissions we don't enable the sortable
|
||||
if not (project.my_permissions.indexOf("modify_us") > -1)
|
||||
return
|
||||
|
||||
initIsBacklog = false
|
||||
|
||||
filterError = ->
|
||||
text = $translate.instant("BACKLOG.SORTABLE_FILTER_ERROR")
|
||||
$tgConfirm.notify("error", text)
|
||||
|
||||
$el.sortable({
|
||||
items: ".us-item-row",
|
||||
cancel: ".popover"
|
||||
connectWith: ".sprint"
|
||||
dropOnEmpty: true
|
||||
placeholder: "row us-item-row us-item-drag sortable-placeholder"
|
||||
scroll: true
|
||||
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: () ->
|
||||
drake = dragula([$el[0], $('.empty-backlog')[0]], {
|
||||
copySortSource: false,
|
||||
copy: false,
|
||||
isContainer: (el) -> return el.classList.contains('sprint-table'),
|
||||
moves: (item) ->
|
||||
if !$(item).hasClass('row')
|
||||
return false
|
||||
|
||||
# it doesn't move is the filter is open
|
||||
parent = $(item).parent()
|
||||
initIsBacklog = parent.hasClass('backlog-table-body')
|
||||
|
||||
if initIsBacklog && $el.hasClass("active-filters")
|
||||
filterError()
|
||||
return false
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
drake.on 'drag', (item, container) ->
|
||||
parent = $(item).parent()
|
||||
initIsBacklog = parent.hasClass('backlog-table-body')
|
||||
|
||||
$(document.body).addClass("drag-active")
|
||||
stop: () ->
|
||||
|
||||
isChecked = $(item).find("input[type='checkbox']").is(":checked")
|
||||
|
||||
window.dragMultiple.start(item, container)
|
||||
|
||||
drake.on 'cloned', (item) ->
|
||||
$(item).addClass('backlog-us-mirror')
|
||||
|
||||
drake.on 'dragend', (item) ->
|
||||
$('.doom-line').remove()
|
||||
|
||||
parent = $(item).parent()
|
||||
isBacklog = parent.hasClass('backlog-table-body') || parent.hasClass('empty-backlog')
|
||||
|
||||
sameContainer = (initIsBacklog == isBacklog)
|
||||
|
||||
dragMultipleItems = window.dragMultiple.stop()
|
||||
|
||||
$(document.body).removeClass("drag-active")
|
||||
|
||||
if $el.hasClass("active-filters")
|
||||
$el.sortable("cancel")
|
||||
filterError()
|
||||
})
|
||||
items = $(item).parent().find('.row')
|
||||
|
||||
$el.on "multiplesortreceive", (event, ui) ->
|
||||
if $el.hasClass("active-filters")
|
||||
ui.source.sortable("cancel")
|
||||
filterError()
|
||||
sprint = null
|
||||
|
||||
return
|
||||
firstElement = if dragMultipleItems.length then dragMultipleItems[0] else item
|
||||
|
||||
itemUs = ui.item.scope().us
|
||||
itemIndex = getUsIndex(ui.item)
|
||||
if isBacklog
|
||||
index = $(firstElement).index(".backlog-table-body .row")
|
||||
else
|
||||
index = $(firstElement).index()
|
||||
sprint = parent.scope().sprint.id
|
||||
|
||||
deleteElement(ui.item)
|
||||
|
||||
$scope.$emit("sprint:us:move", [itemUs], itemIndex, null)
|
||||
ui.item.find('a').removeClass('noclick')
|
||||
|
||||
$el.on "multiplesortstop", (event, ui) ->
|
||||
# When parent not exists, do nothing
|
||||
if $(ui.items[0]).parent().length == 0
|
||||
return
|
||||
|
||||
if $el.hasClass("active-filters")
|
||||
return
|
||||
|
||||
items = _.sortBy ui.items, (item) ->
|
||||
return $(item).index()
|
||||
|
||||
index = _.min _.map items, (item) ->
|
||||
return getUsIndex(item)
|
||||
|
||||
us = _.map items, (item) ->
|
||||
item = $(item)
|
||||
itemUs = item.scope().us
|
||||
|
||||
# HACK: setTimeout prevents that firefox click
|
||||
# event fires just after drag ends
|
||||
setTimeout ( =>
|
||||
item.find('a').removeClass('noclick')
|
||||
), 300
|
||||
|
||||
return itemUs
|
||||
|
||||
$scope.$emit("sprint:us:move", us, index, null)
|
||||
|
||||
$el.on "sortstart", (event, ui) ->
|
||||
ui.item.find('a').addClass('noclick')
|
||||
|
||||
$scope.$on "$destroy", ->
|
||||
$el.off()
|
||||
|
||||
return {link: link}
|
||||
|
||||
BacklogEmptySortableDirective = ($repo, $rs, $rootscope) ->
|
||||
# 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 !sameContainer
|
||||
if dragMultipleItems.length
|
||||
usList = _.map dragMultipleItems, (item) ->
|
||||
return item = $(item).scope().us
|
||||
else
|
||||
usList = [$(item).scope().us]
|
||||
|
||||
if (dragMultipleItems.length)
|
||||
_.each dragMultipleItems, (item) ->
|
||||
deleteElement(item)
|
||||
else
|
||||
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
|
||||
|
||||
$scope.$emit("sprint:us:move", us, index, $scope.sprint.id)
|
||||
$scope.$emit("sprint:us:move", usList, index, sprint)
|
||||
|
||||
$el.on "multiplesortstop", (event, ui) ->
|
||||
# When parent not exists, do nothing
|
||||
if ui.item.parent().length == 0
|
||||
return
|
||||
scroll = autoScroll([window], {
|
||||
margin: 20,
|
||||
pixels: 30,
|
||||
scrollWhenOutside: true,
|
||||
autoScroll: () ->
|
||||
return this.down && drake.dragging;
|
||||
})
|
||||
|
||||
itemUs = ui.item.scope().us
|
||||
itemIndex = ui.item.index()
|
||||
|
||||
# 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')
|
||||
$scope.$on "$destroy", ->
|
||||
$el.off()
|
||||
drake.destroy()
|
||||
|
||||
return {link: link}
|
||||
|
||||
|
||||
module.directive("tgBacklogSortable", [
|
||||
"$tgRepo",
|
||||
"$tgResources",
|
||||
|
@ -228,17 +158,3 @@ module.directive("tgBacklogSortable", [
|
|||
"$translate",
|
||||
BacklogSortableDirective
|
||||
])
|
||||
|
||||
module.directive("tgBacklogEmptySortable", [
|
||||
"$tgRepo",
|
||||
"$tgResources",
|
||||
"$rootScope",
|
||||
BacklogEmptySortableDirective
|
||||
])
|
||||
|
||||
module.directive("tgSprintSortable", [
|
||||
"$tgRepo",
|
||||
"$tgResources",
|
||||
"$rootScope",
|
||||
SprintSortableDirective
|
||||
])
|
||||
|
|
|
@ -62,7 +62,7 @@ BacklogSprintDirective = ($repo, $rootscope) ->
|
|||
|
||||
$el.find(".sprint-table").slideToggle(slideOptions)
|
||||
|
||||
$el.on "click", ".sprint-name > .icon-edit", (event) ->
|
||||
$el.on "click", ".edit-sprint", (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
sprint = $scope.$eval($attrs.tgBacklogSprint)
|
||||
|
|
|
@ -284,39 +284,52 @@ module.factory("$tgTemplate", ["$templateCache", Template])
|
|||
## Permission directive, hide elements when necessary
|
||||
#############################################################################
|
||||
|
||||
Capslock = ($translate) ->
|
||||
link = ($scope, $el, $attrs) ->
|
||||
open = false
|
||||
Capslock = () ->
|
||||
template = """
|
||||
<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 = () ->
|
||||
$('.icon-capslock').fadeOut () ->
|
||||
open = false
|
||||
LightboxClose = () ->
|
||||
template = """
|
||||
<a class="close" href="" title="{{'COMMON.CLOSE' | translate}}">
|
||||
<tg-svg svg-icon="icon-close"></tg-svg>
|
||||
</a>
|
||||
"""
|
||||
|
||||
$(this).remove()
|
||||
return {
|
||||
template: template
|
||||
}
|
||||
|
||||
showIcon = (e) ->
|
||||
return if open
|
||||
element = e.currentTarget
|
||||
$(element).parent().append(warningIcon)
|
||||
$('.icon-capslock').fadeIn()
|
||||
module.directive("tgLightboxClose", [LightboxClose])
|
||||
|
||||
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) ->
|
||||
hideIcon()
|
||||
return {
|
||||
scope: {
|
||||
svgIcon: "@",
|
||||
svgTitle: "@",
|
||||
svgTitleTranslate: "@",
|
||||
svgTitleTranslateValues: "="
|
||||
},
|
||||
template: template
|
||||
}
|
||||
|
||||
$el.on 'keyup.capslock, focus', (e) ->
|
||||
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])
|
||||
module.directive("tgSvg", [Svg])
|
||||
|
|
|
@ -173,14 +173,17 @@ class ConfirmService extends taiga.Service
|
|||
if icon.type == "img"
|
||||
detailImage = $('<img>').addClass('lb-icon').attr('src', icon.name)
|
||||
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.setAttributeNS('http://www.w3.org/1999/xlink','href', '#' + icon.name)
|
||||
|
||||
detailImage = document.createElementNS("http://www.w3.org/2000/svg", "svg")
|
||||
detailImage.classList.add("icon")
|
||||
detailImage.classList.add("lb-icon")
|
||||
detailImage.classList.add(icon.name)
|
||||
detailImage.appendChild(useSVG)
|
||||
detailImage.appendChild(svgContainer).appendChild(useSVG)
|
||||
|
||||
if detailImage
|
||||
el.find('section').prepend(detailImage)
|
||||
|
|
|
@ -117,7 +117,7 @@ CustomAttributesValuesDirective = ($templates, $storage) ->
|
|||
$ctrl.initialize($attrs.type, value.id)
|
||||
$ctrl.loadCustomAttributesValues()
|
||||
|
||||
$el.on "click", ".custom-fields-header .icon", ->
|
||||
$el.on "click", ".custom-fields-header .collapse", ->
|
||||
hash = collapsedHash($attrs.type)
|
||||
collapsed = not($storage.get(hash) or false)
|
||||
$storage.set(hash, collapsed)
|
||||
|
|
|
@ -421,7 +421,7 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c
|
|||
|
||||
# Events
|
||||
|
||||
$el.on "click", ".add-comment button.button-green", debounce 2000, (event) ->
|
||||
$el.on "click", ".add-comment .button-green", debounce 2000, (event) ->
|
||||
event.preventDefault()
|
||||
|
||||
target = angular.element(event.currentTarget)
|
||||
|
@ -467,11 +467,11 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c
|
|||
$el.on "focus", ".add-comment textarea", (event) ->
|
||||
$(this).addClass('active')
|
||||
|
||||
$el.on "click", ".history-tabs li a", (event) ->
|
||||
$el.on "click", ".history-tabs a", (event) ->
|
||||
target = angular.element(event.currentTarget)
|
||||
|
||||
$el.find(".history-tabs li a").removeClass("active")
|
||||
target.addClass("active")
|
||||
$el.find(".history-tabs li").removeClass("active")
|
||||
target.parent().addClass("active")
|
||||
|
||||
$el.find(".history section").addClass("hidden")
|
||||
$el.find(".history section.#{target.data('section-class')}").removeClass("hidden")
|
||||
|
|
|
@ -51,7 +51,12 @@ class LightboxService extends taiga.Service
|
|||
@animationFrame.add ->
|
||||
$el.addClass("open")
|
||||
$el.one "transitionend", =>
|
||||
firstField = $el.find('input,textarea').first()
|
||||
|
||||
if firstField.length
|
||||
$el.find('input,textarea').first().focus()
|
||||
else if document.activeElement
|
||||
$(document.activeElement).blur()
|
||||
|
||||
@animationFrame.add =>
|
||||
lightboxContent.show()
|
||||
|
@ -79,7 +84,7 @@ class LightboxService extends taiga.Service
|
|||
|
||||
if $el.hasClass("remove-on-close")
|
||||
scope = $el.data("scope")
|
||||
scope.$destroy()
|
||||
scope.$destroy() if scope
|
||||
$el.remove()
|
||||
|
||||
closeAll: ->
|
||||
|
|
|
@ -158,6 +158,10 @@ RelatedTaskStatusDirective = ($repo, $template) ->
|
|||
$scope.$eval($attrs.onUpdate)
|
||||
$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) ->
|
||||
$el.append(selectionTemplate({ 'statuses': project.task_statuses }))
|
||||
updateTaskStatus($el, task, $scope.taskStatusById)
|
||||
|
|
|
@ -108,6 +108,8 @@ LbTagLineDirective = ($rs, $template, $compile) ->
|
|||
|
||||
templateTags = $template.get("common/tag/lb-tag-line-tags.html", true)
|
||||
|
||||
autocomplete = null
|
||||
|
||||
link = ($scope, $el, $attrs, $model) ->
|
||||
## Render
|
||||
renderTags = (tags, tagsColors) ->
|
||||
|
@ -130,7 +132,7 @@ LbTagLineDirective = ($rs, $template, $compile) ->
|
|||
|
||||
resetInput = ->
|
||||
$el.find("input").val("")
|
||||
$el.find("input").autocomplete("close")
|
||||
autocomplete.close()
|
||||
|
||||
## Aux methods
|
||||
addValue = (value) ->
|
||||
|
@ -190,22 +192,15 @@ LbTagLineDirective = ($rs, $template, $compile) ->
|
|||
deleteValue(value)
|
||||
|
||||
bindOnce $scope, "project", (project) ->
|
||||
positioningFunction = (position, elements) ->
|
||||
menu = elements.element.element
|
||||
menu.css("width", elements.target.width)
|
||||
menu.css("top", position.top)
|
||||
menu.css("left", position.left)
|
||||
input = $el.find("input")
|
||||
|
||||
$el.find("input").autocomplete({
|
||||
source: _.keys(project.tags_colors)
|
||||
position: {
|
||||
my: "left top",
|
||||
using: positioningFunction
|
||||
}
|
||||
select: (event, ui) ->
|
||||
addValue(ui.item.value)
|
||||
ui.item.value = ""
|
||||
})
|
||||
autocomplete = new Awesomplete(input[0], {
|
||||
list: _.keys(project.tags_colors)
|
||||
});
|
||||
|
||||
input.on "awesomplete-selectcomplete", () ->
|
||||
addValue(input.val())
|
||||
input.val("")
|
||||
|
||||
$scope.$watch $attrs.ngModel, (tags) ->
|
||||
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)
|
||||
|
||||
link = ($scope, $el, $attrs, $model) ->
|
||||
autocomplete = null
|
||||
|
||||
isEditable = ->
|
||||
if $attrs.requiredPerm?
|
||||
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()
|
||||
resetInput = ->
|
||||
$el.find("input").val("")
|
||||
$el.find("input").autocomplete("close")
|
||||
|
||||
autocomplete.close()
|
||||
|
||||
## Aux methods
|
||||
addValue = $qqueue.bindAdd (value) ->
|
||||
|
@ -366,22 +364,15 @@ TagLineDirective = ($rootScope, $repo, $rs, $confirm, $qqueue, $template, $compi
|
|||
|
||||
showAddTagButton()
|
||||
|
||||
positioningFunction = (position, elements) ->
|
||||
menu = elements.element.element
|
||||
menu.css("width", elements.target.width)
|
||||
menu.css("top", position.top)
|
||||
menu.css("left", position.left)
|
||||
input = $el.find("input")
|
||||
|
||||
$el.find("input").autocomplete({
|
||||
source: _.keys(tags_colors)
|
||||
position: {
|
||||
my: "left top",
|
||||
using: positioningFunction
|
||||
}
|
||||
select: (event, ui) ->
|
||||
addValue(ui.item.value)
|
||||
ui.item.value = ""
|
||||
})
|
||||
autocomplete = new Awesomplete(input[0], {
|
||||
list: _.keys(tags_colors)
|
||||
});
|
||||
|
||||
input.on "awesomplete-selectcomplete", () ->
|
||||
addValue(input.val())
|
||||
input.val("")
|
||||
|
||||
$scope.$watch $attrs.ngModel, (model) ->
|
||||
return if not model
|
||||
|
|
|
@ -584,20 +584,20 @@ IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $templat
|
|||
unwatchIssues()
|
||||
|
||||
# Dom Event Handlers
|
||||
$el.on "click", ".filters-cats > ul > li > a", (event) ->
|
||||
$el.on "click", ".filters-cat-single", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
tags = $scope.filters[target.data("type")]
|
||||
renderFilters(_.reject(tags, "selected"))
|
||||
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()
|
||||
showCategories($el)
|
||||
|
||||
$el.on "click", ".filters-applied a", (event) ->
|
||||
$el.on "click", ".filters-applied .remove-filter", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
target = angular.element(event.currentTarget).parent()
|
||||
|
||||
id = target.data("id") or null
|
||||
type = target.data("type")
|
||||
|
@ -617,7 +617,7 @@ IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $templat
|
|||
|
||||
toggleFilterSelection(type, id)
|
||||
|
||||
$el.on "click", ".filter-list .single-filter .remove-filter", (event) ->
|
||||
$el.on "click", ".filter-list .remove-filter", (event) ->
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ KanbanArchivedStatusHeaderDirective = ($rootscope, $translate) ->
|
|||
status = $scope.$eval($attrs.tgKanbanArchivedStatusHeader)
|
||||
hidden = true
|
||||
|
||||
$scope.class = "icon-open-eye"
|
||||
$scope.class = "icon-watch"
|
||||
$scope.title = showArchivedText
|
||||
|
||||
$el.on "click", (event) ->
|
||||
|
@ -337,12 +337,12 @@ KanbanArchivedStatusHeaderDirective = ($rootscope, $translate) ->
|
|||
|
||||
$scope.$apply ->
|
||||
if hidden
|
||||
$scope.class = "icon-open-eye"
|
||||
$scope.class = "icon-watch"
|
||||
$scope.title = showArchivedText
|
||||
$rootscope.$broadcast("kanban:hide-userstories-for-status", status.id)
|
||||
|
||||
else
|
||||
$scope.class = "icon-closed-eye"
|
||||
$scope.class = "icon-unwatch"
|
||||
$scope.title = hideArchivedText
|
||||
$rootscope.$broadcast("kanban:show-userstories-for-status", status.id)
|
||||
|
||||
|
@ -418,15 +418,13 @@ module.directive("tgKanbanArchivedStatusIntro", ["$translate", KanbanArchivedSta
|
|||
|
||||
KanbanUserstoryDirective = ($rootscope, $loading, $rs, $rs2) ->
|
||||
link = ($scope, $el, $attrs, $model) ->
|
||||
$el.disableSelection()
|
||||
|
||||
$scope.$watch "us", (us) ->
|
||||
if us.is_blocked and not $el.hasClass("blocked")
|
||||
$el.addClass("blocked")
|
||||
else if not us.is_blocked and $el.hasClass("blocked")
|
||||
$el.removeClass("blocked")
|
||||
|
||||
$el.on 'click', '.icon-edit', (event) ->
|
||||
$el.on 'click', '.edit-us', (event) ->
|
||||
if $el.find(".icon-edit").hasClass("noclick")
|
||||
return
|
||||
|
||||
|
@ -498,8 +496,6 @@ module.directive("tgKanbanSquishColumn", ["$tgResources", KanbanSquishColumnDire
|
|||
|
||||
KanbanWipLimitDirective = ->
|
||||
link = ($scope, $el, $attrs) ->
|
||||
$el.disableSelection()
|
||||
|
||||
status = $scope.$eval($attrs.tgKanbanWipLimit)
|
||||
|
||||
redrawWipLimit = =>
|
||||
|
|
|
@ -55,16 +55,23 @@ KanbanSortableDirective = ($repo, $rs, $rootscope) ->
|
|||
itemEl.off()
|
||||
itemEl.remove()
|
||||
|
||||
tdom.sortable({
|
||||
handle: ".kanban-task-inner"
|
||||
dropOnEmpty: true
|
||||
connectWith: ".kanban-uses-box"
|
||||
revert: 400
|
||||
containers = _.map $el.find('.task-column'), (item) ->
|
||||
return item
|
||||
|
||||
drake = dragula(containers, {
|
||||
copySortSource: false,
|
||||
copy: false,
|
||||
mirrorContainer: tdom[0],
|
||||
moves: (item) ->
|
||||
return $(item).hasClass('kanban-task')
|
||||
})
|
||||
|
||||
tdom.on "sortstop", (event, ui) ->
|
||||
parentEl = ui.item.parent()
|
||||
itemEl = ui.item
|
||||
drake.on 'drag', (item) ->
|
||||
oldParentScope = $(item).parent().scope()
|
||||
|
||||
drake.on 'dragend', (item) ->
|
||||
parentEl = $(item).parent()
|
||||
itemEl = $(item)
|
||||
itemUs = itemEl.scope().us
|
||||
itemIndex = itemEl.index()
|
||||
newParentScope = parentEl.scope()
|
||||
|
@ -78,14 +85,17 @@ KanbanSortableDirective = ($repo, $rs, $rootscope) ->
|
|||
$scope.$apply ->
|
||||
$rootscope.$broadcast("kanban:us:move", itemUs, itemUs.status, newStatusId, itemIndex)
|
||||
|
||||
ui.item.find('a').removeClass('noclick')
|
||||
|
||||
tdom.on "sortstart", (event, ui) ->
|
||||
oldParentScope = ui.item.parent().scope()
|
||||
ui.item.find('a').addClass('noclick')
|
||||
scroll = autoScroll(containers, {
|
||||
margin: 20,
|
||||
pixels: 30,
|
||||
scrollWhenOutside: true,
|
||||
autoScroll: () ->
|
||||
return this.down && drake.dragging;
|
||||
})
|
||||
|
||||
$scope.$on "$destroy", ->
|
||||
$el.off()
|
||||
drake.destroy()
|
||||
|
||||
return {link: link}
|
||||
|
||||
|
|
|
@ -35,10 +35,6 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
|
|||
$scope.templates = []
|
||||
currentLoading = null
|
||||
|
||||
$auth.refresh()
|
||||
$scope.canCreatePrivateProjects = currentUserService.canCreatePrivateProjects()
|
||||
$scope.canCreatePublicProjects = currentUserService.canCreatePublicProjects()
|
||||
|
||||
form = $el.find("form").checksley({"onlyOneErrorElement": true})
|
||||
|
||||
onSuccessSubmit = (response) ->
|
||||
|
@ -88,6 +84,9 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
|
|||
else
|
||||
$scope.data.creation_template = _.head(_.filter($scope.templates, (x) -> x.slug == "scrum")).id
|
||||
|
||||
$scope.canCreatePrivateProjects = currentUserService.canCreatePrivateProjects()
|
||||
$scope.canCreatePublicProjects = currentUserService.canCreatePublicProjects()
|
||||
|
||||
lightboxService.open($el)
|
||||
|
||||
submitButton = $el.find(".submit-button")
|
||||
|
@ -101,6 +100,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
|
|||
$scope.$on "$destroy", ->
|
||||
$el.off()
|
||||
|
||||
$auth.refresh().then () ->
|
||||
openLightbox()
|
||||
|
||||
directive = {
|
||||
|
|
|
@ -117,16 +117,14 @@ module.directive("tgRelatedTaskRow", ["$tgRepo", "$compile", "$tgConfirm", "$roo
|
|||
"$tgTemplate", "$translate", RelatedTaskRowDirective])
|
||||
|
||||
|
||||
RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $analytics, $template) ->
|
||||
template = $template.get("task/related-task-create-form.html", true)
|
||||
|
||||
RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $analytics) ->
|
||||
newTask = {
|
||||
subject: ""
|
||||
assigned_to: null
|
||||
}
|
||||
|
||||
link = ($scope, $el, $attrs) ->
|
||||
createTask = debounce 2000, (task) ->
|
||||
createTask = (task) ->
|
||||
task.subject = $el.find('input').val()
|
||||
task.assigned_to = $scope.newTask.assigned_to
|
||||
task.status = $scope.newTask.status
|
||||
|
@ -152,48 +150,53 @@ RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading,
|
|||
|
||||
close = () ->
|
||||
$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 = ->
|
||||
$scope.newRelatedTaskFormOpen = true
|
||||
|
||||
$el.html($compile(template())($scope))
|
||||
$el.find('input').focus().select()
|
||||
$el.addClass('active')
|
||||
$scope.openNewRelatedTask = true
|
||||
|
||||
$el.on "keyup", "input", (event)->
|
||||
if event.keyCode == 13
|
||||
createTask(newTask).then ->
|
||||
render()
|
||||
reset()
|
||||
$el.find('input').focus()
|
||||
|
||||
else if event.keyCode == 27
|
||||
$scope.$apply () -> close()
|
||||
|
||||
$el.on "click", ".icon-close", (event)->
|
||||
$scope.$apply () -> close()
|
||||
|
||||
$el.on "click", ".icon-save", (event)->
|
||||
$scope.save = () ->
|
||||
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("")
|
||||
taiga.bindOnce $scope, "us", reset
|
||||
|
||||
$scope.$on "related-tasks:show-form", ->
|
||||
render()
|
||||
$scope.$apply(render)
|
||||
|
||||
$scope.$on "$destroy", ->
|
||||
$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",
|
||||
"$tgAnalytics", "$tgTemplate", RelatedTaskCreateFormDirective])
|
||||
"$tgAnalytics", RelatedTaskCreateFormDirective])
|
||||
|
||||
|
||||
RelatedTaskCreateButtonDirective = ($repo, $compile, $confirm, $tgmodel, $template) ->
|
||||
|
@ -287,6 +290,10 @@ RelatedTaskAssignedToInlineEditionDirective = ($repo, $rootscope, $translate) ->
|
|||
notAutoSave = $scope.$eval($attrs.notAutoSave)
|
||||
autoSave = !notAutoSave
|
||||
|
||||
$scope.$watch $attrs.tgRelatedTaskAssignedToInlineEdition, () ->
|
||||
task = $scope.$eval($attrs.tgRelatedTaskAssignedToInlineEdition)
|
||||
updateRelatedTask(task)
|
||||
|
||||
updateRelatedTask(task)
|
||||
|
||||
$el.on "click", ".task-assignedto", (event) ->
|
||||
|
|
|
@ -51,7 +51,9 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
|
|||
params = {"project": projectId, "milestone": "null"}
|
||||
params = _.extend({}, params, filters or {})
|
||||
service.storeQueryParams(projectId, params)
|
||||
return $repo.queryMany("userstories", params)
|
||||
return $repo.queryMany("userstories", params, {
|
||||
enablePagination: true
|
||||
}, true)
|
||||
|
||||
service.listAll = (projectId, filters) ->
|
||||
params = {"project": projectId}
|
||||
|
|
|
@ -309,24 +309,22 @@ module.directive("tgTaskboard", ["$rootScope", TaskboardDirective])
|
|||
|
||||
TaskboardTaskDirective = ($rootscope, $loading, $rs, $rs2) ->
|
||||
link = ($scope, $el, $attrs, $model) ->
|
||||
$el.disableSelection()
|
||||
|
||||
$scope.$watch "task", (task) ->
|
||||
if task.is_blocked and not $el.hasClass("blocked")
|
||||
$el.addClass("blocked")
|
||||
else if not task.is_blocked and $el.hasClass("blocked")
|
||||
$el.removeClass("blocked")
|
||||
|
||||
$el.find(".icon-edit").on "click", (event) ->
|
||||
if $el.find('.icon-edit').hasClass('noclick')
|
||||
$el.find(".edit-task").on "click", (event) ->
|
||||
if $el.find('.edit-task').hasClass('noclick')
|
||||
return
|
||||
|
||||
$scope.$apply ->
|
||||
target = $(event.target)
|
||||
|
||||
currentLoading = $loading()
|
||||
.target(target)
|
||||
.timeout(200)
|
||||
.removeClasses("icon-edit")
|
||||
.start()
|
||||
|
||||
task = $scope.task
|
||||
|
|
|
@ -39,9 +39,9 @@ module = angular.module("taigaBacklog")
|
|||
|
||||
TaskboardSortableDirective = ($repo, $rs, $rootscope) ->
|
||||
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 not (project.my_permissions.indexOf("modify_us") > -1)
|
||||
if not ($scope.project.my_permissions.indexOf("modify_us") > -1)
|
||||
return
|
||||
|
||||
oldParentScope = null
|
||||
|
@ -55,16 +55,22 @@ TaskboardSortableDirective = ($repo, $rs, $rootscope) ->
|
|||
itemEl.off()
|
||||
itemEl.remove()
|
||||
|
||||
tdom.sortable({
|
||||
handle: ".taskboard-task-inner",
|
||||
dropOnEmpty: true
|
||||
connectWith: ".taskboard-tasks-box"
|
||||
revert: 400
|
||||
containers = _.map $el.find('.task-column'), (item) ->
|
||||
return item
|
||||
|
||||
drake = dragula(containers, {
|
||||
copySortSource: false,
|
||||
copy: false,
|
||||
mirrorContainer: $el[0],
|
||||
moves: (item) -> return $(item).hasClass('taskboard-task')
|
||||
})
|
||||
|
||||
tdom.on "sortstop", (event, ui) ->
|
||||
parentEl = ui.item.parent()
|
||||
itemEl = ui.item
|
||||
drake.on 'drag', (item) ->
|
||||
oldParentScope = $(item).parent().scope()
|
||||
|
||||
drake.on 'dragend', (item) ->
|
||||
parentEl = $(item).parent()
|
||||
itemEl = $(item)
|
||||
itemTask = itemEl.scope().task
|
||||
itemIndex = itemEl.index()
|
||||
newParentScope = parentEl.scope()
|
||||
|
@ -80,14 +86,17 @@ TaskboardSortableDirective = ($repo, $rs, $rootscope) ->
|
|||
$scope.$apply ->
|
||||
$rootscope.$broadcast("taskboard:task:move", itemTask, newUsId, newStatusId, itemIndex)
|
||||
|
||||
ui.item.find('a').removeClass('noclick')
|
||||
|
||||
tdom.on "sortstart", (event, ui) ->
|
||||
oldParentScope = ui.item.parent().scope()
|
||||
ui.item.find('a').addClass('noclick')
|
||||
scroll = autoScroll(containers, {
|
||||
margin: 20,
|
||||
pixels: 30,
|
||||
scrollWhenOutside: true,
|
||||
autoScroll: () ->
|
||||
return this.down && drake.dragging;
|
||||
})
|
||||
|
||||
$scope.$on "$destroy", ->
|
||||
$el.off()
|
||||
drake.destroy()
|
||||
|
||||
return {link: link}
|
||||
|
||||
|
|
|
@ -117,6 +117,13 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
|
|||
loadWikiLinks: ->
|
||||
return @rs.wiki.listLinks(@scope.projectId).then (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})
|
||||
@scope.wikiTitle = selectedWikiLink.title if selectedWikiLink?
|
||||
|
||||
|
@ -258,8 +265,9 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $
|
|||
currentLoading.finish()
|
||||
|
||||
$el.on "click", "a", (event) ->
|
||||
target = angular.element(event.target)
|
||||
target = angular.element(event.currentTarget)
|
||||
href = target.attr('href')
|
||||
|
||||
if href.indexOf("#") == 0
|
||||
event.preventDefault()
|
||||
$('body').scrollTop($(href).offset().top)
|
||||
|
|
|
@ -35,7 +35,8 @@ module = angular.module("taigaWiki")
|
|||
## 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)
|
||||
link = ($scope, $el, $attrs) ->
|
||||
$ctrl = $el.controller()
|
||||
|
@ -59,18 +60,6 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l
|
|||
$el.off()
|
||||
$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) ->
|
||||
event.preventDefault()
|
||||
$el.find(".new").removeClass("hidden")
|
||||
|
@ -146,5 +135,5 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l
|
|||
|
||||
return {link:link}
|
||||
|
||||
module.directive("tgWikiNav", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", "$tgNavUrls",
|
||||
"$tgAnalytics", "$tgLoading", "$tgTemplate", "$compile", "$translate", WikiNavDirective])
|
||||
module.directive("tgWikiNav", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", "$tgAnalytics",
|
||||
"$tgLoading", "$tgTemplate", "$compile", "$translate", WikiNavDirective])
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
# File: utils.coffee
|
||||
###
|
||||
|
||||
addClass = (el, className) ->
|
||||
if (el.classList)
|
||||
el.classList.add(className)
|
||||
else
|
||||
el.className += ' ' + className
|
||||
|
||||
nl2br = (str) =>
|
||||
breakTag = '<br />'
|
||||
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2')
|
||||
|
@ -222,6 +228,7 @@ patch = (oldImmutable, newImmutable) ->
|
|||
return pathObj
|
||||
|
||||
taiga = @.taiga
|
||||
taiga.addClass = addClass
|
||||
taiga.nl2br = nl2br
|
||||
taiga.bindMethods = bindMethods
|
||||
taiga.bindOnce = bindOnce
|
||||
|
|
|
@ -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;
|
||||
}());
|
|
@ -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;
|
||||
}());
|
|
@ -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
|
@ -1,11 +0,0 @@
|
|||
/*!
|
||||
* jQuery UI Touch Punch 0.2.3
|
||||
*
|
||||
* Copyright 2011–2014, 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);
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "Nota de bloqueig",
|
||||
"IS_BLOCKED": "està bloquejat",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Vots"
|
||||
"VOTES": "Vots",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Tot"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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",
|
||||
"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_PROJECT_LIST": "No tens cap projecte encara",
|
||||
"WORKING_ON_SECTION": "En Progrés",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"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",
|
||||
"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_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} membres amb aquest rol",
|
||||
"TITLE_DELETE_ROLE": "Esborrar rol",
|
||||
"REPLACEMENT_ROLE": "Tots els usuaris amb aquest rol es canviaran a",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Acceptar",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Esciu pàgina del Wiki",
|
||||
"REMOVE": "Esborrar pàgina de Wiki",
|
||||
"DELETE_LIGHTBOX_TITLE": "Esborrar pàgina de Wiki",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Enllaços",
|
||||
"ACTION_ADD_LINK": "Afegir link"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "Blockierungsgrund",
|
||||
"IS_BLOCKED": "wird blockiert",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Stimmen"
|
||||
"VOTES": "Stimmen",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Alle"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"PAGE_TITLE": "Home - Taiga",
|
||||
"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 sieht’s 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_PROJECT_LIST": "Sie haben noch keine Projekte",
|
||||
"WORKING_ON_SECTION": "Zuletzt bearbeitet",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"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.",
|
||||
"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_MESSAGE": "<strong>Bist du sicher, dass in dieser Rolle Estimatepoints deaktivieren möchtest?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} Mitglieder mit dieser Rolle",
|
||||
"TITLE_DELETE_ROLE": "Rolle löschen",
|
||||
"REPLACEMENT_ROLE": "Alle Benutzer mit dieser Rolle werden verschoben nach",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Akzeptieren",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Schreiben Sie Ihre Wiki Seite",
|
||||
"REMOVE": "Diese Wiki Seite entfernen",
|
||||
"DELETE_LIGHTBOX_TITLE": "Wiki Seite löschen",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Links",
|
||||
"ACTION_ADD_LINK": "Link hinzufügen"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "blocked note",
|
||||
"IS_BLOCKED": "is blocked",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Votes"
|
||||
"VOTES": "Votes",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "All"
|
||||
|
@ -224,6 +225,7 @@
|
|||
"CODE_BLOCK_SAMPLE_TEXT": "Your text here...",
|
||||
"PREVIEW_BUTTON": "Preview",
|
||||
"EDIT_BUTTON": "Edit",
|
||||
"ATTACH_FILE_HELP": "Attach files by dragging & dropping on the textarea above.",
|
||||
"MARKDOWN_HELP": "Markdown syntax help"
|
||||
},
|
||||
"PERMISIONS_CATEGORIES": {
|
||||
|
@ -355,7 +357,7 @@
|
|||
"HOME": {
|
||||
"PAGE_TITLE": "Home - Taiga",
|
||||
"PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues",
|
||||
"EMPTY_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_PROJECT_LIST": "You don't have any projects yet",
|
||||
"WORKING_ON_SECTION": "Working on",
|
||||
|
@ -556,9 +558,8 @@
|
|||
"PAGE_TITLE": "Roles - {{projectName}}",
|
||||
"WARNING_NO_ROLE": "Be careful, no role in your project will be able to estimate the point value for user stories",
|
||||
"HELP_ROLE_ENABLED": "When enabled, members assigned to this role will be able to estimate the point value for user stories",
|
||||
"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_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} members with this role",
|
||||
"TITLE_DELETE_ROLE": "Delete Role",
|
||||
"REPLACEMENT_ROLE": "All the users with this role will be moved to",
|
||||
|
@ -699,7 +700,6 @@
|
|||
"ACCEPT": "Accept",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1413,7 @@
|
|||
"PLACEHOLDER_PAGE": "Write your wiki page",
|
||||
"REMOVE": "Remove this wiki page",
|
||||
"DELETE_LIGHTBOX_TITLE": "Delete Wiki Page",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Links",
|
||||
"ACTION_ADD_LINK": "Add link"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "Motivo del bloqueo",
|
||||
"IS_BLOCKED": "está bloqueada",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Votos"
|
||||
"VOTES": "Votos",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Todos"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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.",
|
||||
"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_PROJECT_LIST": "Todavía no tienes ningún proyecto",
|
||||
"WORKING_ON_SECTION": "Trabajando en",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "Roles - {{projectName}}",
|
||||
"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",
|
||||
"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_MESSAGE": "<strong>¿Seguro de que deseas deshabilitar las estimaciones para este rol?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} miembros con este rol",
|
||||
"TITLE_DELETE_ROLE": "Borrar Rol",
|
||||
"REPLACEMENT_ROLE": "Todos los usuarios con este rol serán movidos a",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Aceptar",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Escribe el contenido de tu página",
|
||||
"REMOVE": "Eliminar esta página del wiki",
|
||||
"DELETE_LIGHTBOX_TITLE": "Eliminar Página del Wiki",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Enlaces",
|
||||
"ACTION_ADD_LINK": "Añadir enlace"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "estetty muistiinpano",
|
||||
"IS_BLOCKED": "on estetty",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Ääniä"
|
||||
"VOTES": "Ääniä",
|
||||
"SPRINT": "Kierros"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Kaikki"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"PAGE_TITLE": "Home - Taiga",
|
||||
"PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues",
|
||||
"EMPTY_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_PROJECT_LIST": "You don't have any projects yet",
|
||||
"WORKING_ON_SECTION": "Working on",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "Roles - {{projectName}}",
|
||||
"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",
|
||||
"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_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} jäsentä joilla tämä rooli",
|
||||
"TITLE_DELETE_ROLE": "Poista rooli",
|
||||
"REPLACEMENT_ROLE": "Kaikki käyttäjä joilla on tämä rooli siirretään",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Hyväksy",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Kirjoita wiki-sivu",
|
||||
"REMOVE": "Poista tämä wiki-sivu",
|
||||
"DELETE_LIGHTBOX_TITLE": "Poista wiki-sivu",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Linkit",
|
||||
"ACTION_ADD_LINK": "Lisää linkki"
|
||||
|
|
|
@ -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",
|
||||
"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",
|
||||
"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": {
|
||||
"DEFAULT_MESSAGE": "Cette valeur semble être invalide.",
|
||||
"TYPE_EMAIL": "Cette valeur devrait être une adresse courriel valide.",
|
||||
|
@ -67,8 +67,8 @@
|
|||
"MAX_CHECK": "Vous devez sélectionner %s options ou moins.",
|
||||
"RANGE_CHECK": "Vous devez sélectionner parmi les choix %s et %s.",
|
||||
"EQUAL_TO": "Cette valeur doit être identique.",
|
||||
"LINEWIDTH": "One or more lines is perhaps too long. Try to keep under %s characters.",
|
||||
"PIKADAY": "Invalid date format, please use DD MMM YYYY (like 23 Mar 1984)"
|
||||
"LINEWIDTH": "Une ou plusieurs lignes est peut-être trop long. Essayez de rester en dessous de %s caractères.",
|
||||
"PIKADAY": "Format de date non valide, merci d'utiliser JJ MMM AAAA (comme 23 mar 1984)"
|
||||
},
|
||||
"PICKERDATE": {
|
||||
"FORMAT": "DD MMM YYYY",
|
||||
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "note bloquée",
|
||||
"IS_BLOCKED": "est bloqué",
|
||||
"REF": "Réf.",
|
||||
"VOTES": "Votes"
|
||||
"VOTES": "Votes",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Tout"
|
||||
|
@ -283,7 +284,7 @@
|
|||
},
|
||||
"LOGIN_COMMON": {
|
||||
"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é ?",
|
||||
"TITLE_LINK_FORGOT_PASSWORD": "Avez-vous oublié votre mot de passe ?",
|
||||
"ACTION_ENTER": "Entrer",
|
||||
|
@ -318,8 +319,8 @@
|
|||
"PLACEHOLDER_FIELD": "Nom d'utilisateur ou adresse courriel",
|
||||
"ACTION_RESET_PASSWORD": "Réinitialiser le mot de passe",
|
||||
"LINK_CANCEL": "Nan, ramenez-moi en arrière. Je crois que je m'en souviens.",
|
||||
"SUCCESS_TITLE": "Check your inbox!",
|
||||
"SUCCESS_TEXT": "We sent you an email with the instructions to set a new password",
|
||||
"SUCCESS_TITLE": "Consultez votre boîte aux lettres !",
|
||||
"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é."
|
||||
},
|
||||
"CHANGE_PASSWORD": {
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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.",
|
||||
"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_PROJECT_LIST": "Vous n'avez aucun projet pour l'instant",
|
||||
"WORKING_ON_SECTION": "Projets en cours",
|
||||
|
@ -434,9 +435,9 @@
|
|||
"BACKLOG": "Backlog",
|
||||
"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_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_HELP": "0 for an undetermined number",
|
||||
"NUMBER_US_POINTS_HELP": "0 pour un nombre indéterminé",
|
||||
"KANBAN": "Kanban",
|
||||
"KANBAN_DESCRIPTION": "Organisez votre projet de manière agile avec ce tableau.",
|
||||
"ISSUES": "Tickets",
|
||||
|
@ -474,15 +475,15 @@
|
|||
"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_MEMBERS": "The project exceeds your maximum number of members for public projects",
|
||||
"PROJECT_OWNER": "Project owner",
|
||||
"REQUEST_OWNERSHIP": "Request ownership",
|
||||
"REQUEST_OWNERSHIP_CONFIRMATION_TITLE": "Do you want to become the new project owner?",
|
||||
"REQUEST_OWNERSHIP_DESC": "Request that current project owner {{name}} transfer ownership of this project to you.",
|
||||
"PROJECT_OWNER": "Propriétaire du projet",
|
||||
"REQUEST_OWNERSHIP": "Demander la propriété",
|
||||
"REQUEST_OWNERSHIP_CONFIRMATION_TITLE": "Voulez-vous devenir le nouveau propriétaire du projet ?",
|
||||
"REQUEST_OWNERSHIP_DESC": "Demander que le propriétaire actuel du projet {{name}} vous transfert la propriété.",
|
||||
"REQUEST_OWNERSHIP_BUTTON": "Requête",
|
||||
"REQUEST_OWNERSHIP_SUCCESS": "We'll notify the project owner",
|
||||
"CHANGE_OWNER": "Change owner",
|
||||
"CHANGE_OWNER_SUCCESS_TITLE": "Ok, your request has been sent!",
|
||||
"CHANGE_OWNER_SUCCESS_DESC": "We will notify you by email if the project ownership request is accepted or declined"
|
||||
"REQUEST_OWNERSHIP_SUCCESS": "Nous allons prévenir le propriétaire du projet",
|
||||
"CHANGE_OWNER": "Changer le propriétaire",
|
||||
"CHANGE_OWNER_SUCCESS_TITLE": "Ok, votre demande a été envoyée !",
|
||||
"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": {
|
||||
"TITLE": "Rapports",
|
||||
|
@ -556,13 +557,12 @@
|
|||
"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",
|
||||
"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_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",
|
||||
"TITLE_DELETE_ROLE": "Supprimer des rôles",
|
||||
"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",
|
||||
"EXTERNAL_USER": "Utilisateur externe"
|
||||
},
|
||||
|
@ -692,21 +692,20 @@
|
|||
"TITLE": "Services"
|
||||
},
|
||||
"PROJECT_TRANSFER": {
|
||||
"DO_YOU_ACCEPT_PROJECT_OWNERNSHIP": "Would you like to become the new project owner?",
|
||||
"PRIVATE": "Private",
|
||||
"ACCEPTED_PROJECT_OWNERNSHIP": "Congratulations! You're now the new project owner.",
|
||||
"REJECTED_PROJECT_OWNERNSHIP": "OK. We'll contact the current project owner",
|
||||
"DO_YOU_ACCEPT_PROJECT_OWNERNSHIP": "Voudriez-vous devenir le nouveau propriétaire du projet ?",
|
||||
"PRIVATE": "Privé",
|
||||
"ACCEPTED_PROJECT_OWNERNSHIP": "Félicitations ! Vous êtes maintenant le nouveau propriétaire du projet.",
|
||||
"REJECTED_PROJECT_OWNERNSHIP": "OK. Nous allons contacter le propriétaire actuel du projet",
|
||||
"ACCEPT": "Accepter",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"REJECT": "Rejeter",
|
||||
"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": "Voulez-vous ajouter un commentaire pour le propriétaire du projet ?",
|
||||
"UNLIMITED_PROJECTS": "Illimité",
|
||||
"OWNER_MESSAGE": {
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
|
@ -771,7 +770,7 @@
|
|||
"BLOCKED_PROJECT": {
|
||||
"BLOCKED": "Projet bloqué",
|
||||
"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": {
|
||||
"PROJECT": "points<br/> projet",
|
||||
|
@ -890,7 +889,7 @@
|
|||
"NEWSLETTER_LABEL_TEXT": "Je ne veux plus recevoir votre bulletin d'information",
|
||||
"CANCEL": "Retour aux réglages",
|
||||
"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! :("
|
||||
},
|
||||
"DELETE_PROJECT": {
|
||||
|
@ -952,20 +951,20 @@
|
|||
"LIMIT_USERS_WARNING_MESSAGE": "Unfortunately, this project can't have more than <strong>{{maxMembers}}</strong> members."
|
||||
},
|
||||
"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": {
|
||||
"DESC": "You are the current owner of this project. Before leaving, please transfer ownership to someone else.",
|
||||
"BUTTON": "Change the project owner"
|
||||
"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": "Changer le propriétaire du projet"
|
||||
},
|
||||
"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.",
|
||||
"BUTTON": "Request project owner change"
|
||||
"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": "Demander le changement de propriétaire du projet"
|
||||
}
|
||||
},
|
||||
"CHANGE_OWNER": {
|
||||
"TITLE": "Who do you want to be the new project owner?",
|
||||
"ADD_COMMENT": "Add comment",
|
||||
"BUTTON": "Ask this project member to become the new project owner"
|
||||
"TITLE": "Qui voulez-vous désigner comme le nouveau propriétaire du projet ?",
|
||||
"ADD_COMMENT": "Ajouter un commentaire",
|
||||
"BUTTON": "Demander à ce membre du projet de devenir le nouveau propriétaire"
|
||||
}
|
||||
},
|
||||
"US": {
|
||||
|
@ -1395,7 +1394,7 @@
|
|||
"WIZARD": {
|
||||
"SECTION_TITLE_CREATE_PROJECT": "Créer un projet",
|
||||
"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_INFO": "Plus d'informations",
|
||||
"PROJECT_DETAILS": "Détails du projet",
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Ecrivez votre page wiki",
|
||||
"REMOVE": "Supprimer cette page wiki",
|
||||
"DELETE_LIGHTBOX_TITLE": "Supprimer la page Wiki",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Liens",
|
||||
"ACTION_ADD_LINK": "Ajouter un lien"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "nota bloccata",
|
||||
"IS_BLOCKED": "è bloccato",
|
||||
"REF": "Riferimento",
|
||||
"VOTES": "Voti"
|
||||
"VOTES": "Voti",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Tutti"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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. ",
|
||||
"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_PROJECT_LIST": "Per ora non hai nessun progetto",
|
||||
"WORKING_ON_SECTION": "Sta lavorando su",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "Ruoli - {{projectName}}",
|
||||
"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",
|
||||
"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_MESSAGE": "<strong>sei sicuro di voler disabilitare la stime di questo ruolo?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} membri con questo ruolo",
|
||||
"TITLE_DELETE_ROLE": "Elimina ruolo",
|
||||
"REPLACEMENT_ROLE": "Tutti gli utenti con questo ruolo saranno spostati a ",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Accetta",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Crea la tua pagina wiki",
|
||||
"REMOVE": "Rimuovi questa pagina wiki",
|
||||
"DELETE_LIGHTBOX_TITLE": "Elimina Pagina Wiki",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Link",
|
||||
"ACTION_ADD_LINK": "Aggiungi link"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "geblokkeerde notitie",
|
||||
"IS_BLOCKED": "is geblokkeerd",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Stemmen"
|
||||
"VOTES": "Stemmen",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Alles"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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",
|
||||
"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_PROJECT_LIST": "Je hebt nog geen projecten",
|
||||
"WORKING_ON_SECTION": "Werkt aan",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "Rollen - {{projectName}}",
|
||||
"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",
|
||||
"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_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} leden met deze rol",
|
||||
"TITLE_DELETE_ROLE": "Verwijder Rol",
|
||||
"REPLACEMENT_ROLE": "Al de gebruikers met deze rol zullen verplaats worden naar",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Accepteren",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Schrijf je wiki pagina",
|
||||
"REMOVE": "Verwijder deze wiki pagina",
|
||||
"DELETE_LIGHTBOX_TITLE": "Verwijderd wiki pagina",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Links",
|
||||
"ACTION_ADD_LINK": "Link toevoegen"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "zablokowana notka",
|
||||
"IS_BLOCKED": "zablokowana",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Głosy"
|
||||
"VOTES": "Głosy",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Wszystko"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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.",
|
||||
"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_PROJECT_LIST": "Nie masz jeszcze żadnych projektów",
|
||||
"WORKING_ON_SECTION": "Pracujesz nad",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"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ć :)",
|
||||
"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_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",
|
||||
"TITLE_DELETE_ROLE": "Usuń rolę",
|
||||
"REPLACEMENT_ROLE": "Wszyscy użytkownicy pełniący tę rolę zostaną przeniesieni do",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Akceptuj",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Napisz swoje Wiki",
|
||||
"REMOVE": "Usuń tą stronę Wiki",
|
||||
"DELETE_LIGHTBOX_TITLE": "Usuń tą stronę Wiki",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Linki",
|
||||
"ACTION_ADD_LINK": "Dodaj link"
|
||||
|
|
|
@ -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!",
|
||||
"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",
|
||||
"OWNER": "Project Owner",
|
||||
"OWNER": "Dono do Projeto",
|
||||
"CAPSLOCK_WARNING": "Be careful! You are using capital letters in an input field that is case sensitive.",
|
||||
"FORM_ERRORS": {
|
||||
"DEFAULT_MESSAGE": "Este valor parece ser inválido.",
|
||||
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "Nota de bloqueio",
|
||||
"IS_BLOCKED": "está bloqueada",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Votos"
|
||||
"VOTES": "Votos",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Tudo"
|
||||
|
@ -318,8 +319,8 @@
|
|||
"PLACEHOLDER_FIELD": "Nome de usuário ou email",
|
||||
"ACTION_RESET_PASSWORD": "Resetar Senha",
|
||||
"LINK_CANCEL": "Nããão, me leve de volta. Acho que me lembrei.",
|
||||
"SUCCESS_TITLE": "Check your inbox!",
|
||||
"SUCCESS_TEXT": "We sent you an email with the instructions to set a new password",
|
||||
"SUCCESS_TITLE": "Verifique sua caixa de entrada!",
|
||||
"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."
|
||||
},
|
||||
"CHANGE_PASSWORD": {
|
||||
|
@ -355,8 +356,8 @@
|
|||
"HOME": {
|
||||
"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",
|
||||
"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_WATCHING": "<strong>Siga</strong> Estórias, Tarefas e Problemas nos seus projetos e seja notificado das mudanças :)",
|
||||
"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 Casos nos seus projetos e seja notificado das mudanças :)",
|
||||
"EMPTY_PROJECT_LIST": "Você ainda não tem projetos",
|
||||
"WORKING_ON_SECTION": "Trabalhando em",
|
||||
"WATCHING_SECTION": "Observando",
|
||||
|
@ -476,7 +477,7 @@
|
|||
"MAX_PUBLIC_PROJECTS_MEMBERS": "The project exceeds your maximum number of members for public projects",
|
||||
"PROJECT_OWNER": "Project owner",
|
||||
"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_BUTTON": "Solicitação",
|
||||
"REQUEST_OWNERSHIP_SUCCESS": "We'll notify the project owner",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"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",
|
||||
"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_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",
|
||||
"TITLE_DELETE_ROLE": "Apagar Função",
|
||||
"REPLACEMENT_ROLE": "Todos os usuários com essa função serão movidos para",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Aceitar",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -888,8 +887,8 @@
|
|||
"SECTION_NAME": "Apagar conta no Taiga",
|
||||
"CONFIRM": "Você tem certeza que quer apagar sua conta Taiga?",
|
||||
"NEWSLETTER_LABEL_TEXT": "Eu não quero receber mais os informativos",
|
||||
"CANCEL": "Back to settings",
|
||||
"ACCEPT": "Delete account",
|
||||
"CANCEL": "Voltar para configurações",
|
||||
"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.",
|
||||
"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_INFO": "More info",
|
||||
"PROJECT_DETAILS": "Project Details",
|
||||
"PUBLIC_PROJECT": "Public Project",
|
||||
"PRIVATE_PROJECT": "Private Project",
|
||||
"PUBLIC_PROJECT": "Projeto Público",
|
||||
"PRIVATE_PROJECT": "Projeto Privado",
|
||||
"CREATE_PROJECT": "Criar projeto",
|
||||
"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",
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Escreve sua página wiki",
|
||||
"REMOVE": "Remover essa página wiki",
|
||||
"DELETE_LIGHTBOX_TITLE": "Apagar página Wiki",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Links",
|
||||
"ACTION_ADD_LINK": "Adicionar link"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "Пояснение блокировки",
|
||||
"IS_BLOCKED": "заблокирован",
|
||||
"REF": "Ссылка",
|
||||
"VOTES": "Голоса"
|
||||
"VOTES": "Голоса",
|
||||
"SPRINT": "Спринт"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Все"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"PAGE_TITLE": "Домашняя страница - 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_PROJECT_LIST": "У Вас пока нет проектов",
|
||||
"WORKING_ON_SECTION": "Работает над",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "Роли - {{projectName}}",
|
||||
"WARNING_NO_ROLE": "Осторожнее: ни с какими ролями на вашем проекте участники не смогут оценить очки для пользовательских историй.",
|
||||
"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_MESSAGE": "<strong>Вы уверены, что хотите отключить оценку очков для этой роли?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} участников с этой ролью",
|
||||
"TITLE_DELETE_ROLE": "Удалить Роль",
|
||||
"REPLACEMENT_ROLE": "Все пользователи этой роли будут перемещены в",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Принимаю",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Создать вики страницу",
|
||||
"REMOVE": "Удалить эту вики страницу",
|
||||
"DELETE_LIGHTBOX_TITLE": "Удалить вики страницу",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Ссылки",
|
||||
"ACTION_ADD_LINK": "Добавить ссылку"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"ONE_ITEM_LINE": "En post per rad ...",
|
||||
"NEW_BULK": "Lägg till flera nya",
|
||||
"RELATED_TASKS": "Besläktade uppgifter",
|
||||
"LOGOUT": "Logg ut",
|
||||
"LOGOUT": "Logga ut",
|
||||
"EXTERNAL_USER": "en extern användare",
|
||||
"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!",
|
||||
|
@ -140,20 +140,21 @@
|
|||
"BLOCKED_NOTE": "blockerad notering",
|
||||
"IS_BLOCKED": "är blockerad",
|
||||
"REF": "Ref. ",
|
||||
"VOTES": "Röster"
|
||||
"VOTES": "Röster",
|
||||
"SPRINT": "Sprint"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Alla"
|
||||
},
|
||||
"ASSIGNED_TO": {
|
||||
"NOT_ASSIGNED": "Ej tilldelad",
|
||||
"ASSIGN": "Assign",
|
||||
"ASSIGN": "Tilldela",
|
||||
"DELETE_ASSIGNMENT": "Ta bort tilldelning",
|
||||
"REMOVE_ASSIGNED": "Ta bort tilldelning",
|
||||
"TOO_MANY": "... för många användare, fortsätter filtreringen",
|
||||
"CONFIRM_UNASSIGNED": "Vill du lämna det utan att tilldela det? ",
|
||||
"TITLE_ACTION_EDIT_ASSIGNMENT": "Redigera tilldelning",
|
||||
"SELF": "Assign to me"
|
||||
"SELF": "Tilldela mig"
|
||||
},
|
||||
"STATUS": {
|
||||
"CLOSED": "Stängd",
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"PAGE_TITLE": "Hem - Taiga",
|
||||
"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_PROJECT_LIST": "Du har inte än några projekt",
|
||||
"WORKING_ON_SECTION": "Arbetar med",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "Roller - {{projectName}}",
|
||||
"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",
|
||||
"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_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",
|
||||
"TITLE_DELETE_ROLE": "Ta bort rollen",
|
||||
"REPLACEMENT_ROLE": "Alla användarna med den här rollen vill flyttas till",
|
||||
|
@ -693,13 +693,12 @@
|
|||
},
|
||||
"PROJECT_TRANSFER": {
|
||||
"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.",
|
||||
"REJECTED_PROJECT_OWNERNSHIP": "OK. We'll contact the current project owner",
|
||||
"ACCEPT": "Acceptera",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -795,24 +794,24 @@
|
|||
"PLACEHOLDER_SEARCH": "Sök i ...",
|
||||
"ACTION_CREATE_PROJECT": "Skapa projekt",
|
||||
"ACTION_IMPORT_PROJECT": "Importerar projekt",
|
||||
"MANAGE_PROJECTS": "Manage projects",
|
||||
"MANAGE_PROJECTS": "Hantera projekt",
|
||||
"TITLE_CREATE_PROJECT": "Skapa projekt",
|
||||
"TITLE_IMPORT_PROJECT": "Importerar projekt",
|
||||
"TITLE_PRVIOUS_PROJECT": "Visa tidigare projekt",
|
||||
"TITLE_NEXT_PROJECT": "Visa nästa projekt",
|
||||
"HELP_TITLE": "Taiga hjälpsida",
|
||||
"HELP": "Hjälp",
|
||||
"HOMEPAGE": "Homepage",
|
||||
"HOMEPAGE": "Webbplats",
|
||||
"FEEDBACK_TITLE": "Skicka återkoppling",
|
||||
"FEEDBACK": "Återkokppling",
|
||||
"FEEDBACK": "Återkoppling",
|
||||
"NOTIFICATIONS_TITLE": "Ändra inställningar för dina notifieringar",
|
||||
"NOTIFICATIONS": "Notifieringar",
|
||||
"ORGANIZATIONS_TITLE": "Ändra dina organisationer",
|
||||
"ORGANIZATIONS": "Ändra organizationer",
|
||||
"SETTINGS_TITLE": "Ändra inställningarna",
|
||||
"SETTINGS": "Inställningar",
|
||||
"VIEW_PROFILE_TITLE": "Vis profil",
|
||||
"VIEW_PROFILE": "Vis profil",
|
||||
"VIEW_PROFILE_TITLE": "Visa profil",
|
||||
"VIEW_PROFILE": "Visa profil",
|
||||
"EDIT_PROFILE_TITLE": "Ändra din profil",
|
||||
"EDIT_PROFILE": "Ändra profil",
|
||||
"CHANGE_PASSWORD_TITLE": "Byt lösenord",
|
||||
|
@ -889,7 +888,7 @@
|
|||
"CONFIRM": "Är du säker på att du vill radera kontot?",
|
||||
"NEWSLETTER_LABEL_TEXT": "Jag vill inte motta flera nyhetsbrev",
|
||||
"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.",
|
||||
"SUBTITLE": "Sorry to see you go. We'll be here if you should ever consider us again! :("
|
||||
},
|
||||
|
@ -964,7 +963,7 @@
|
|||
},
|
||||
"CHANGE_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"
|
||||
}
|
||||
},
|
||||
|
@ -1368,7 +1367,7 @@
|
|||
"USER_PROFILE": "Användarprofil",
|
||||
"CHANGE_PASSWORD": "Ändra lösenord",
|
||||
"NOTIFICATIONS": "Notifieringar",
|
||||
"FEEDBACK": "Återkokppling",
|
||||
"FEEDBACK": "Återkoppling",
|
||||
"TITLE_AVATAR": "Inställningar för användare"
|
||||
}
|
||||
},
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Skriv din wiki-sida",
|
||||
"REMOVE": "Ta bort den här wiki-sidan",
|
||||
"DELETE_LIGHTBOX_TITLE": "Ta bort Wiki-sida",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Länkar",
|
||||
"ACTION_ADD_LINK": "Lägg till länk"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "engel notu",
|
||||
"IS_BLOCKED": "engellendi ",
|
||||
"REF": "Ref",
|
||||
"VOTES": "Oylar"
|
||||
"VOTES": "Oylar",
|
||||
"SPRINT": "Koşu"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "Hepsi"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"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",
|
||||
"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_PROJECT_LIST": "Henüz bir projeniz yok",
|
||||
"WORKING_ON_SECTION": "Üzerinde çalışılıyor",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"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.",
|
||||
"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_MESSAGE": "<strong>Bu role ait kestirimleri kapatmak istediğinizden emin misiniz?</strong>",
|
||||
"COUNT_MEMBERS": "bu roldeki üyelerin sayısı {{ role.members_count }} ",
|
||||
"TITLE_DELETE_ROLE": "Rol Sil",
|
||||
"REPLACEMENT_ROLE": "Bu role sahip kullanıcıların taşınacağı",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "Kabul et",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "Wiki sayfanı yaz ",
|
||||
"REMOVE": "Bu wiki sayfasını sil",
|
||||
"DELETE_LIGHTBOX_TITLE": "Wiki Sayfası Sil",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "Bağlantılar",
|
||||
"ACTION_ADD_LINK": "Bağlantı ekle"
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
"BLOCKED_NOTE": "已封鎖之筆記",
|
||||
"IS_BLOCKED": "封鎖",
|
||||
"REF": "Ref",
|
||||
"VOTES": "投票數"
|
||||
"VOTES": "投票數",
|
||||
"SPRINT": "衝刺任務"
|
||||
},
|
||||
"ROLES": {
|
||||
"ALL": "所有"
|
||||
|
@ -355,7 +356,7 @@
|
|||
"HOME": {
|
||||
"PAGE_TITLE": "首頁 - 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_PROJECT_LIST": "你尚無任何專案",
|
||||
"WORKING_ON_SECTION": "進行中",
|
||||
|
@ -556,9 +557,8 @@
|
|||
"PAGE_TITLE": "角色- {{projectName}}",
|
||||
"WARNING_NO_ROLE": "注意,你的專案中無角色可以評估使用者故事的點數",
|
||||
"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_MESSAGE": "<strong>Are you sure you want to disable this role estimations?</strong>",
|
||||
"COUNT_MEMBERS": "{{ role.members_count }} 這類角色的成員",
|
||||
"TITLE_DELETE_ROLE": "删除角色",
|
||||
"REPLACEMENT_ROLE": "和此角色有關的使用者都將遭移除 ",
|
||||
|
@ -699,7 +699,6 @@
|
|||
"ACCEPT": "接受",
|
||||
"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.",
|
||||
"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?",
|
||||
"UNLIMITED_PROJECTS": "Unlimited",
|
||||
"OWNER_MESSAGE": {
|
||||
|
@ -1413,6 +1412,7 @@
|
|||
"PLACEHOLDER_PAGE": "編寫你的維基頁",
|
||||
"REMOVE": "移除此維基頁 ",
|
||||
"DELETE_LIGHTBOX_TITLE": "刪除維基頁",
|
||||
"DELETE_LINK_TITLE": "Delete Wiki link",
|
||||
"NAVIGATION": {
|
||||
"SECTION_NAME": "連結",
|
||||
"ACTION_ADD_LINK": "新增連結"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
}
|
||||
}
|
||||
.attachment-name {
|
||||
@extend %light;
|
||||
@include font-type(light);
|
||||
@include ellipsis(175px);
|
||||
display: inline-block;
|
||||
}
|
||||
|
|
|
@ -51,10 +51,12 @@
|
|||
opacity: 0;
|
||||
}
|
||||
.editable-settings {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
svg {
|
||||
fill: $gray-light;
|
||||
pointer-events: none;
|
||||
}
|
||||
.icon-edit,
|
||||
.icon-save {
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
.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 {
|
||||
|
@ -10,8 +25,8 @@
|
|||
justify-content: space-between;
|
||||
min-height: 36px;
|
||||
.attachments-title {
|
||||
@extend %medium;
|
||||
@extend %bold;
|
||||
@include font-type(bold);
|
||||
@include font-size(medium);
|
||||
color: $grayer;
|
||||
line-height: 36px;
|
||||
padding: 0 1rem;
|
||||
|
@ -55,8 +70,8 @@
|
|||
}
|
||||
}
|
||||
.size-info {
|
||||
@extend %light;
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
@include font-type(light);
|
||||
color: $gray;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
@ -66,8 +81,8 @@
|
|||
}
|
||||
|
||||
.attachments-empty {
|
||||
@extend %large;
|
||||
@extend %bold;
|
||||
@include font-size(large);
|
||||
@include font-type(bold);
|
||||
border: 3px dashed $whitish;
|
||||
color: $gray-light;
|
||||
margin-top: .5rem;
|
||||
|
@ -76,19 +91,10 @@
|
|||
}
|
||||
|
||||
.single-attachment {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
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 {
|
||||
@extend %bold;
|
||||
@include font-type(bold);
|
||||
padding-right: 1rem;
|
||||
svg {
|
||||
fill: $gray;
|
||||
|
@ -103,7 +109,7 @@
|
|||
}
|
||||
|
||||
.more-attachments {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
border-bottom: 1px solid $gray-light;
|
||||
display: block;
|
||||
padding: 1rem 0 1rem 1rem;
|
||||
|
|
|
@ -34,5 +34,4 @@
|
|||
title="{{'COMMON.DELETE' | translate}}"
|
||||
ng-click="vm.delete()"
|
||||
)
|
||||
svg.icon.icon-trash
|
||||
use(xlink:href="#icon-trash")
|
||||
tg-svg(svg-icon="icon-trash")
|
||||
|
|
|
@ -12,8 +12,7 @@ form.single-attachment(
|
|||
target="_blank"
|
||||
download="{{::vm.attachment.getIn(['file', 'name'])}}"
|
||||
)
|
||||
svg.icon.icon-attachment
|
||||
use(xlink:href="#icon-attachment")
|
||||
tg-svg(svg-icon="icon-attachment")
|
||||
span {{::vm.attachment.getIn(['file', 'name'])}}
|
||||
|
||||
.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')")
|
||||
div(tg-loading="vm.attachment.get('loading')")
|
||||
a.editable-settings(
|
||||
a.editable-settings.e2e-save(
|
||||
href=""
|
||||
title="{{'COMMON.SAVE' | translate}}"
|
||||
ng-click="vm.save()"
|
||||
)
|
||||
svg.drag.icon.icon-save
|
||||
use(xlink:href="#icon-save")
|
||||
tg-svg(svg-icon="icon-save")
|
||||
|
||||
div
|
||||
a.editable-settings(
|
||||
a.editable-settings.e2e-cancel(
|
||||
href=""
|
||||
title="{{'COMMON.CANCEL' | translate}}"
|
||||
ng-click="vm.editMode(false)"
|
||||
)
|
||||
svg.drag.icon.icon-close
|
||||
use(xlink:href="#icon-close")
|
||||
tg-svg(svg-icon="icon-close")
|
||||
|
||||
.attachment-settings(
|
||||
ng-if="!vm.attachment.get('editable')"
|
||||
tg-check-permission="modify_{{vm.type}}"
|
||||
)
|
||||
a.settings(
|
||||
a.settings.e2e-edit(
|
||||
href=""
|
||||
title="{{'COMMON.EDIT' | translate}}"
|
||||
ng-click="vm.editMode(true)"
|
||||
)
|
||||
svg.drag.icon.icon-edit
|
||||
use(xlink:href="#icon-edit")
|
||||
a.settings(
|
||||
tg-svg.drag(svg-icon="icon-edit")
|
||||
a.settings.e2e-delete(
|
||||
href=""
|
||||
title="{{'COMMON.DELETE' | translate}}"
|
||||
ng-click="vm.delete()"
|
||||
)
|
||||
svg.drag.icon.icon-trash
|
||||
use(xlink:href="#icon-trash")
|
||||
tg-svg.drag(svg-icon="icon-trash")
|
||||
a.settings(
|
||||
href=""
|
||||
title="{{'COMMON.DRAG' | translate}}"
|
||||
)
|
||||
svg.drag.icon.icon-drag
|
||||
use(xlink:href="#icon-drag")
|
||||
tg-svg.drag(svg-icon="icon-drag")
|
||||
|
|
|
@ -11,24 +11,21 @@ section.attachments(
|
|||
ng-click="vm.setMode('gallery')"
|
||||
title="{{ 'ATTACHMENT.GALLERY_VIEW_MODE' | translate }}"
|
||||
)
|
||||
svg.icon.icon-gallery
|
||||
use(xlink:href="#icon-gallery")
|
||||
tg-svg(svg-icon="icon-gallery")
|
||||
button.view-list(
|
||||
ng-class="{'is-active': vm.mode == 'list'}"
|
||||
ng-if="vm.attachments.size"
|
||||
ng-click="vm.setMode('list')"
|
||||
title="{{ 'ATTACHMENT.LIST_VIEW_MODE' | translate }}"
|
||||
)
|
||||
svg.icon.icon-list
|
||||
use(xlink:href="#icon-list")
|
||||
tg-svg(svg-icon="icon-list")
|
||||
.add-attach(
|
||||
tg-check-permission="modify_{{vm.type}}"
|
||||
title!="{{'ATTACHMENT.ADD' | translate}}"
|
||||
)
|
||||
|
||||
label.add-attachment-button(for="add-attach")
|
||||
svg.icon.icon-add
|
||||
use(xlink:href="#icon-add")
|
||||
tg-svg(svg-icon="icon-add")
|
||||
|
||||
input(
|
||||
id="add-attach",
|
||||
|
@ -55,8 +52,7 @@ section.attachments(
|
|||
|
||||
.single-attachment(ng-repeat="file in vm.uploadingAttachments()")
|
||||
.attachment-name
|
||||
svg.icon.icon-attachment
|
||||
use(xlink:href="#icon-attachment")
|
||||
tg-svg(svg-icon="icon-attachment")
|
||||
span {{file.name}}
|
||||
.attachment-size
|
||||
span {{file.size | sizeFormat}}
|
||||
|
|
|
@ -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")]
|
||||
.add-attach(title!="{{'ATTACHMENT.ADD' | translate}}")
|
||||
label.add-attachment-button(for="add-attach")
|
||||
svg.icon.icon-add
|
||||
use(xlink:href="#icon-add")
|
||||
tg-svg(svg-icon="icon-add")
|
||||
input(
|
||||
id="add-attach"
|
||||
type="file"
|
||||
|
@ -19,8 +18,7 @@ section.attachments(tg-attachments-drop="vm.addAttachments(files)")
|
|||
.attachment-body.attachment-list
|
||||
.single-attachment(tg-repeat="attachment in vm.attachments track by $index")
|
||||
.attachment-name
|
||||
svg.icon.icon-attachment
|
||||
use(xlink:href="#icon-attachment")
|
||||
tg-svg(svg-icon="icon-attachment")
|
||||
span {{attachment.get('name')}}
|
||||
.attachment-size
|
||||
span {{attachment.get('size') | sizeFormat}}
|
||||
|
@ -31,5 +29,4 @@ section.attachments(tg-attachments-drop="vm.addAttachments(files)")
|
|||
title="{{'COMMON.DELETE' | translate}}"
|
||||
ng-click="vm.deleteAttachment(attachment)"
|
||||
)
|
||||
svg.icon.icon-trash
|
||||
use(xlink:href="#icon-trash")
|
||||
tg-svg(svg-icon="icon-trash")
|
||||
|
|
|
@ -21,25 +21,34 @@ AttachmentSortableDirective = ($parse) ->
|
|||
link = (scope, el, attrs) ->
|
||||
callback = $parse(attrs.tgAttachmentsSortable)
|
||||
|
||||
el.sortable({
|
||||
items: "div[tg-bind-scope]"
|
||||
handle: ".settings .icon"
|
||||
containment: ".attachments"
|
||||
dropOnEmpty: true
|
||||
helper: 'clone'
|
||||
scroll: false
|
||||
tolerance: "pointer"
|
||||
placeholder: "sortable-placeholder single-attachment"
|
||||
drake = dragula([el[0]], {
|
||||
copySortSource: false,
|
||||
copy: false,
|
||||
mirrorContainer: el[0],
|
||||
moves: (item) -> return $(item).is('div[tg-bind-scope]')
|
||||
})
|
||||
|
||||
el.on "sortstop", (event, ui) ->
|
||||
attachment = ui.item.scope().attachment
|
||||
newIndex = ui.item.index()
|
||||
drake.on 'dragend', (item) ->
|
||||
item = $(item)
|
||||
|
||||
attachment = item.scope().attachment
|
||||
newIndex = item.index()
|
||||
|
||||
scope.$apply () ->
|
||||
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 {
|
||||
link: link
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
a.close(
|
||||
ng-click="vm.close()"
|
||||
href=""
|
||||
title="{{ COMMON.CLOSE | translate }}"
|
||||
ng-title="COMMON.CLOSE | translate"
|
||||
)
|
||||
svg.icon.icon-close
|
||||
use(xlink:href="#icon-close")
|
||||
tg-svg(svg-icon="icon-close")
|
||||
|
|
|
@ -43,26 +43,27 @@
|
|||
width: 100%;
|
||||
}
|
||||
.title {
|
||||
@extend %bold;
|
||||
@extend %larger;
|
||||
@include font-type(bold);
|
||||
@include font-size(larger);
|
||||
color: $tribe-secondary;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
.warning {
|
||||
color: $tribe-secondary;
|
||||
a {
|
||||
@extend %bold;
|
||||
@include font-type(bold);
|
||||
color: $tribe-secondary;
|
||||
}
|
||||
}
|
||||
.close {
|
||||
height: 2.5rem;
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 1rem;
|
||||
width: 2.5rem;
|
||||
svg {
|
||||
@include svg-size(2rem);
|
||||
fill: lighten($tribe-secondary, 15%);
|
||||
pointer-events: none;
|
||||
transition: fill .2s;
|
||||
&:hover {
|
||||
fill: $tribe-secondary;
|
||||
|
|
|
@ -2,9 +2,9 @@ nav.menu(
|
|||
ng-if="vm.project"
|
||||
ng-class="{'menu-fixed': vm.fixed}",
|
||||
)
|
||||
div(class="menu-container")
|
||||
ul(class="main-nav")
|
||||
li(id="nav-search")
|
||||
.menu-container
|
||||
ul.main-nav
|
||||
li#nav-search
|
||||
a(
|
||||
href=""
|
||||
ng-click="vm.search()"
|
||||
|
@ -12,94 +12,85 @@ nav.menu(
|
|||
aria-label="{{'PROJECT.SECTION.SEARCH' | translate}}"
|
||||
tabindex="1"
|
||||
)
|
||||
svg.icon.icon-search
|
||||
use(xlink:href="#icon-search")
|
||||
tg-svg(svg-icon="icon-search")
|
||||
span.helper(translate="PROJECT.SECTION.SEARCH")
|
||||
|
||||
li(id="nav-timeline")
|
||||
li#nav-timeline
|
||||
a(
|
||||
tg-nav="project:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'project-timeline'}"
|
||||
aria-label="{{'PROJECT.SECTION.TIMELINE' | translate}}"
|
||||
tabindex="2"
|
||||
)
|
||||
svg.icon.icon-timeline
|
||||
use(xlink:href="#icon-timeline")
|
||||
tg-svg(svg-icon="icon-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(
|
||||
tg-nav="project-backlog:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'backlog'}"
|
||||
aria-label="{{'PROJECT.SECTION.BACKLOG' | translate}}"
|
||||
tabindex="2"
|
||||
)
|
||||
svg.icon.icon-scrum
|
||||
use(xlink:href="#icon-scrum")
|
||||
tg-svg(svg-icon="icon-scrum")
|
||||
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(
|
||||
tg-nav="project-kanban:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'kanban'}"
|
||||
aria-label="{{'PROJECT.SECTION.KANBAN' | translate}}"
|
||||
tabindex="3"
|
||||
)
|
||||
svg.icon.icon-kanban
|
||||
use(xlink:href="#icon-kanban")
|
||||
tg-svg(svg-icon="icon-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(
|
||||
tg-nav="project-issues:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'issues'}"
|
||||
aria-label="{{'PROJECT.SECTION.ISSUES' | translate}}"
|
||||
tabindex="4"
|
||||
)
|
||||
svg.icon.icon-issues
|
||||
use(xlink:href="#icon-issues")
|
||||
tg-svg(svg-icon="icon-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(
|
||||
tg-nav="project-wiki:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'wiki'}"
|
||||
aria-label="{{'PROJECT.SECTION.WIKI' | translate}}"
|
||||
tabindex="5"
|
||||
)
|
||||
svg.icon.icon-wiki
|
||||
use(xlink:href="#icon-wiki")
|
||||
tg-svg(svg-icon="icon-wiki")
|
||||
span.helper(translate="PROJECT.SECTION.WIKI")
|
||||
|
||||
li(id="nav-team")
|
||||
li#nav-team
|
||||
a(
|
||||
tg-nav="project-team:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'team'}"
|
||||
aria-label="{{'PROJECT.SECTION.TEAM' | translate}}"
|
||||
tabindex="6"
|
||||
)
|
||||
svg.icon.icon-team
|
||||
use(xlink:href="#icon-team")
|
||||
tg-svg(svg-icon="icon-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(
|
||||
ng-href="{{vm.project.get('videoconferenceUrl')}}"
|
||||
target="_blank"
|
||||
aria-label="{{'PROJECT.SECTION.MEETUP' | translate}}"
|
||||
tabindex="7"
|
||||
)
|
||||
svg.icon.icon-bubble
|
||||
use(xlink:href="#icon-bubble")
|
||||
tg-svg(svg-icon="icon-bubble")
|
||||
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(
|
||||
tg-nav="project-admin-home:project=vm.project.get('slug')"
|
||||
ng-class="{active: vm.active == 'admin'}"
|
||||
aria-label="{{'PROJECT.SECTION.ADMIN' | translate}}"
|
||||
tabindex="8"
|
||||
)
|
||||
svg.icon.icon-settings
|
||||
use(xlink:href="#icon-settings")
|
||||
tg-svg(svg-icon="icon-settings")
|
||||
span.helper(translate="PROJECT.SECTION.ADMIN")
|
||||
|
|
|
@ -9,8 +9,7 @@ a.vote-inner(
|
|||
ng-mouseleave="vm.showTextWhenMouseIsLeave()"
|
||||
)
|
||||
span.track-icon
|
||||
svg.icon.icon-upvote
|
||||
use(xlink:href="#icon-upvote")
|
||||
tg-svg(svg-icon="icon-upvote")
|
||||
span.track-button-counter(
|
||||
title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.total_voters||0}:'messageformat' }}",
|
||||
tg-loading="vm.loading"
|
||||
|
@ -19,8 +18,7 @@ a.vote-inner(
|
|||
//- Anonymous user button
|
||||
span.vote-inner(ng-if="::!vm.user")
|
||||
span.track-icon
|
||||
svg.icon.icon-upvote
|
||||
use(xlink:href="#icon-upvote")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span.track-button-counter(
|
||||
title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.total_voters||0}:'messageformat' }}"
|
||||
) {{ ::vm.item.total_voters }}
|
||||
|
|
|
@ -14,17 +14,14 @@ div.ticket-watch-inner
|
|||
ng-mouseleave="vm.showTextWhenMouseIsLeave()"
|
||||
)
|
||||
span(ng-if="!vm.item.is_watcher")
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
| {{'COMMON.WATCH_BUTTON.WATCH' | translate}}
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{'COMMON.WATCH_BUTTON.WATCH' | translate}}
|
||||
span(ng-if="vm.item.is_watcher && !vm.isMouseOver",)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
| {{'COMMON.WATCH_BUTTON.WATCHING' | translate}}
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{'COMMON.WATCH_BUTTON.WATCHING' | translate}}
|
||||
span(ng-if="vm.item.is_watcher && vm.isMouseOver")
|
||||
svg.icon.icon-unwatch
|
||||
use(xlink:href="#icon-unwatch")
|
||||
| {{'COMMON.WATCH_BUTTON.UNWATCH' | translate}}
|
||||
tg-svg(svg-icon="icon-unwatch")
|
||||
span {{'COMMON.WATCH_BUTTON.UNWATCH' | translate}}
|
||||
|
||||
a.add-watcher(
|
||||
href=""
|
||||
|
|
|
@ -16,8 +16,7 @@ a.track-button.watch-button.watch-container(
|
|||
ng-mouseleave="vm.showTextWhenMouseIsLeave()"
|
||||
)
|
||||
span.track-inner
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span(
|
||||
ng-if="!vm.item.is_watcher",
|
||||
translate="COMMON.WATCH_BUTTON.WATCH"
|
||||
|
@ -38,7 +37,6 @@ span.track-button.watch-button.watch-container(
|
|||
)
|
||||
span.track-inner
|
||||
span.track-icon
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span(translate="COMMON.WATCH_BUTTON.WATCHERS")
|
||||
+counter
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
href="#"
|
||||
ng-click="vm.open()"
|
||||
) {{vm.currentText()}}
|
||||
svg.icon.icon-arrow-down
|
||||
use(xlink:href="#icon-arrow-down")
|
||||
tg-svg(svg-icon="icon-arrow-down")
|
||||
|
||||
ul.filter-list(ng-if="vm.is_open")
|
||||
li(ng-click="vm.orderBy('week')") {{ 'DISCOVER.FILTERS.WEEK' | translate }}
|
||||
|
|
|
@ -18,12 +18,11 @@ div.discover-header
|
|||
placeholder="{{ 'DISCOVER.SEARCH.INPUT_PLACEHOLDER' | translate }}"
|
||||
ng-model="vm.q"
|
||||
)
|
||||
svg.search-button.icon.icon-search(
|
||||
tg-svg.search-button(
|
||||
ng-click="vm.submitFilter()"
|
||||
href="#"
|
||||
title="{{ 'DISCOVER.SEARCH.ACTION_TITLE' | translate }}"
|
||||
svg-icon="icon-search"
|
||||
svg-title-translate="DISCOVER.SEARCH.ACTION_TITLE"
|
||||
)
|
||||
use(xlink:href="#icon-search")
|
||||
|
||||
fieldset.searchbox-filters(ng-if="vm.filter")
|
||||
input(
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
margin: 0 auto;
|
||||
}
|
||||
.title {
|
||||
@extend %xxlarge;
|
||||
@include font-size(xxlarge);
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.project-number {
|
||||
@extend %light;
|
||||
@extend %large;
|
||||
@include font-type(light);
|
||||
@include font-size(large);
|
||||
color: $primary;
|
||||
}
|
||||
form {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
.discover-results-header
|
||||
.discover-results-header-inner
|
||||
.title
|
||||
svg.icon.icon-search
|
||||
use(xlink:href="#icon-search")
|
||||
tg-svg(svg-icon="icon-search")
|
||||
h2 {{ 'DISCOVER.SEARCH.RESULTS' | translate }}
|
||||
|
||||
.filter-discover-search(ng-mouseleave="vm.toggleClose()")
|
||||
|
@ -11,16 +10,14 @@
|
|||
ng-click="vm.openLike()"
|
||||
ng-class="{active: vm.like_is_open}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{ 'DISCOVER.MOST_LIKED' | translate }}
|
||||
a.discover-search-filter(
|
||||
href="#"
|
||||
ng-click="vm.openActivity()"
|
||||
ng-class="{active: vm.activity_is_open}"
|
||||
)
|
||||
svg.icon.icon-activity
|
||||
use(xlink:href="#icon-activity")
|
||||
tg-svg(svg-icon="icon-activity")
|
||||
span {{ 'DISCOVER.MOST_ACTIVE' | translate }}
|
||||
|
||||
.discover-search-subfilter.most-liked-subfilter(ng-if="vm.like_is_open")
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
margin-right: .25rem;
|
||||
}
|
||||
.title {
|
||||
@extend %bold;
|
||||
@extend %larger;
|
||||
@include font-type(bold);
|
||||
@include font-size(larger);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h2 {
|
||||
|
@ -57,7 +57,7 @@
|
|||
animation: dropdownFade .2s;
|
||||
}
|
||||
.results {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
color: $red-light;
|
||||
display: block;
|
||||
padding: .5rem 1rem;
|
||||
|
|
|
@ -26,31 +26,28 @@
|
|||
tg-nav="project:project=project.get('slug')"
|
||||
title="{{::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')"
|
||||
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 ? '' : '...'}}
|
||||
.project-card-statistics
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('is_fan')}"
|
||||
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{::project.get('total_fans')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('is_watcher')}"
|
||||
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{::project.get('total_watchers')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('i_am_member')}"
|
||||
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-team
|
||||
use(xlink:href="#icon-team")
|
||||
tg-svg(svg-icon="icon-team")
|
||||
span.statistics-num {{ ::project.get('members').size }}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
.featured-projects {
|
||||
@include centered;
|
||||
.title {
|
||||
@extend %bold;
|
||||
@extend %larger;
|
||||
@include font-type(bold);
|
||||
@include font-size(larger);
|
||||
color: $grayer;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -24,30 +24,29 @@
|
|||
tg-nav="project:project=project.get('slug')"
|
||||
title="{{::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")
|
||||
title="{{ ::project.get('looking_for_people_note') }}"
|
||||
tg-svg.look-for-people(
|
||||
ng-if="project.get('is_looking_for_people')"
|
||||
svg-icon="icon-recruit"
|
||||
svg-title="{{ ::project.get('looking_for_people_note') }}"
|
||||
)
|
||||
.project-statistics
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('is_fan')}"
|
||||
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{::project.get('total_fans')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('is_watcher')}"
|
||||
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{::project.get('total_watchers')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('i_am_member')}"
|
||||
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-team
|
||||
use(xlink:href="#icon-team")
|
||||
tg-svg(svg-icon="icon-team")
|
||||
span.statistics-num {{ ::project.get('members').size }}
|
||||
p.project-description {{ ::project.get('description') | limitTo:150 }}{{ ::project.get('description').length < 150 ? '' : '...'}}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@
|
|||
}
|
||||
}
|
||||
.title {
|
||||
@extend %bold;
|
||||
@extend %larger;
|
||||
@include font-type(bold);
|
||||
@include font-size(larger);
|
||||
color: $grayer;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
|
@ -85,7 +85,7 @@
|
|||
margin: 1rem auto;
|
||||
}
|
||||
span {
|
||||
@extend %light;
|
||||
@include font-type(light);
|
||||
color: $gray;
|
||||
display: block;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@
|
|||
}
|
||||
}
|
||||
li {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
color: $white;
|
||||
cursor: pointer;
|
||||
min-width: 8rem;
|
||||
|
@ -161,8 +161,8 @@
|
|||
justify-content: space-between;
|
||||
}
|
||||
.project-title {
|
||||
@extend %large;
|
||||
@extend %text;
|
||||
@include font-size(large);
|
||||
@include font-type(text);
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
a {
|
||||
|
@ -172,13 +172,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.look-for-people {
|
||||
@include svg-size();
|
||||
fill: $gray-light;
|
||||
margin-left: .5rem;
|
||||
}
|
||||
.project-description {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
color: $gray;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -191,12 +186,9 @@
|
|||
fill: $gray-light;
|
||||
margin-right: .25rem;
|
||||
}
|
||||
.svg-eye-closed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.statistic {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
color: $gray-light;
|
||||
display: inline-block;
|
||||
margin-right: .5rem;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
.most-active(ng-if="vm.highlighted.size")
|
||||
.header
|
||||
.title-wrapper
|
||||
svg.icon.icon-activity
|
||||
use(xlink:href="#icon-activity")
|
||||
tg-svg(svg-icon="icon-activity")
|
||||
h1.title {{ 'DISCOVER.MOST_ACTIVE' | translate }}
|
||||
tg-discover-home-order-by(on-change="vm.orderBy(orderBy)", order-by="vm.currentOrderBy")
|
||||
|
||||
|
@ -15,6 +14,5 @@
|
|||
.empty-highlighted-project(
|
||||
ng-if="!vm.highlighted.size"
|
||||
)
|
||||
svg.icon.icon-activity
|
||||
use(xlink:href="#icon-activity")
|
||||
tg-svg(svg-icon="icon-activity")
|
||||
span {{ 'DISCOVER.MOST_ACTIVE_EMPTY' | translate }}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
.most-liked(ng-if="vm.highlighted.size")
|
||||
.header
|
||||
.title-wrapper
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
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(
|
||||
loading="vm.loading",
|
||||
highlighted="vm.highlighted"
|
||||
|
@ -14,6 +16,5 @@
|
|||
.empty-highlighted-project(
|
||||
ng-if="!vm.highlighted.size"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{ 'DISCOVER.MOST_LIKED_EMPTY' | translate }}
|
||||
|
|
|
@ -43,9 +43,11 @@ div(tg-discover-search)
|
|||
tg-nav="project:project=project.get('slug')"
|
||||
title="{{ ::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")
|
||||
title="{{ ::project.get('looking_for_people_note') }}"
|
||||
tg-svg.look-for-people(
|
||||
ng-if="project.get('is_looking_for_people')"
|
||||
svg-icon="icon-recruit"
|
||||
svg-title="{{ ::project.get('looking_for_people_note') }}"
|
||||
)
|
||||
p {{ ::project.get('description') | limitTo:300 }}
|
||||
span(ng-if="::project.get('description').length > 300") ...
|
||||
.list-itemtype-project-right.project-statistics
|
||||
|
@ -53,22 +55,19 @@ div(tg-discover-search)
|
|||
ng-class="{'active': project.get('is_fan')}"
|
||||
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{::project.get('total_fans')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('is_watcher')}"
|
||||
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{::project.get('total_watchers')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('i_am_member')}"
|
||||
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-team
|
||||
use(xlink:href="#icon-team")
|
||||
tg-svg(svg-icon="icon-team")
|
||||
span.statistics-num {{ ::project.get('members').size }}
|
||||
|
||||
a.button-green.more-results(
|
||||
|
|
|
@ -71,10 +71,6 @@
|
|||
flex: 1;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.look-for-people {
|
||||
fill: $gray-light;
|
||||
margin-left: .5rem;
|
||||
}
|
||||
.project-statistics {
|
||||
display: flex;
|
||||
flex-basis: 300px;
|
||||
|
@ -84,12 +80,9 @@
|
|||
fill: $gray-light;
|
||||
margin-right: .2rem;
|
||||
}
|
||||
.svg-eye-closed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.statistic {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
color: $gray-light;
|
||||
display: inline-block;
|
||||
margin-right: .5rem;
|
||||
|
@ -121,8 +114,8 @@
|
|||
margin-bottom: 1rem;
|
||||
}
|
||||
.title {
|
||||
@extend %large;
|
||||
@extend %light;
|
||||
@include font-size(large);
|
||||
@include font-type(light);
|
||||
margin: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
margin: 0;
|
||||
}
|
||||
h3 {
|
||||
@extend %large;
|
||||
@include font-size(large);
|
||||
}
|
||||
a {
|
||||
@extend %xsmall;
|
||||
@include font-size(x-small);
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@
|
|||
|
||||
}
|
||||
p {
|
||||
@extend %xsmall;
|
||||
@include font-size(x-small);
|
||||
}
|
||||
}
|
||||
.user-card {
|
||||
|
@ -67,7 +67,7 @@
|
|||
display: block;
|
||||
}
|
||||
.cancel {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
display: block;
|
||||
margin-top: .5rem;
|
||||
text-align: left;
|
||||
|
|
|
@ -19,9 +19,12 @@ a.list-itemtype-ticket(
|
|||
|
||||
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') }}
|
||||
svg.icon.icon-blocked-project(ng-if="vm.duty.get('blockedProject')")
|
||||
use(xlink:href="#icon-blocked-project")
|
||||
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
|
||||
|
||||
tg-svg(
|
||||
ng-if="vm.duty.get('blockedProject')",
|
||||
svg-icon="icon-blocked-project",
|
||||
svg-title-translate="PROJECT.BLOCKED_PROJECT.BLOCKED"
|
||||
)
|
||||
|
||||
h2
|
||||
span.ticket-id(tg-bo-ref="duty.get('ref')")
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
display: block;
|
||||
}
|
||||
.title-bar {
|
||||
@extend %light;
|
||||
@extend %larger;
|
||||
@include font-type(light);
|
||||
@include font-size(larger);
|
||||
align-content: center;
|
||||
background: $whitish;
|
||||
display: flex;
|
||||
|
|
|
@ -11,7 +11,10 @@ section.home-project-list(ng-if="vm.projects.size")
|
|||
title="{{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
|
||||
a.project-card-logo(
|
||||
href="#"
|
||||
|
@ -22,18 +25,30 @@ section.home-project-list(ng-if="vm.projects.size")
|
|||
tg-project-logo-small-src="::project"
|
||||
alt="{{::project.get('name')}}"
|
||||
)
|
||||
h2.project-card-name
|
||||
h3.project-card-name
|
||||
a.project-title(
|
||||
href="#"
|
||||
tg-nav="project:project=project.get('slug')"
|
||||
title="{{::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")
|
||||
title="{{ ::project.get('looking_for_people_note') }}"
|
||||
svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
|
||||
use(xlink:href="#icon-blocked-project")
|
||||
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
|
||||
|
||||
tg-svg.look-for-people(
|
||||
ng-if="project.get('is_looking_for_people')"
|
||||
svg-icon="icon-recruit"
|
||||
svg-title="{{ ::project.get('looking_for_people_note') }}"
|
||||
)
|
||||
|
||||
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 }}
|
||||
span(ng-if="::project.get('description').length > 100") ...
|
||||
|
@ -42,29 +57,25 @@ section.home-project-list(ng-if="vm.projects.size")
|
|||
ng-class="{'active': project.get('is_fan')}"
|
||||
title="{{ 'PROJECT.FANS_COUNTER_TITLE'|translate:{total:project.get('total_fans')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{::project.get('total_fans')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('is_watcher')}"
|
||||
title="{{ 'PROJECT.WATCHERS_COUNTER_TITLE'|translate:{total:project.get('total_watchers')||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{::project.get('total_watchers')}}
|
||||
span.statistic(
|
||||
ng-class="{'active': project.get('i_am_member')}"
|
||||
title="{{ 'PROJECT.MEMBERS_COUNTER_TITLE'|translate:{total:project.get('members').size||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-team
|
||||
use(xlink:href="#icon-team")
|
||||
tg-svg(svg-icon="icon-team")
|
||||
span.statistics-num {{ ::project.get('members').size }}
|
||||
span.statistic(
|
||||
ng-if="::project.get('is_private')"
|
||||
title="{{ 'PROJECT.PRIVATE' | translate }}"
|
||||
)
|
||||
svg.icon.icon-lock
|
||||
use(xlink:href="#icon-lock")
|
||||
tg-svg(svg-icon="icon-lock")
|
||||
|
||||
a.see-more-projects-btn.button-gray(
|
||||
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")
|
||||
svg.icon.icon-project
|
||||
use(xlink:href="#icon-project")
|
||||
tg-svg(svg-icon="icon-project")
|
||||
p(translate="HOME.EMPTY_PROJECT_LIST")
|
||||
a.create-project-button.button-green(href="#", ng-click="vm.newProject()",
|
||||
title="{{'PROJECT.NAVIGATION.TITLE_CREATE_PROJECT' | translate}}",
|
||||
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT")
|
||||
a.create-project-button.button-green(
|
||||
href="#"
|
||||
ng-click="vm.newProject()"
|
||||
title="{{'PROJECT.NAVIGATION.TITLE_CREATE_PROJECT' | translate}}"
|
||||
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT"
|
||||
)
|
||||
span(tg-import-project-button)
|
||||
a.import-project-button.button-blackish(href="#",
|
||||
title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}",
|
||||
translate="PROJECT.NAVIGATION.ACTION_IMPORT_PROJECT")
|
||||
a.import-project-button.button-blackish(
|
||||
href="#"
|
||||
title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}"
|
||||
translate="PROJECT.NAVIGATION.ACTION_IMPORT_PROJECT"
|
||||
)
|
||||
input.import-file.hidden(type="file")
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
.tags-container,
|
||||
.project-card-logo,
|
||||
.project-card-name a,
|
||||
.icon-recruit,
|
||||
.project-card-description,
|
||||
.project-card-statistics {
|
||||
opacity: .3;
|
||||
|
@ -36,8 +35,8 @@
|
|||
width: 100%;
|
||||
}
|
||||
p {
|
||||
@extend %small;
|
||||
@extend %light;
|
||||
@include font-size(small);
|
||||
@include font-type(light);
|
||||
}
|
||||
.create-project-button {
|
||||
display: block;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.watching-empty {
|
||||
margin-bottom: 4rem;
|
||||
p {
|
||||
@extend %light;
|
||||
@include font-type(light);
|
||||
margin: 2rem 9rem 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
section.working-on-container
|
||||
|
||||
header
|
||||
h1
|
||||
span.green {{"HOME.DASHBOARD" | translate}}
|
||||
|
||||
|
||||
.title-bar.working-on-title(translate="HOME.WORKING_ON_SECTION")
|
||||
section.working-on-container
|
||||
header
|
||||
h1.title-bar.working-on-title(translate="HOME.WORKING_ON_SECTION")
|
||||
|
||||
.working-on(ng-if="vm.assignedTo.size")
|
||||
.duty-single(
|
||||
|
@ -17,7 +15,8 @@ section.working-on-container
|
|||
include empty.jade
|
||||
|
||||
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")
|
||||
.duty-single(
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
a(href="", title="Projects", tg-nav="projects")
|
||||
svg.icon.icon-project
|
||||
use(xlink:href="#icon-project")
|
||||
a(
|
||||
href=""
|
||||
title="Projects"
|
||||
tg-nav="projects"
|
||||
)
|
||||
tg-svg(svg-icon="icon-project")
|
||||
|
||||
div.navbar-dropdown.dropdown-project-list
|
||||
ul
|
||||
|
@ -11,9 +14,11 @@ div.navbar-dropdown.dropdown-project-list
|
|||
ng-class="{'blocked-project': project.get('blocked_code')}"
|
||||
)
|
||||
span {{::project.get("name")}}
|
||||
svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
|
||||
use(xlink:href="#icon-blocked-project")
|
||||
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
|
||||
tg-svg(
|
||||
svg-icon="icon-blocked-project"
|
||||
ng-if="project.get('blocked_code')"
|
||||
svg-title="PROJECT.BLOCKED_PROJECT.BLOCKED"
|
||||
)
|
||||
|
||||
a.see-more-projects-btn.button-gray(
|
||||
href="#",
|
||||
|
@ -33,6 +38,5 @@ div.navbar-dropdown.dropdown-project-list
|
|||
href=""
|
||||
title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}"
|
||||
)
|
||||
svg.icon.icon-upload
|
||||
use(xlink:href="#icon-upload")
|
||||
tg-svg(svg-icon="icon-upload")
|
||||
input.import-file.hidden(type="file")
|
|
@ -30,8 +30,6 @@ div.navbar-dropdown.dropdown-user
|
|||
ng-class="{active: plugin.slug == currentPlugin.slug}"
|
||||
)
|
||||
span.title {{ plugin.name }}
|
||||
span.new(translate="PROJECT.NAVIGATION.NEW_ITEM")
|
||||
|
||||
li
|
||||
a(
|
||||
href="#",
|
||||
|
@ -54,7 +52,7 @@ div.navbar-dropdown.dropdown-user
|
|||
translate="PROJECT.NAVIGATION.FEEDBACK")
|
||||
li
|
||||
a(
|
||||
href="https://taiga.io/support/",
|
||||
href="https://tree.taiga.io/support/",
|
||||
target="_blank",
|
||||
title="{{'PROJECT.NAVIGATION.HELP_TITLE' | translate}}",
|
||||
translate="PROJECT.NAVIGATION.HELP")
|
||||
|
|
|
@ -16,7 +16,7 @@ nav.navbar(ng-if="vm.isEnabledHeader")
|
|||
include ../../svg/logo.svg
|
||||
|
||||
a(
|
||||
href="https://taiga.io/support/",
|
||||
href="https://tree.taiga.io/support/",
|
||||
target="_blank",
|
||||
title="{{'PROJECT.NAVIGATION.HELP_TITLE' | translate}}",
|
||||
translate="PROJECT.NAVIGATION.HELP"
|
||||
|
@ -38,21 +38,19 @@ nav.navbar(ng-if="vm.isEnabledHeader")
|
|||
)
|
||||
|
||||
div.nav-right(ng-if="vm.isAuthenticated")
|
||||
a(tg-nav="home",
|
||||
ng-class="{active: vm.active}",
|
||||
title="{{'PROJECT.NAVIGATION.DASHBOARD_TITLE' | translate}}")
|
||||
|
||||
svg.icon.icon-dashboard
|
||||
use(xlink:href="#icon-dashboard")
|
||||
a(
|
||||
tg-nav="home"
|
||||
ng-class="{active: vm.active}"
|
||||
title="{{'PROJECT.NAVIGATION.DASHBOARD_TITLE' | translate}}"
|
||||
)
|
||||
tg-svg(svg-icon="icon-dashboard")
|
||||
|
||||
a(
|
||||
href="#",
|
||||
tg-nav="discover",
|
||||
title="{{'PROJECT.NAVIGATION.DISCOVER_TITLE' | translate}}",
|
||||
)
|
||||
svg.icon.icon-discover
|
||||
use(xlink:href="#icon-discover")
|
||||
tg-svg(svg-icon="icon-discover")
|
||||
|
||||
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)
|
||||
|
|
|
@ -136,7 +136,7 @@ $dropdown-width: 350px;
|
|||
}
|
||||
}
|
||||
.new {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
background: $red-light;
|
||||
float: right;
|
||||
margin-left: auto;
|
||||
|
|
|
@ -4,8 +4,7 @@ section.profile-contacts
|
|||
img(src="/#{v}/svg/spinner-circle.svg", alt="Loading...")
|
||||
|
||||
div.empty-tab(ng-if="vm.contacts && !vm.contacts.size")
|
||||
svg.icon.icon-unwatch
|
||||
use(xlink:href="#icon-unwatch")
|
||||
tg-svg(svg-icon="icon-unwatch")
|
||||
|
||||
div(ng-if="!vm.isCurrentUser")
|
||||
p(translate="USER.PROFILE.CONTACTS_EMPTY", translate-values="{username: vm.user.get('full_name_display')}")
|
||||
|
|
|
@ -18,12 +18,18 @@
|
|||
tg-nav="project:project=vm.item.get('slug')"
|
||||
title="{{ ::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")
|
||||
title {{'PROJECT.PRIVATE' | translate}}"
|
||||
svg.icon.icon-blocked-project(ng-if="vm.item.get('project_blocked_code')")
|
||||
use(xlink:href="#icon-blocked-project")
|
||||
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
|
||||
|
||||
tg-svg(
|
||||
ng-if="::vm.item.get('is_private')"
|
||||
svg-icon="icon-lock"
|
||||
svg-title-translate="PROJECT.PRIVATE"
|
||||
)
|
||||
|
||||
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') }}
|
||||
|
||||
.list-itemtype-track
|
||||
|
@ -31,14 +37,12 @@
|
|||
ng-class="{'active': vm.item.get('is_fan')}"
|
||||
title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_fans\")||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{ ::vm.item.get('total_fans') }}
|
||||
|
||||
span.list-itemtype-track-watchers(
|
||||
ng-class="{'active': vm.item.get('is_watcher')}"
|
||||
title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_watchers\")||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{ ::vm.item.get('total_watchers') }}
|
||||
|
|
|
@ -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(
|
||||
href=""
|
||||
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 }}"
|
||||
)
|
||||
|
||||
div.list-itemtype-ticket-data
|
||||
.list-itemtype-ticket-data
|
||||
p
|
||||
span.ticket-project
|
||||
| {{:: 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'"
|
||||
translate="COMMON.ISSUE"
|
||||
)
|
||||
span.ticket-status(ng-style="::{'color': vm.item.get('status_color')}")
|
||||
| {{:: vm.item.get('status') }}
|
||||
svg.icon.icon-blocked-project(ng-if="vm.item.get('project_blocked_code')")
|
||||
use(xlink:href="#icon-blocked-project")
|
||||
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
|
||||
span.ticket-status(ng-style="::{'color': vm.item.get('status_color')}") {{:: vm.item.get('status') }}
|
||||
tg-svg(
|
||||
ng-if="vm.item.get('project_blocked_code')"
|
||||
svg-icon="icon-blocked-project"
|
||||
svgTitleTranslate: "PROJECT.BLOCKED_PROJECT.BLOCKED"
|
||||
)
|
||||
h2
|
||||
span.ticket-id(tg-bo-ref="vm.item.get('ref')")
|
||||
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')}",
|
||||
title="{{ 'COMMON.VOTE_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_voters\")||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-upvote
|
||||
use(xlink:href="#icon-upvote")
|
||||
tg-svg(svg-icon="icon-upvote")
|
||||
span {{ ::vm.item.get('total_voters') }}
|
||||
|
||||
span.list-itemtype-track-watchers(
|
||||
ng-class="{'active': vm.item.get('is_watcher')}"
|
||||
title="{{ 'COMMON.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.item.get(\"total_watchers\")||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{ ::vm.item.get('total_watchers') }}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
section.profile-favs
|
||||
div.profile-filter
|
||||
div.searchbox(ng-if="::vm.enableFilterByTextQuery")
|
||||
svg.icon.icon-search
|
||||
use(xlink:href="#icon-search")
|
||||
tg-svg(svg-icon="icon-search")
|
||||
input(
|
||||
type="text"
|
||||
ng-model="vm.q"
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
class ProfileHints
|
||||
HINTS: [
|
||||
{ #hint1
|
||||
url: "https://taiga.io/support/import-export-projects/"
|
||||
url: "https://tree.taiga.io/support/admin/import-export-projects/"
|
||||
},
|
||||
{ #hint2
|
||||
url: "https://taiga.io/support/custom-fields/"
|
||||
url: "https://tree.taiga.io/support/admin/custom-fields/"
|
||||
},
|
||||
{ #hint3
|
||||
},
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
h4
|
||||
svg.icon.icon-question
|
||||
use(xlink:href="#icon-question")
|
||||
tg-svg(svg-icon="icon-question")
|
||||
span(translate="HINTS.SECTION_NAME")
|
||||
|
||||
p {{::vm.hint.title}}
|
||||
|
|
|
@ -4,8 +4,7 @@ section.profile-projects
|
|||
img(src="/#{v}/svg/spinner-circle.svg", alt="Loading...")
|
||||
|
||||
.empty-tab(ng-if="vm.projects && !vm.projects.size")
|
||||
svg.icon.icon-unwatch
|
||||
use(xlink:href="#icon-unwatch")
|
||||
tg-svg(svg-icon="icon-unwatch")
|
||||
|
||||
p(
|
||||
translate="USER.PROFILE.PROJECTS_EMPTY"
|
||||
|
@ -33,9 +32,12 @@ section.profile-projects
|
|||
tg-nav="project:project=project.get('slug')"
|
||||
title="{{ ::project.get('name') }}"
|
||||
) {{::project.get('name')}}
|
||||
svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
|
||||
use(xlink:href="#icon-blocked-project")
|
||||
title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
|
||||
|
||||
tg-svg(
|
||||
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 }}
|
||||
|
||||
.list-itemtype-project-right
|
||||
|
@ -45,16 +47,14 @@ section.profile-projects
|
|||
ng-class="{'active': project.get('is_fan')}"
|
||||
title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:project.get(\"total_fans\")||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-like
|
||||
use(xlink:href="#icon-like")
|
||||
tg-svg(svg-icon="icon-like")
|
||||
span {{ ::project.get('total_fans') }}
|
||||
|
||||
span.list-itemtype-track-watchers(
|
||||
ng-class="{'active': project.get('is_watcher')}"
|
||||
title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:project.get(\"total_watchers\")||0}:'messageformat' }}"
|
||||
)
|
||||
svg.icon.icon-watch
|
||||
use(xlink:href="#icon-watch")
|
||||
tg-svg(svg-icon="icon-watch")
|
||||
span {{ ::project.get('total_watchers') }}
|
||||
|
||||
.list-itemtype-project-members
|
||||
|
|
|
@ -28,7 +28,6 @@ ProfileTabDirective = () ->
|
|||
scope.tab.title = title
|
||||
|
||||
scope.tab.icon = attrs.tabIcon
|
||||
scope.tab.iconName = '#' + attrs.tabIcon
|
||||
scope.tab.active = !!attrs.tabActive
|
||||
|
||||
if scope.$eval(attrs.tabDisabled) != true
|
||||
|
|
|
@ -7,8 +7,7 @@ div
|
|||
ng-click="vm.toggleTab(tab)"
|
||||
ng-class="{active: tab.active}"
|
||||
)
|
||||
svg.icon(ng-class="::tab.icon")
|
||||
use(xlink:href="{{::tab.iconName}}")
|
||||
tg-svg(svg-icon="{{::tab.icon}}")
|
||||
span {{::tab.name}}
|
||||
|
||||
ng-transclude
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
margin: 10% auto;
|
||||
width: 3rem;
|
||||
img {
|
||||
@extend %loading-spinner;
|
||||
@include loading-spinner;
|
||||
max-height: 3rem;
|
||||
max-width: 3rem;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
width: 100%;
|
||||
}
|
||||
.profile-edition {
|
||||
@extend %large;
|
||||
@extend %light;
|
||||
@include font-size(large);
|
||||
@include font-type(light);
|
||||
background: rgba($black, .4);
|
||||
bottom: 0;
|
||||
color: $white;
|
||||
|
@ -64,8 +64,8 @@
|
|||
}
|
||||
}
|
||||
h1 {
|
||||
@extend %bold;
|
||||
@extend %xlarge;
|
||||
@include font-type(bold);
|
||||
@include font-size(xlarge);
|
||||
line-height: 1.2;
|
||||
margin-bottom: .25rem;
|
||||
text-transform: none;
|
||||
|
@ -75,15 +75,15 @@
|
|||
word-wrap: break-word;
|
||||
}
|
||||
h2 {
|
||||
@extend %light;
|
||||
@extend %larger;
|
||||
@include font-type(light);
|
||||
@include font-size(larger);
|
||||
color: $gray;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.username {
|
||||
@extend %light;
|
||||
@extend %large;
|
||||
@include font-type(light);
|
||||
@include font-size(large);
|
||||
color: $gray-light;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
@ -112,43 +112,20 @@
|
|||
text-align: center;
|
||||
}
|
||||
.stat-number {
|
||||
@extend %xlarge;
|
||||
@extend %bold;
|
||||
@include font-size(xlarge);
|
||||
@include font-type(bold);
|
||||
display: block;
|
||||
line-height: 1;
|
||||
}
|
||||
.stat-name {
|
||||
@extend %title;
|
||||
@extend %small;
|
||||
@include font-type(text);
|
||||
@include font-size(small);
|
||||
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 {
|
||||
@extend %light;
|
||||
@extend %large;
|
||||
@include font-type(light);
|
||||
@include font-size(large);
|
||||
background: url('../images/quote.png') no-repeat top left;
|
||||
line-height: 1.4;
|
||||
padding: .5rem;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.profile-sidebar {
|
||||
h4 {
|
||||
@extend %bold;
|
||||
@include font-type(bold);
|
||||
background: $whitish;
|
||||
color: $gray;
|
||||
margin-bottom: .5rem;
|
||||
|
@ -13,7 +13,7 @@
|
|||
}
|
||||
}
|
||||
p {
|
||||
@extend %small;
|
||||
@include font-size(small);
|
||||
color: $gray-light;
|
||||
}
|
||||
a {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue