Merge branch 'master' into stable

stable
Jesús Espino 2017-03-10 17:08:37 +01:00
commit 78bee2ae08
1921 changed files with 21719 additions and 7752 deletions

View File

@ -1,3 +0,0 @@
{
"directory" : "vendor"
}

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
7.2.1

View File

@ -1,14 +1,17 @@
language: node_js language: node_js
dist: trusty
node_js: node_js:
- "4.1" - "node"
before_install: before_install:
- export CHROME_BIN=chromium-browser - sudo apt-get update
- export DISPLAY=:99.0 - sudo apt-get install -y libappindicator1 fonts-liberation
- sh -e /etc/init.d/xvfb start - wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- travis_retry npm install -g bower - sudo dpkg -i google-chrome*.deb
- travis_retry npm install -g gulp
install: install:
- travis_retry npm install - travis_retry npm install
- travis_retry bower install
before_script: before_script:
- export CHROME_BIN=/usr/bin/google-chrome
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- travis_retry npm install -g gulp
- gulp deploy - gulp deploy

View File

@ -1,5 +1,32 @@
# Changelog # # Changelog #
## 3.1.0 Perovskia Atriplicifolia (2017-03-10)
### Features
- New project creation form: Now you can:
- duplicate a project.
- import from Taiga.
- import from Trello.
- import from Jira.
- import from GitHub.
- import from Asana.
- Improve add-members form: Now users can select between their contacts or type an email.
- Contact with the project: if the projects have this module enabled Taiga users can contact them.
- Velocity forecasting. Create sprints according to team velocity.
- Add new wysiwyg editor (like the Medunm editor) with emojis, local storage changes, mentions...
- Add rich text custom fields (with a wysiwyg editor like descreption or comments).
- Add thumbnails and preview for:
- PSD files.
- SVG files.
- i18n:
- Add japanese (ja) translation.
- Add korean (ko) translation.
- Add chinese simplified (zh-Hans) translation.
### Misc
- Lots of small and not so small bugfixes.
- Remove bower, now use only npm packages.
## 3.0.0 Stellaria Borealis (2016-10-02) ## 3.0.0 Stellaria Borealis (2016-10-02)

View File

@ -2,18 +2,18 @@
Please ensure that your issue is not already reported in our [issues list](https://tree.taiga.io/project/taiga/issues?order_by=-created_date). Please ensure that your issue is not already reported in our [issues list](https://tree.taiga.io/project/taiga/issues?order_by=-created_date).
If this issue was already reported, remember that you can upvote it to raise its importance. If this issue was already reported, remember that you can upvote it to raise its importance.
###Do you want to request a *feature* or report a *bug*? **Do you want to request a *feature* or report a *bug*?**
###What is the current behavior? **What is the current behavior?**
###If the current behavior is a bug, please provide the steps to reproduce. **If the current behavior is a bug, please provide the steps to reproduce.**
###What is the expected behavior? **What is the expected behavior?**
###Is it happening in taiga.io or in your own instance? **Is it happening in taiga.io or in your own instance?**
###What browser/version are you using? **What browser/version are you using?**
###Are there any console errors *(Ctrl + F12)* in red? **Are there any console errors *(Ctrl + F12)* in red?**
Thanks for reporting! Thanks for reporting!

View File

@ -1,10 +1,8 @@
# Taiga Front # # Taiga Front #
![Kaleidos Project](http://kaleidos.net/static/img/badge.png "Kaleidos Project") ![Kaleidos Project](http://kaleidos.net/static/img/badge.svg "Kaleidos Project")
[![Managed with Taiga](https://taiga.io/media/support/attachments/article-22/banner-gh.png)](https://taiga.io "Managed with Taiga") [![Managed with Taiga.io](https://img.shields.io/badge/managed%20with-TAIGA.io-709f14.svg)](https://tree.taiga.io/project/taiga/ "Managed with Taiga.io")
[![Build Status](https://travis-ci.org/taigaio/taiga-front.svg?branch=public-header-bar)](https://travis-ci.org/taigaio/taiga-front) [![Build Status](https://img.shields.io/travis/taigaio/taiga-front.svg)](https://travis-ci.org/taigaio/taiga-front "Build Status")
[![Dependency Status](https://www.versioneye.com/user/projects/561ba659a193340f280013f4/badge.svg?style=flat)](https://www.versioneye.com/user/projects/561ba659a193340f280013f4)
## Get the compiled version ## ## Get the compiled version ##
@ -39,6 +37,7 @@ Every code patch accepted in taiga codebase is licensed under [AGPL v3.0](http:/
Please read carefully [our license](https://github.com/taigaio/taiga-front/blob/master/LICENSE) and ask us if you have any questions. Please read carefully [our license](https://github.com/taigaio/taiga-front/blob/master/LICENSE) and ask us if you have any questions.
Emoji provided free by [Twemoji](https://github.com/twitter/twemoji)
#### Bug reports, enhancements and support #### #### Bug reports, enhancements and support ####
@ -125,14 +124,12 @@ sass -v # should return Sass 3.3.8 (Maptastic Maple)
Complete process for all OS at: http://sass-lang.com/install Complete process for all OS at: http://sass-lang.com/install
**Node + Bower + Gulp** **Node + Gulp**
We recommend using [nvm](https://github.com/creationix/nvm) to manage different node versions We recommend using [nvm](https://github.com/creationix/nvm) to manage different node versions
``` ```
npm install -g gulp npm install -g gulp
npm install -g bower
npm install npm install
bower install
gulp gulp
``` ```

View File

@ -15,6 +15,7 @@ window.taigaConfig = {
"privacyPolicyUrl": null, "privacyPolicyUrl": null,
"termsOfServiceUrl": null, "termsOfServiceUrl": null,
"maxUploadFileSize": null, "maxUploadFileSize": null,
"importers": [],
"contribPlugins": [] "contribPlugins": []
} }

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -126,6 +126,54 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
controllerAs: "vm" controllerAs: "vm"
} }
) )
# Project
$routeProvider.when("/project/new",
{
title: "PROJECT.CREATE.TITLE",
templateUrl: "projects/create/create-project.html",
loader: true,
controller: "CreateProjectCtrl",
controllerAs: "vm"
}
)
# Project - scrum
$routeProvider.when("/project/new/scrum",
{
title: "PROJECT.CREATE.TITLE",
template: "<tg-create-project-form type=\"scrum\"></tg-create-project-form>",
loader: true
}
)
# Project - kanban
$routeProvider.when("/project/new/kanban",
{
title: "PROJECT.CREATE.TITLE",
template: "<tg-create-project-form type=\"kanban\"></tg-create-project-form>",
loader: true
}
)
# Project - duplicate
$routeProvider.when("/project/new/duplicate",
{
title: "PROJECT.CREATE.TITLE",
template: "<tg-duplicate-project></tg-duplicate-project>",
loader: true
}
)
# Project - import
$routeProvider.when("/project/new/import/:platform?",
{
title: "PROJECT.CREATE.TITLE",
template: "<tg-import-project></tg-import-project>",
loader: true
}
)
# Project # Project
$routeProvider.when("/project/:pslug/", $routeProvider.when("/project/:pslug/",
{ {

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -27,112 +27,6 @@ debounce = @.taiga.debounce
module = angular.module("taigaKanban") module = angular.module("taigaKanban")
#############################################################################
## Create Members Lightbox Directive
#############################################################################
class LightboxAddMembersController
@.$inject = [
"$scope",
"lightboxService",
"tgLoader",
"$tgConfirm",
"$tgResources",
"$rootScope",
]
constructor: (@scope, @lightboxService, @tgLoader, @confirm, @rs, @rootScope) ->
@._defaultMaxInvites = 4
@._defaultRole = @.project.roles[0].id
@.form = null
@.submitInvites = false
@.canAddUsers = true
@.memberInvites = []
if @.project.max_memberships == null
@.membersLimit = @._defaultMaxInvites
else
pendingMembersCount = Math.max(@.project.max_memberships - @.project.total_memberships, 0)
@.membersLimit = Math.min(pendingMembersCount, @._defaultMaxInvites)
@.addSingleMember()
addSingleMember: () ->
@.memberInvites.push({email:'', role_id: @._defaultRole})
if @.memberInvites.length >= @.membersLimit
@.canAddUsers = false
@.showWarningMessage = (!@.canAddUsers &&
@.project.total_memberships + @.memberInvites.length == @.project.max_memberships)
removeSingleMember: (index) ->
@.memberInvites.splice(index, 1)
@.canAddUsers = true
@.showWarningMessage = @.membersLimit == 1
submit: () ->
# Need to reset the form constrains
@.form.initializeFields()
@.form.reset()
return if not @.form.validate()
@.memberInvites = _.filter(@.memberInvites, (invites) ->
invites.email != "")
@.submitInvites = true
promise = @rs.memberships.bulkCreateMemberships(
@.project.id,
@.memberInvites,
@.invitationText
)
promise.then(
@._onSuccessInvite.bind(this),
@._onErrorInvite.bind(this)
)
_onSuccessInvite: () ->
@.submitInvites = false
@rootScope.$broadcast("membersform:new:success")
@lightboxService.closeAll()
@confirm.notify("success")
_onErrorInvite: (response) ->
@.submitInvites = false
errors = {}
_.each response.data.bulk_memberships, (value, index) =>
if value.email
errors["email-#{index}"] = value.email[0]
if value.role
errors["role-#{index}"] = value.role[0]
@.form.setErrors(errors)
if response.data._error_message
@confirm.notify("error", response.data._error_message)
module.controller("LbAddMembersController", LightboxAddMembersController)
LightboxAddMembersDirective = (lightboxService) ->
link = (scope, el, attrs, ctrl) ->
lightboxService.open(el)
ctrl.form = el.find("form").checksley()
return {
scope: {},
bindToController: {
project: '=',
},
controller: 'LbAddMembersController',
controllerAs: 'vm',
templateUrl: 'admin/lightbox-add-members.html',
link: link
}
module.directive("tgLbAddMembers", ["lightboxService", LightboxAddMembersDirective])
############################################################################# #############################################################################
## Warning message directive ## Warning message directive
############################################################################# #############################################################################

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -50,11 +50,12 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
"$translate", "$translate",
"$tgAuth", "$tgAuth",
"tgLightboxFactory", "tgLightboxFactory",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @analytics, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, @analytics,
@appMetaService, @translate, @auth, @lightboxFactory, @errorHandlingService) -> @appMetaService, @translate, @auth, @lightboxFactory, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.project = {} @scope.project = {}
@ -74,17 +75,18 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
@analytics.trackEvent("membership", "create", "create memberships on admin", 1) @analytics.trackEvent("membership", "create", "create memberships on admin", 1)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.i_am_admin
@scope.project = project @errorHandlingService.permissionDenied()
@scope.canAddUsers = project.max_memberships == null || project.max_memberships > project.total_memberships @scope.projectId = project.id
@scope.project = project
@scope.$emit('project:loaded', project) @scope.canAddUsers = project.max_memberships == null || project.max_memberships > project.total_memberships
return project
@scope.$emit('project:loaded', project)
return project
loadMembers: -> loadMembers: ->
httpFilters = @.getUrlFilters() httpFilters = @.getUrlFilters()
@ -99,11 +101,12 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai
return data return data
loadInitialData: -> loadInitialData: ->
return @.loadProject().then () => @.loadProject()
return @q.all([
@.loadMembers(), return @q.all([
@auth.refresh() @.loadMembers(),
]) @auth.refresh()
])
getUrlFilters: -> getUrlFilters: ->
filters = _.pick(@location.search(), "page") filters = _.pick(@location.search(), "page")
@ -392,7 +395,7 @@ module.directive("tgMembershipsRowRoleSelector", ["$log", "$tgRepo", "$tgConfirm
############################################################################# #############################################################################
MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $translate, $location, MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $translate, $location,
$navUrls, lightboxFactory) -> $navUrls, lightboxFactory, projectService) ->
activedTemplate = """ activedTemplate = """
<div class="active" <div class="active"
translate="ADMIN.MEMBERSHIP.STATUS_ACTIVE"> translate="ADMIN.MEMBERSHIP.STATUS_ACTIVE">
@ -455,7 +458,8 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
if $scope.page > 1 && ($scope.count - 1) <= $scope.paginatedBy if $scope.page > 1 && ($scope.count - 1) <= $scope.paginatedBy
$ctrl.selectFilter("page", $scope.page - 1) $ctrl.selectFilter("page", $scope.page - 1)
$ctrl.loadInitialData() projectService.fetchProject().then =>
$ctrl.loadInitialData()
else else
$location.path($navUrls.resolve("home")) $location.path($navUrls.resolve("home"))
@ -492,7 +496,7 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla
module.directive("tgMembershipsRowActions", ["$log", "$tgRepo", "$tgResources", "$tgConfirm", "$compile", module.directive("tgMembershipsRowActions", ["$log", "$tgRepo", "$tgResources", "$tgConfirm", "$compile",
"$translate", "$tgLocation", "$tgNavUrls", "tgLightboxFactory", "$translate", "$tgLocation", "$tgNavUrls", "tgLightboxFactory",
MembershipsRowActionsDirective]) "tgProjectService", MembershipsRowActionsDirective])
############################################################################# #############################################################################

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -54,15 +54,17 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
"$translate", "$translate",
"$tgAuth", "$tgAuth",
"tgCurrentUserService", "tgCurrentUserService",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService",
"$tgModel"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
@appMetaService, @translate, @tgAuth, @currentUserService, @errorHandlingService) -> @appMetaService, @translate, @tgAuth, @currentUserService, @errorHandlingService, @projectService, @model) ->
@scope.project = {} @scope.project = {}
promise = @.loadInitialData()
@scope.projectTags = [] @scope.projectTags = []
promise = @.loadInitialData()
promise.then => promise.then =>
sectionName = @translate.instant( @scope.sectionName) sectionName = @translate.instant( @scope.sectionName)
@ -83,32 +85,33 @@ class ProjectProfileController extends mixOf(taiga.Controller, taiga.PageMixin)
@appMetaService.setAll(title, description) @appMetaService.setAll(title, description)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin project = @model.make_model("projects", project)
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.i_am_admin
@scope.project = project @errorHandlingService.permissionDenied()
@scope.epicStatusList = _.sortBy(project.epic_statuses, "order")
@scope.usStatusList = _.sortBy(project.us_statuses, "order")
@scope.pointsList = _.sortBy(project.points, "order")
@scope.taskStatusList = _.sortBy(project.task_statuses, "order")
@scope.issueTypesList = _.sortBy(project.issue_types, "order")
@scope.issueStatusList = _.sortBy(project.issue_statuses, "order")
@scope.prioritiesList = _.sortBy(project.priorities, "order")
@scope.severitiesList = _.sortBy(project.severities, "order")
@scope.$emit('project:loaded', project)
@scope.projectTags = _.map @scope.project.tags, (it) => @scope.projectId = project.id
return [it, @scope.project.tags_colors[it]] @scope.project = project
@scope.epicStatusList = _.sortBy(project.epic_statuses, "order")
@scope.usStatusList = _.sortBy(project.us_statuses, "order")
@scope.pointsList = _.sortBy(project.points, "order")
@scope.taskStatusList = _.sortBy(project.task_statuses, "order")
@scope.issueTypesList = _.sortBy(project.issue_types, "order")
@scope.issueStatusList = _.sortBy(project.issue_statuses, "order")
@scope.prioritiesList = _.sortBy(project.priorities, "order")
@scope.severitiesList = _.sortBy(project.severities, "order")
@scope.$emit('project:loaded', project)
return project @scope.projectTags = _.map @scope.project.tags, (it) =>
return [it, @scope.project.tags_colors[it]]
return project
loadInitialData: -> loadInitialData: ->
return @q.all([ @.loadProject()
@.loadProject(),
@tgAuth.refresh() return @tgAuth.refresh()
])
openDeleteLightbox: -> openDeleteLightbox: ->
@rootscope.$broadcast("deletelightbox:new", @scope.project) @rootscope.$broadcast("deletelightbox:new", @scope.project)
@ -158,9 +161,9 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
}) })
$location.path(newUrl) $location.path(newUrl)
$ctrl.loadInitialData() projectService.fetchProject().then () =>
$ctrl.loadInitialData()
projectService.fetchProject()
currentUserService.loadProjects() currentUserService.loadProjects()
promise.then null, (data) -> promise.then null, (data) ->

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -53,36 +53,36 @@ class ProjectValuesSectionController extends mixOf(taiga.Controller, taiga.PageM
"$tgNavUrls", "$tgNavUrls",
"tgAppMetaService", "tgAppMetaService",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
@appMetaService, @translate, @errorHandlingService) -> @appMetaService, @translate, @errorHandlingService, @projectService) ->
@scope.project = {} @scope.project = {}
promise = @.loadInitialData() @.loadInitialData()
promise.then () => sectionName = @translate.instant(@scope.sectionName)
sectionName = @translate.instant(@scope.sectionName)
title = @translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", { title = @translate.instant("ADMIN.PROJECT_VALUES.PAGE_TITLE", {
"sectionName": sectionName, "sectionName": sectionName,
"projectName": @scope.project.name "projectName": @scope.project.name
}) })
description = @scope.project.description
@appMetaService.setAll(title, description)
promise.then null, @.onInitialDataError.bind(@) description = @scope.project.description
@appMetaService.setAll(title, description)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.i_am_admin
@scope.project = project @errorHandlingService.permissionDenied()
@scope.$emit('project:loaded', project)
return project @scope.projectId = project.id
@scope.project = project
@scope.$emit('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() promise = @.loadProject()
@ -106,8 +106,11 @@ class ProjectValuesController extends taiga.Controller
constructor: (@scope, @rootscope, @repo, @confirm, @rs) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs) ->
@scope.$on("admin:project-values:move", @.moveValue) @scope.$on("admin:project-values:move", @.moveValue)
@rootscope.$on("project:loaded", @.loadValues)
unwatch = @scope.$watch "resource", (resource) =>
if resource
@.loadValues()
unwatch()
loadValues: => loadValues: =>
return @rs[@scope.resource].listValues(@scope.projectId, @scope.type).then (values) => return @rs[@scope.resource].listValues(@scope.projectId, @scope.type).then (values) =>
@scope.values = values @scope.values = values
@ -131,7 +134,7 @@ module.controller("ProjectValuesController", ProjectValuesController)
## Project values directive ## Project values directive
############################################################################# #############################################################################
ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame, $translate, $rootscope) -> ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame, $translate, $rootscope, projectService) ->
## Drag & Drop Link ## Drag & Drop Link
linkDragAndDrop = ($scope, $el, $attrs) -> linkDragAndDrop = ($scope, $el, $attrs) ->
@ -211,6 +214,8 @@ ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame, $tra
row.addClass("hidden") row.addClass("hidden")
row.siblings(".visualization").removeClass('hidden') row.siblings(".visualization").removeClass('hidden')
projectService.fetchProject()
promise.then null, (data) -> promise.then null, (data) ->
form.setErrors(data) form.setErrors(data)
@ -325,7 +330,7 @@ ProjectValuesDirective = ($log, $repo, $confirm, $location, animationFrame, $tra
return {link:link} return {link:link}
module.directive("tgProjectValues", ["$log", "$tgRepo", "$tgConfirm", "$tgLocation", "animationFrame", module.directive("tgProjectValues", ["$log", "$tgRepo", "$tgConfirm", "$tgLocation", "animationFrame",
"$translate", "$rootScope", ProjectValuesDirective]) "$translate", "$rootScope", "tgProjectService", ProjectValuesDirective])
############################################################################# #############################################################################
@ -403,6 +408,7 @@ module.directive("tgColorSelection", ColorSelectionDirective)
# Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py) # Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py)
TEXT_TYPE = "text" TEXT_TYPE = "text"
MULTILINE_TYPE = "multiline" MULTILINE_TYPE = "multiline"
RICHTEXT_TYPE = "richtext"
DATE_TYPE = "date" DATE_TYPE = "date"
URL_TYPE = "url" URL_TYPE = "url"
@ -416,6 +422,10 @@ TYPE_CHOICES = [
key: MULTILINE_TYPE, key: MULTILINE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI" name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI"
}, },
{
key: RICHTEXT_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_RICHTEXT"
},
{ {
key: DATE_TYPE, key: DATE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE" name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE"
@ -437,26 +447,28 @@ class ProjectCustomAttributesController extends mixOf(taiga.Controller, taiga.Pa
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appMetaService, constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appMetaService,
@translate) -> @translate, @projectService) ->
@scope.TYPE_CHOICES = TYPE_CHOICES @scope.TYPE_CHOICES = TYPE_CHOICES
@scope.project = @projectService.project.toJS()
@scope.projectId = @scope.project.id
@scope.project = {} sectionName = @translate.instant(@scope.sectionName)
title = @translate.instant("ADMIN.CUSTOM_ATTRIBUTES.PAGE_TITLE", {
"sectionName": sectionName,
"projectName": @scope.project.name
})
description = @scope.project.description
@appMetaService.setAll(title, description)
@rootscope.$on "project:loaded", => @scope.init = (type) =>
@scope.type = type
@.loadCustomAttributes() @.loadCustomAttributes()
sectionName = @translate.instant(@scope.sectionName)
title = @translate.instant("ADMIN.CUSTOM_ATTRIBUTES.PAGE_TITLE", {
"sectionName": sectionName,
"projectName": @scope.project.name
})
description = @scope.project.description
@appMetaService.setAll(title, description)
######################### #########################
# Custom Attribute # Custom Attribute
######################### #########################
@ -716,22 +728,26 @@ class ProjectTagsController extends taiga.Controller
"$tgConfirm", "$tgConfirm",
"$tgResources", "$tgResources",
"$tgModel", "$tgModel",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @model) -> constructor: (@scope, @rootscope, @repo, @confirm, @rs, @model, @projectService) ->
@.loading = true @.loading = true
@rootscope.$on("project:loaded", @.loadTags) @.loadTags()
loadTags: => loadTags: =>
return @rs.projects.tagsColors(@scope.projectId).then (tags) => project = @projectService.project.toJS()
return @rs.projects.tagsColors(project.id).then (tags) =>
@scope.projectTagsAll = _.map tags.getAttrs(), (color, name) => @scope.projectTagsAll = _.map tags.getAttrs(), (color, name) =>
@model.make_model('tag', {name: name, color: color}) @model.make_model('tag', {name: name, color: color})
@.filterAndSortTags() @.filterAndSortTags()
@.loading = false @.loading = false
filterAndSortTags: => filterAndSortTags: =>
@scope.projectTags = _.sortBy @scope.projectTagsAll, (it) -> it.name.toLowerCase()
@scope.projectTags = _.filter( @scope.projectTags = _.filter(
_.sortBy(@scope.projectTagsAll, "name"), @scope.projectTags,
(tag) => tag.name.indexOf(@scope.tagsFilter.name) != -1 (tag) => tag.name.indexOf(@scope.tagsFilter.name) != -1
) )

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -47,13 +47,15 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
"$q", "$q",
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$tgModel",
"tgAppMetaService", "tgAppMetaService",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @navUrls,
@appMetaService, @translate, @errorHandlingService) -> @model, @appMetaService, @translate, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "ADMIN.MENU.PERMISSIONS" @scope.sectionName = "ADMIN.MENU.PERMISSIONS"
@ -70,17 +72,19 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin project = @model.make_model("projects", project)
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.i_am_admin
@scope.project = project @errorHandlingService.permissionDenied()
@scope.$emit('project:loaded', project) @scope.projectId = project.id
@scope.anyComputableRole = _.some(_.map(project.roles, (point) -> point.computable)) @scope.project = project
return project @scope.$emit('project:loaded', project)
@scope.anyComputableRole = _.some(_.map(project.roles, (point) -> point.computable))
return project
loadRoles: -> loadRoles: ->
return @rs.roles.list(@scope.projectId).then (roles) => return @rs.roles.list(@scope.projectId).then (roles) =>
@ -103,9 +107,12 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
return roles return roles
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadRoles()) return @.loadRoles()
return promise
forceLoadProject: () ->
@projectService.fetchProject () =>
@.loadProject()
setRole: (role) -> setRole: (role) ->
@scope.role = role @scope.role = role
@ -126,7 +133,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
warning = @translate.instant("ADMIN.ROLES.WARNING_DELETE_ROLE") warning = @translate.instant("ADMIN.ROLES.WARNING_DELETE_ROLE")
return @confirm.askChoice(title, subtitle, choices, replacement, warning).then (response) => return @confirm.askChoice(title, subtitle, choices, replacement, warning).then (response) =>
onSuccess = => onSuccess = =>
@.loadProject() @.forceLoadProject()
@.loadRoles().finally => @.loadRoles().finally =>
response.finish() response.finish()
onError = => onError = =>
@ -137,7 +144,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
_enableComputable: => _enableComputable: =>
onSuccess = => onSuccess = =>
@confirm.notify("success") @confirm.notify("success")
@.loadProject() @.forceLoadProject()
onError = => onError = =>
@confirm.notify("error") @confirm.notify("error")
@ -150,7 +157,7 @@ class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fil
onSuccess = => onSuccess = =>
response.finish() response.finish()
@confirm.notify("success") @confirm.notify("success")
@.loadProject() @.forceLoadProject()
onError = => onError = =>
response.finish() response.finish()
@confirm.notify("error") @confirm.notify("error")
@ -264,7 +271,7 @@ NewRoleDirective = ($tgrepo, $confirm) ->
$scope.roles.splice(insertPosition, 0, role) $scope.roles.splice(insertPosition, 0, role)
$ctrl.setRole(role) $ctrl.setRole(role)
$el.find(".add-button").show() $el.find(".add-button").show()
$ctrl.loadProject() $ctrl.forceLoadProject()
onError = -> onError = ->
$confirm.notify("error") $confirm.notify("error")
@ -474,7 +481,7 @@ RolePermissionsDirective = ($rootscope, $repo, $confirm, $compile) ->
renderResume(target.parents(".category-config"), categories[categoryId]) renderResume(target.parents(".category-config"), categories[categoryId])
$rootscope.$broadcast("projects:reload") $rootscope.$broadcast("projects:reload")
$confirm.notify("success") $confirm.notify("success")
$ctrl.loadProject() $ctrl.forceLoadProject()
onError = -> onError = ->
$confirm.notify("error") $confirm.notify("error")

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -46,10 +46,11 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
"$tgNavUrls", "$tgNavUrls",
"tgAppMetaService", "tgAppMetaService",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appMetaService, @translate, @errorHandlingService) -> constructor: (@scope, @repo, @rs, @params, @location, @navUrls, @appMetaService, @translate, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME" @scope.sectionName = "ADMIN.WEBHOOKS.SECTION_NAME"
@ -71,21 +72,20 @@ class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.
@scope.webhooks = webhooks @scope.webhooks = webhooks
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.i_am_admin
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.i_am_admin
@scope.project = project @errorHandlingService.permissionDenied()
@scope.$emit('project:loaded', project)
return project @scope.projectId = project.id
@scope.project = project
@scope.$emit('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then =>
@.loadWebhooks()
return promise return @.loadWebhooks()
module.controller("WebhooksController", WebhooksController) module.controller("WebhooksController", WebhooksController)
@ -309,10 +309,11 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME") @scope.sectionName = @translate.instant("ADMIN.GITHUB.SECTION_NAME")
@ -332,16 +333,16 @@ class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.github = github @scope.github = github
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.$emit('project:loaded', project) @scope.project = project
return project @scope.$emit('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() promise = @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("GithubController", GithubController) module.controller("GithubController", GithubController)
@ -357,10 +358,11 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.GITLAB.SECTION_NAME") @scope.sectionName = @translate.instant("ADMIN.GITLAB.SECTION_NAME")
@ -382,16 +384,16 @@ class GitlabController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.gitlab = gitlab @scope.gitlab = gitlab
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.$emit('project:loaded', project) @scope.project = project
return project @scope.$emit('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("GitlabController", GitlabController) module.controller("GitlabController", GitlabController)
@ -407,10 +409,11 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME") @scope.sectionName = @translate.instant("ADMIN.BITBUCKET.SECTION_NAME")
@ -432,16 +435,16 @@ class BitbucketController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
@scope.bitbucket = bitbucket @scope.bitbucket = bitbucket
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.$emit('project:loaded', project) @scope.project = project
return project @scope.$emit('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("BitbucketController", BitbucketController) module.controller("BitbucketController", BitbucketController)
@ -598,10 +601,11 @@ class GogsController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Filt
"$tgResources", "$tgResources",
"$routeParams", "$routeParams",
"tgAppMetaService", "tgAppMetaService",
"$translate" "$translate",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate) -> constructor: (@scope, @repo, @rs, @params, @appMetaService, @translate, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = @translate.instant("ADMIN.GOGS.SECTION_NAME") @scope.sectionName = @translate.instant("ADMIN.GOGS.SECTION_NAME")
@ -621,15 +625,15 @@ class GogsController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Filt
@scope.gogs = gogs @scope.gogs = gogs
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.$emit('project:loaded', project) @scope.project = project
return project @scope.$emit('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() @.loadProject()
promise.then(=> @.loadModules()) return @.loadModules()
return promise
module.controller("GogsController", GogsController) module.controller("GogsController", GogsController)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -105,6 +105,7 @@ class AuthService extends taiga.Service
return @rootscope.user return @rootscope.user
userData = @storage.get("userInfo") userData = @storage.get("userInfo")
if userData if userData
user = @model.make_model("users", userData) user = @model.make_model("users", userData)
@rootscope.user = user @rootscope.user = user
@ -205,9 +206,6 @@ class AuthService extends taiga.Service
acceptInvitiationWithNewUser: (data) -> acceptInvitiationWithNewUser: (data) ->
return @.register(data, "private", false) return @.register(data, "private", false)
acceptInvitiationWithExistingUser: (data) ->
return @.register(data, "private", true)
forgotPassword: (data) -> forgotPassword: (data) ->
url = @urls.resolve("users-password-recovery") url = @urls.resolve("users-password-recovery")
data = _.clone(data, false) data = _.clone(data, false)
@ -478,7 +476,7 @@ module.directive("tgChangePasswordFromRecovery", ["$tgAuth", "$tgConfirm", "$tgL
## Invitation ## Invitation
############################################################################# #############################################################################
InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics, $translate, config) -> InvitationDirective = ($auth, $confirm, $location, $config, $params, $navUrls, $analytics, $translate, config) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
token = $params.token token = $params.token
@ -515,7 +513,14 @@ InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics
if not loginForm.validate() if not loginForm.validate()
return return
promise = $auth.acceptInvitiationWithExistingUser($scope.dataLogin) loginFormType = $config.get("loginFormType", "normal")
data = $scope.dataLogin
promise = $auth.login({
username: data.username,
password: data.password,
invitation_token: data.token
}, loginFormType)
promise.then(onSuccessSubmitLogin, onErrorSubmitLogin) promise.then(onSuccessSubmitLogin, onErrorSubmitLogin)
$el.on "submit", "form.login-form", submitLogin $el.on "submit", "form.login-form", submitLogin
@ -555,7 +560,7 @@ InvitationDirective = ($auth, $confirm, $location, $params, $navUrls, $analytics
return {link:link} return {link:link}
module.directive("tgInvitation", ["$tgAuth", "$tgConfirm", "$tgLocation", "$routeParams", module.directive("tgInvitation", ["$tgAuth", "$tgConfirm", "$tgLocation", "$tgConfig", "$routeParams",
"$tgNavUrls", "$tgAnalytics", "$translate", "$tgConfig", InvitationDirective]) "$tgNavUrls", "$tgAnalytics", "$translate", "$tgConfig", InvitationDirective])

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -38,6 +38,7 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading,
createSprint = true createSprint = true
form = null form = null
$scope.newSprint = {} $scope.newSprint = {}
ussToAdd = null
resetSprint = () -> resetSprint = () ->
form.reset() if form form.reset() if form
@ -97,7 +98,10 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading,
else else
return it return it
$rootscope.$broadcast(broadcastEvent, data) if broadcastEvent == "sprintform:create:success" && ussToAdd
$rootscope.$broadcast(broadcastEvent, data, ussToAdd)
else
$rootscope.$broadcast(broadcastEvent, data)
lightboxService.close($el) lightboxService.close($el)
@ -135,7 +139,8 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading,
return sortedSprints[sortedSprints.length - 1] return sortedSprints[sortedSprints.length - 1]
$scope.$on "sprintform:create", (event, projectId) -> $scope.$on "sprintform:create", (event, projectId, uss) ->
ussToAdd = uss
resetSprint() resetSprint()
form = $el.find("form").checksley() form = $el.find("form").checksley()

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -59,7 +59,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService", "tgErrorHandlingService",
"$tgStorage", "$tgStorage",
"tgFilterRemoteStorageService" "tgFilterRemoteStorageService",
"tgProjectService"
] ]
storeCustomFiltersName: 'backlog-custom-filters' storeCustomFiltersName: 'backlog-custom-filters'
@ -69,7 +70,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @appMetaService, @navUrls, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @appMetaService, @navUrls,
@events, @analytics, @translate, @loading, @rs2, @modelTransform, @errorHandlingService, @events, @analytics, @translate, @loading, @rs2, @modelTransform, @errorHandlingService,
@storage, @filterRemoteStorageService) -> @storage, @filterRemoteStorageService, @projectService) ->
bindMethods(@) bindMethods(@)
@.backlogOrder = {} @.backlogOrder = {}
@ -86,6 +87,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@showTags = false @showTags = false
@activeFilters = false @activeFilters = false
@scope.showGraphPlaceholder = null @scope.showGraphPlaceholder = null
@displayVelocity = false
@.initializeEventHandlers() @.initializeEventHandlers()
@ -120,8 +122,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@confirm.notify("success") @confirm.notify("success")
@analytics.trackEvent("userstory", "create", "bulk create userstory on backlog", 1) @analytics.trackEvent("userstory", "create", "bulk create userstory on backlog", 1)
@scope.$on "sprintform:create:success", => @scope.$on "sprintform:create:success", (e, data, ussToMove) =>
@.loadSprints() @.loadSprints().then () =>
@scope.$broadcast("sprintform:create:success:callback", ussToMove)
@.loadProjectStats() @.loadProjectStats()
@confirm.notify("success") @confirm.notify("success")
@analytics.trackEvent("sprint", "create", "create sprint on backlog", 1) @analytics.trackEvent("sprint", "create", "create sprint on backlog", 1)
@ -181,6 +185,17 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
toggleActiveFilters: -> toggleActiveFilters: ->
@activeFilters = !@activeFilters @activeFilters = !@activeFilters
toggleVelocityForecasting: ->
@displayVelocity = !@displayVelocity
if !@displayVelocity
@scope.visibleUserStories = _.map @scope.userstories, (it) ->
return it.ref
else
@scope.visibleUserStories = _.map @.forecastedStories, (it) ->
return it.ref
scopeDefer @scope, =>
@scope.$broadcast("userstories:loaded")
loadProjectStats: -> loadProjectStats: ->
return @rs.projects.stats(@scope.projectId).then (stats) => return @rs.projects.stats(@scope.projectId).then (stats) =>
@scope.stats = stats @scope.stats = stats
@ -192,6 +207,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@scope.stats.completedPercentage = 0 @scope.stats.completedPercentage = 0
@scope.showGraphPlaceholder = !(stats.total_points? && stats.total_milestones?) @scope.showGraphPlaceholder = !(stats.total_points? && stats.total_milestones?)
@.calculateForecasting()
return stats return stats
setMilestonesOrder: (sprints) -> setMilestonesOrder: (sprints) ->
@ -275,6 +291,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
promise = @rs.userstories.listUnassigned(@scope.projectId, params, pageSize) promise = @rs.userstories.listUnassigned(@scope.projectId, params, pageSize)
return promise.then (result) => return promise.then (result) =>
userstories = result[0] userstories = result[0]
header = result[1] header = result[1]
@ -283,6 +300,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
# NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files # NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files
@scope.userstories = @scope.userstories.concat(_.sortBy(userstories, "backlog_order")) @scope.userstories = @scope.userstories.concat(_.sortBy(userstories, "backlog_order"))
@scope.visibleUserStories = _.map @scope.userstories, (it) ->
return it.ref
for it in @scope.userstories for it in @scope.userstories
@.backlogOrder[it.id] = it.backlog_order @.backlogOrder[it.id] = it.backlog_order
@ -305,31 +324,47 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@.loadProjectStats(), @.loadProjectStats(),
@.loadSprints(), @.loadSprints(),
@.loadUserstories() @.loadUserstories()
]) ]).then(@.calculateForecasting)
calculateForecasting: ->
stats = @scope.stats
total_points = stats.total_points
current_sum = stats.assigned_points
backlog_points_sum = 0
@forecastedStories = []
for us in @scope.userstories
current_sum += us.total_points
backlog_points_sum += us.total_points
@forecastedStories.push(us)
if stats.speed > 0 && backlog_points_sum > stats.speed
break
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_backlog_activated
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.is_backlog_activated
@scope.project = project @errorHandlingService.permissionDenied()
@scope.closedMilestones = !!project.total_closed_milestones
@scope.$emit('project:loaded', project) @scope.projectId = project.id
@scope.points = _.sortBy(project.points, "order") @scope.project = project
@scope.pointsById = groupBy(project.points, (x) -> x.id) @scope.closedMilestones = !!project.total_closed_milestones
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) @scope.$emit('project:loaded', project)
@scope.usStatusList = _.sortBy(project.us_statuses, "id") @scope.points = _.sortBy(project.points, "order")
return project @scope.pointsById = groupBy(project.points, (x) -> x.id)
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id)
@scope.usStatusList = _.sortBy(project.us_statuses, "id")
return project
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription()
return promise @.fillUsersAndRoles(project.members, project.roles)
.then(=> @.loadBacklog()) @.initializeSubscription()
return @.loadBacklog()
.then(=> @.generateFilters()) .then(=> @.generateFilters())
.then(=> @scope.$emit("backlog:loaded")) .then(=> @scope.$emit("backlog:loaded"))
@ -545,7 +580,7 @@ module.controller("BacklogController", BacklogController)
## Backlog Directive ## Backlog Directive
############################################################################# #############################################################################
BacklogDirective = ($repo, $rootscope, $translate) -> BacklogDirective = ($repo, $rootscope, $translate, $rs) ->
## Doom line Link ## Doom line Link
doomLineTemplate = _.template(""" doomLineTemplate = _.template("""
<div class="doom-line"><span><%- text %></span></div> <div class="doom-line"><span><%- text %></span></div>
@ -553,11 +588,13 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
linkDoomLine = ($scope, $el, $attrs, $ctrl) -> linkDoomLine = ($scope, $el, $attrs, $ctrl) ->
reloadDoomLine = -> reloadDoomLine = ->
if $scope.stats? and $scope.stats.total_points? and $scope.stats.total_points != 0 if $scope.displayVelocity
removeDoomlineDom()
if $scope.stats? and $scope.stats.total_points? and $scope.stats.total_points != 0 and !$scope.displayVelocity?
removeDoomlineDom() removeDoomlineDom()
stats = $scope.stats stats = $scope.stats
total_points = stats.total_points total_points = stats.total_points
current_sum = stats.assigned_points current_sum = stats.assigned_points
@ -584,6 +621,7 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
return _.map(rowElements, (x) -> angular.element(x)) return _.map(rowElements, (x) -> angular.element(x))
$scope.$on("userstories:loaded", reloadDoomLine) $scope.$on("userstories:loaded", reloadDoomLine)
$scope.$on("userstories:forecast", removeDoomlineDom)
$scope.$watch("stats", reloadDoomLine) $scope.$watch("stats", reloadDoomLine)
## Move to current sprint link ## Move to current sprint link
@ -614,9 +652,11 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
# Update the total of points # Update the total of points
sprint.total_points += totalExtraPoints sprint.total_points += totalExtraPoints
$repo.saveAll(selectedUss).then -> $rs.userstories.bulkUpdateMilestone($scope.project.id, $scope.sprints[0].id, selectedUss).then =>
$ctrl.loadSprints() $ctrl.loadSprints()
$ctrl.loadProjectStats() $ctrl.loadProjectStats()
$ctrl.toggleVelocityForecasting()
$ctrl.calculateForecasting()
$el.find(".move-to-sprint").hide() $el.find(".move-to-sprint").hide()
@ -626,6 +666,9 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
moveToLatestSprint = (selectedUss) -> moveToLatestSprint = (selectedUss) ->
moveUssToSprint(selectedUss, $scope.sprints[0]) moveUssToSprint(selectedUss, $scope.sprints[0])
$scope.$on "sprintform:create:success:callback", (e, ussToMove) ->
_.partial(moveToCurrentSprint, ussToMove)()
shiftPressed = false shiftPressed = false
lastChecked = null lastChecked = null
@ -640,6 +683,7 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
else else
moveToSprintDom.hide() moveToSprintDom.hide()
$(window).on "keydown.shift-pressed keyup.shift-pressed", (event) -> $(window).on "keydown.shift-pressed keyup.shift-pressed", (event) ->
shiftPressed = !!event.shiftKey shiftPressed = !!event.shiftKey
@ -685,6 +729,22 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
showHideTags($ctrl) showHideTags($ctrl)
$el.on "click", ".forecasting-add-sprint", (event) ->
ussToMoveList = $ctrl.forecastedStories
if $scope.currentSprint
ussToMove = _.map ussToMoveList, (us, index) ->
us.milestone = $scope.currentSprint.id
us.order = index
return us
$scope.$apply(_.partial(moveToCurrentSprint, ussToMove))
else
ussToMove = _.map ussToMoveList, (us, index) ->
us.order = index
return us
$rootscope.$broadcast("sprintform:create", $scope.projectId, ussToMove)
showHideTags = ($ctrl) -> showHideTags = ($ctrl) ->
elm = angular.element("#show-tags") elm = angular.element("#show-tags")
@ -759,7 +819,7 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
return {link: link} return {link: link}
module.directive("tgBacklog", ["$tgRepo", "$rootScope", "$translate", BacklogDirective]) module.directive("tgBacklog", ["$tgRepo", "$rootScope", "$translate", "$tgResources", BacklogDirective])
############################################################################# #############################################################################
## User story points directive ## User story points directive

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -62,7 +62,12 @@ urls = {
"cancel-account": "/cancel-account/:token" "cancel-account": "/cancel-account/:token"
"register": "/register" "register": "/register"
"invitation": "/invitation/:token" "invitation": "/invitation/:token"
"create-project": "/create-project" "create-project": "/project/new"
"create-project-scrum": "/project/new/scrum"
"create-project-kanban": "/project/new/kanban"
"create-project-duplicate": "/project/new/duplicate"
"create-project-import": "/project/new/import"
"create-project-import-platform": "/project/new/import/:platform"
"profile": "/profile" "profile": "/profile"
"user-profile": "/profile/:username" "user-profile": "/profile/:username"

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -32,25 +32,24 @@ class ContribController extends taiga.Controller
"$routeParams", "$routeParams",
"$tgRepo", "$tgRepo",
"$tgResources", "$tgResources",
"$tgConfirm" "$tgConfirm",
"tgProjectService"
] ]
constructor: (@rootScope, @scope, @params, @repo, @rs, @confirm) -> constructor: (@rootScope, @scope, @params, @repo, @rs, @confirm, @projectService) ->
@scope.currentPlugin = _.head(_.filter(@rootScope.adminPlugins, {"slug": @params.plugin})) @scope.currentPlugin = _.head(_.filter(@rootScope.adminPlugins, {"slug": @params.plugin}))
@scope.projectSlug = @params.pslug @scope.projectSlug = @params.pslug
promise = @.loadInitialData() @.loadInitialData()
promise.then null, =>
@confirm.notify("error")
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.$emit('project:loaded', project) @scope.project = project
@scope.$broadcast('project:loaded', project) @scope.$emit('project:loaded', project)
return project @scope.$broadcast('project:loaded', project)
return project
loadInitialData: -> loadInitialData: ->
return @.loadProject() return @.loadProject()

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -39,7 +39,7 @@ class Model
instance._modifiedAttrs = _.cloneDeep(@._modifiedAttrs) instance._modifiedAttrs = _.cloneDeep(@._modifiedAttrs)
instance._isModified = _.cloneDeep(@._isModified) instance._isModified = _.cloneDeep(@._isModified)
return instance return instance
clone: -> clone: ->
instance = new Model(@._name, @._attrs, @._dataTypes) instance = new Model(@._name, @._attrs, @._dataTypes)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -216,6 +216,9 @@ module.directive("tgToggleComment", ToggleCommentDirective)
ProjectUrl = ($navurls) -> ProjectUrl = ($navurls) ->
get = (project) -> get = (project) ->
if project.toJS
project = project.toJS()
ctx = {project: project.slug} ctx = {project: project.slug}
if project.is_backlog_activated and project.my_permissions.indexOf("view_us") > -1 if project.is_backlog_activated and project.my_permissions.indexOf("view_us") > -1
@ -353,12 +356,18 @@ module.directive("tgCapslock", [Capslock])
LightboxClose = () -> LightboxClose = () ->
template = """ template = """
<a class="close" href="" title="{{'COMMON.CLOSE' | translate}}"> <a class="close" ng-click="onClose()" href="" title="{{'COMMON.CLOSE' | translate}}">
<tg-svg svg-icon="icon-close"></tg-svg> <tg-svg svg-icon="icon-close"></tg-svg>
</a> </a>
""" """
link = (scope, elm, attrs) ->
return { return {
scope: {
onClose: '&'
},
link: link,
template: template template: template
} }
@ -369,11 +378,7 @@ Svg = () ->
<svg class="{{ 'icon ' + svgIcon }}"> <svg class="{{ 'icon ' + svgIcon }}">
<use xlink:href="" ng-attr-xlink:href="{{ '#' + svgIcon }}"> <use xlink:href="" ng-attr-xlink:href="{{ '#' + svgIcon }}">
<title ng-if="svgTitle">{{svgTitle}}</title> <title ng-if="svgTitle">{{svgTitle}}</title>
<title <title ng-if="svgTitleTranslate">{{svgTitleTranslate | translate: svgTitleTranslateValues}}</title>
ng-if="svgTitleTranslate"
translate="{{svgTitleTranslate}}"
translate-values="{{svgTitleTranslateValues}}"
></title>
</use> </use>
</svg> </svg>
""" """
@ -390,14 +395,22 @@ Svg = () ->
module.directive("tgSvg", [Svg]) module.directive("tgSvg", [Svg])
Autofocus = ($timeout) -> Autofocus = ($timeout, $parse, animationFrame) ->
return { return {
restrict: 'A', restrict: 'A',
link : ($scope, $element) -> link : ($scope, $element, attrs) ->
$timeout -> $element[0].focus() if attrs.ngShow
model = $parse(attrs.ngShow)
$scope.$watch model, (value) ->
if value == true
$timeout () -> $element[0].focus()
else
$timeout () -> $element[0].focus()
} }
module.directive('tgAutofocus', ['$timeout', Autofocus]) module.directive('tgAutofocus', ['$timeout', '$parse', "animationFrame", Autofocus])
module.directive 'tgPreloadImage', () -> module.directive 'tgPreloadImage', () ->
spinner = "<img class='loading-spinner' src='/" + window._version + "/svg/spinner-circle.svg' alt='loading...' />" spinner = "<img class='loading-spinner' src='/" + window._version + "/svg/spinner-circle.svg' alt='loading...' />"

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,5 +1,5 @@
### ###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io> # Copyright (C) 2014-2017 Taiga Agile LLC <taiga@taiga.io>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,5 +1,5 @@
### ###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io> # Copyright (C) 2014-2017 Taiga Agile LLC <taiga@taiga.io>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -496,40 +496,37 @@ DeleteButtonDirective = ($log, $repo, $confirm, $location, $template) ->
module.directive("tgDeleteButton", ["$log", "$tgRepo", "$tgConfirm", "$tgLocation", "$tgTemplate", DeleteButtonDirective]) module.directive("tgDeleteButton", ["$log", "$tgRepo", "$tgConfirm", "$tgLocation", "$tgTemplate", DeleteButtonDirective])
############################################################################# #############################################################################
## Editable description directive ## Editable subject directive
############################################################################# #############################################################################
EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, $selectedText, $modelTransform, $template, $translate) -> EditableSubjectDirective = ($rootscope, $repo, $confirm, $loading, $modelTransform, $template) ->
template = $template.get("common/components/editable-description.html") template = $template.get("common/components/editable-subject.html")
noDescriptionMegEditMode = $template.get("common/components/editable-description-msg-edit-mode.html")
noDescriptionMegReadMode = $template.get("common/components/editable-description-msg-read-mode.html")
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
$el.find('.edit-description').hide()
$el.find('.view-description .edit').hide()
$scope.$on "object:updated", () -> $scope.$on "object:updated", () ->
$el.find('.edit-description').hide() $el.find('.edit-subject').hide()
$el.find('.view-description').show() $el.find('.view-subject').show()
isEditable = -> isEditable = ->
return $scope.project.my_permissions.indexOf($attrs.requiredPerm) != -1 return $scope.project.my_permissions.indexOf($attrs.requiredPerm) != -1
save = (description) -> save = (subject) ->
currentLoading = $loading() currentLoading = $loading()
.target($el.find('.save-container')) .target($el.find('.save-container'))
.start() .start()
transform = $modelTransform.save (item) -> transform = $modelTransform.save (item) ->
item.description = description
item.subject = subject
return item return item
transform.then -> transform.then =>
$confirm.notify("success") $confirm.notify("success")
$rootscope.$broadcast("object:updated") $rootscope.$broadcast("object:updated")
$el.find('.edit-description').hide() $el.find('.edit-subject').hide()
$el.find('.view-description').show() $el.find('.view-subject').show()
transform.then null, -> transform.then null, ->
$confirm.notify("error") $confirm.notify("error")
@ -537,60 +534,43 @@ EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading,
transform.finally -> transform.finally ->
currentLoading.finish() currentLoading.finish()
cancelEdition = () -> return transform
$scope.item.revert()
$el.find('.edit-description').hide()
$el.find('.view-description').show()
$el.on "mouseup", ".view-description", (event) -> $el.click ->
# We want to dettect the a inside the div so we use the target and
# not the currentTarget
target = angular.element(event.target)
return if not isEditable() return if not isEditable()
return if target.is('a') $el.find('.edit-subject').show()
return if $selectedText.get().length $el.find('.view-subject').hide()
$el.find('input').focus()
$el.find('.edit-description').show()
$el.find('.view-description').hide()
$el.find('textarea').focus()
$el.on "click", "a", (event) ->
target = angular.element(event.target)
href = target.attr('href')
if href.indexOf("#") == 0
event.preventDefault()
$('body').scrollTop($(href).offset().top)
$el.on "click", ".save", (e) -> $el.on "click", ".save", (e) ->
e.preventDefault() e.preventDefault()
description = $scope.item.description subject = $scope.item.subject
save(description) save(subject)
$el.on "keydown", "textarea", (event) -> $el.on "keyup", "input", (event) ->
return if event.keyCode != 27 if event.keyCode == 13
subject = $scope.item.subject
save(subject)
else if event.keyCode == 27
$scope.$apply () => $model.$modelValue.revert()
$scope.$applyAsync () -> $el.find('.edit-subject').hide()
title = $translate.instant("COMMON.CONFIRM_CLOSE_EDIT_MODE_TITLE") $el.find('.view-subject').show()
message = $translate.instant("COMMON.CONFIRM_CLOSE_EDIT_MODE_MESSAGE")
$confirm.ask(title, null, message).then (askResponse) -> $el.find('.edit-subject').hide()
cancelEdition()
askResponse.finish()
$scope.$watch $attrs.ngModel, (value) -> $scope.$watch $attrs.ngModel, (value) ->
return if not value return if not value
$scope.item = value $scope.item = value
if isEditable()
$el.find('.view-description .edit').show() if not isEditable()
$el.find('.view-description .us-content').addClass('editable') $el.find('.view-subject .edit').remove()
$scope.noDescriptionMsg = $compile(noDescriptionMegEditMode)($scope)
else
$scope.noDescriptionMsg = $compile(noDescriptionMegReadMode)($scope)
$scope.$on "$destroy", -> $scope.$on "$destroy", ->
$el.off() $el.off()
return { return {
link: link link: link
restrict: "EA" restrict: "EA"
@ -598,81 +578,8 @@ EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading,
template: template template: template
} }
module.directive("tgEditableDescription", [ module.directive("tgEditableSubject", ["$rootScope", "$tgRepo", "$tgConfirm", "$tgLoading", "$tgQueueModelTransformation",
"$rootScope", "$tgTemplate", EditableSubjectDirective])
"$tgRepo",
"$tgConfirm",
"$compile",
"$tgLoading",
"$selectedText",
"$tgQueueModelTransformation",
"$tgTemplate",
"$translate",
EditableDescriptionDirective])
EditableWysiwyg = (attachmentsService, attachmentsFullService) ->
link = ($scope, $el, $attrs, $model) ->
isInEditMode = ->
return $el.find('textarea').is(':visible') and $model.$modelValue.id
uploadFile = (file, type) ->
return if !attachmentsService.validate(file)
return attachmentsFullService.addAttachment($model.$modelValue.project, $model.$modelValue.id, type, file).then (result) ->
if taiga.isImage(result.getIn(['file', 'name']))
return '![' + result.getIn(['file', 'name']) + '](' + result.getIn(['file', 'url']) + ')'
else
return '[' + result.getIn(['file', 'name']) + '](' + result.getIn(['file', 'url']) + ')'
$el.on 'dragover', (e) ->
textarea = $el.find('textarea').focus()
return false
$el.on 'drop', (e) ->
e.stopPropagation()
e.preventDefault()
if isInEditMode()
dataTransfer = e.dataTransfer || (e.originalEvent && e.originalEvent.dataTransfer)
textarea = $el.find('textarea')
textarea.addClass('in-progress')
type = $model.$modelValue['_name']
if type == "userstories"
type = "us"
else if type == "tasks"
type = "task"
else if type == "issues"
type = "issue"
else if type == "wiki"
type = "wiki_page"
promises = _.map dataTransfer.files, (file) ->
return uploadFile(file, type)
Promise.all(promises).then (result) ->
textarea = $el.find('textarea')
$.markItUp({ replaceWith: result.join(' ') })
textarea.removeClass('in-progress')
return {
link: link
restrict: "EA"
require: "ngModel"
}
module.directive("tgEditableWysiwyg", ["tgAttachmentsService", "tgAttachmentsFullService", EditableWysiwyg])
############################################################################# #############################################################################
## Common list directives ## Common list directives

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -207,13 +207,16 @@ class ConfirmService extends taiga.Service
return defered.promise return defered.promise
loader: (title, message) -> loader: (title, message, spin=false) ->
el = angular.element(".lightbox-generic-loading") el = angular.element(".lightbox-generic-loading")
# Render content # Render content
el.find(".title").html(title) if title el.find(".title").html(title) if title
el.find(".message").html(message) if message el.find(".message").html(message) if message
if spin
el.find(".spin").removeClass("hidden")
return { return {
start: => @lightboxService.open(el) start: => @lightboxService.open(el)
stop: => @lightboxService.close(el) stop: => @lightboxService.close(el)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -32,6 +32,7 @@ module = angular.module("taigaCommon")
# Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py) # Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py)
TEXT_TYPE = "text" TEXT_TYPE = "text"
RICHTEXT_TYPE = "url"
MULTILINE_TYPE = "multiline" MULTILINE_TYPE = "multiline"
DATE_TYPE = "date" DATE_TYPE = "date"
URL_TYPE = "url" URL_TYPE = "url"
@ -53,6 +54,10 @@ TYPE_CHOICES = [
{ {
key: URL_TYPE, key: URL_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_URL" name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_URL"
},
{
key: RICHTEXT_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_RICHTEXT"
} }
] ]
@ -193,6 +198,15 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
requiredEditionPerm = $attrs.requiredEditionPerm requiredEditionPerm = $attrs.requiredEditionPerm
return permissions.indexOf(requiredEditionPerm) > -1 return permissions.indexOf(requiredEditionPerm) > -1
$scope.saveCustomRichText = (markdown, callback) =>
attributeValue.value = markdown
$ctrl.updateAttributeValue(attributeValue).then ->
callback()
render(attributeValue, false)
$scope.cancelCustomRichText= () =>
render(attributeValue, false)
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
event.preventDefault() event.preventDefault()
@ -214,6 +228,9 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
# Bootstrap # Bootstrap
attributeValue = $scope.$eval($attrs.tgCustomAttributeValue) attributeValue = $scope.$eval($attrs.tgCustomAttributeValue)
if attributeValue.value == null or attributeValue.value == undefined
attributeValue.value = ""
$scope.customAttributeValue = attributeValue
render(attributeValue) render(attributeValue)
## Actions (on view mode) ## Actions (on view mode)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -75,7 +75,6 @@ sizeFormat = =>
module.filter("sizeFormat", sizeFormat) module.filter("sizeFormat", sizeFormat)
toMutableFilter = -> toMutableFilter = ->
toMutable = (js) -> toMutable = (js) ->
return js.toJS() return js.toJS()
@ -127,3 +126,20 @@ darkerFilter = ->
module.filter("darker", darkerFilter) module.filter("darker", darkerFilter)
markdownToHTML = (wysiwigService) ->
return (input) ->
if input
return wysiwigService.getHTML(input)
return ""
module.filter("markdownToHTML", ["tgWysiwygService", markdownToHTML])
inArray = ($filter) ->
return (list, arrayFilter, element) ->
if arrayFilter
filter = $filter("filter")
return filter list, (listItem) ->
return arrayFilter.indexOf(listItem[element]) != -1
module.filter("inArray", ["$filter", inArray])

View File

@ -1,153 +0,0 @@
###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: modules/common/importer.coffee
###
module = angular.module("taigaCommon")
ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls, $translate, $lightboxFactory, currentUserService, $tgAuth) ->
link = ($scope, $el, $attrs) ->
getRestrictionError = (result) ->
if result.headers
errorKey = ''
user = currentUserService.getUser()
maxMemberships = 0
if result.headers.isPrivate
privateError = !currentUserService.canCreatePrivateProjects().valid
maxMemberships = null
if user.get('max_memberships_private_projects') != null && result.headers.memberships >= user.get('max_memberships_private_projects')
membersError = true
else
membersError = false
if privateError && membersError
errorKey = 'private-space-members'
maxMemberships = user.get('max_memberships_private_projects')
else if privateError
errorKey = 'private-space'
else if membersError
errorKey = 'private-members'
maxMemberships = user.get('max_memberships_private_projects')
else
publicError = !currentUserService.canCreatePublicProjects().valid
if user.get('max_memberships_public_projects') != null && result.headers.memberships >= user.get('max_memberships_public_projects')
membersError = true
else
membersError = false
if publicError && membersError
errorKey = 'public-space-members'
maxMemberships = user.get('max_memberships_public_projects')
else if publicError
errorKey = 'public-space'
else if membersError
errorKey = 'public-members'
maxMemberships = user.get('max_memberships_public_projects')
return {
key: errorKey,
values: {
max_memberships: maxMemberships,
members: result.headers.memberships
}
}
else
return false
$el.on "click", ".import-project-button", (event) ->
event.preventDefault()
$el.find("input.import-file").val("")
$el.find("input.import-file").trigger("click")
$el.on "change", "input.import-file", (event) ->
event.preventDefault()
file = event.target.files[0]
return if not file
loader = $confirm.loader($translate.instant("PROJECT.IMPORT.UPLOADING_FILE"))
onSuccess = (result) ->
currentUserService.loadProjects().then () ->
loader.stop()
if result.status == 202 # Async mode
title = $translate.instant("PROJECT.IMPORT.ASYNC_IN_PROGRESS_TITLE")
message = $translate.instant("PROJECT.IMPORT.ASYNC_IN_PROGRESS_MESSAGE")
$confirm.success(title, message)
else # result.status == 201 # Sync mode
ctx = {project: result.data.slug}
$location.path($navUrls.resolve("project-admin-project-profile-details", ctx))
msg = $translate.instant("PROJECT.IMPORT.SYNC_SUCCESS")
$confirm.notify("success", msg)
onError = (result) ->
$tgAuth.refresh().then () ->
restrictionError = getRestrictionError(result)
loader.stop()
if restrictionError
$lightboxFactory.create('tg-lb-import-error', {
class: 'lightbox lightbox-import-error'
}, restrictionError)
else
errorMsg = $translate.instant("PROJECT.IMPORT.ERROR")
if result.status == 429 # TOO MANY REQUESTS
errorMsg = $translate.instant("PROJECT.IMPORT.ERROR_TOO_MANY_REQUEST")
else if result.data?._error_message
errorMsg = $translate.instant("PROJECT.IMPORT.ERROR_MESSAGE", {error_message: result.data._error_message})
$confirm.notify("error", errorMsg)
loader.start()
$rs.projects.import(file, loader.update).then(onSuccess, onError)
return {link: link}
module.directive("tgImportProjectButton",
["$tgResources", "$tgConfirm", "$location", "$tgNavUrls", "$translate", "tgLightboxFactory", "tgCurrentUserService", "$tgAuth",
ImportProjectButtonDirective])
LbImportErrorDirective = (lightboxService) ->
link = (scope, el, attrs) ->
lightboxService.open(el)
scope.close = () ->
lightboxService.close(el)
return
return {
templateUrl: "common/lightbox/lightbox-import-error.html",
link: link
}
LbImportErrorDirective.$inject = ["lightboxService"]
module.directive("tgLbImportError", LbImportErrorDirective)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -38,7 +38,7 @@ trim = @.taiga.trim
class LightboxService extends taiga.Service class LightboxService extends taiga.Service
constructor: (@animationFrame, @q, @rootScope) -> constructor: (@animationFrame, @q, @rootScope) ->
open: ($el, onClose) -> open: ($el, onClose, onEsc) ->
@.onClose = onClose @.onClose = onClose
if _.isString($el) if _.isString($el)
@ -68,7 +68,12 @@ class LightboxService extends taiga.Service
docEl = angular.element(document) docEl = angular.element(document)
docEl.on "keydown.lightbox", (e) => docEl.on "keydown.lightbox", (e) =>
code = if e.keyCode then e.keyCode else e.which code = if e.keyCode then e.keyCode else e.which
@.close($el) if code == 27 if code == 27
if onEsc
@rootScope.$applyAsync(onEsc)
else
@.close($el)
return defered.promise return defered.promise
@ -171,9 +176,11 @@ module.service("lightboxKeyboardNavigationService", LightboxKeyboardNavigationSe
LightboxDirective = (lightboxService) -> LightboxDirective = (lightboxService) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$el.on "click", ".close", (event) ->
event.preventDefault() if !$attrs.$attr.visible
lightboxService.close($el) $el.on "click", ".close", (event) ->
event.preventDefault()
lightboxService.close($el)
return {restrict: "C", link: link} return {restrict: "C", link: link}
@ -308,6 +315,9 @@ CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService,
attachmentsToAdd = attachmentsToAdd.push(attachment) attachmentsToAdd = attachmentsToAdd.push(attachment)
$scope.deleteAttachment = (attachment) -> $scope.deleteAttachment = (attachment) ->
attachmentsToAdd = attachmentsToAdd.filter (it) ->
return it.get('name') != attachment.get('name')
if attachment.get("id") if attachment.get("id")
attachmentsToDelete = attachmentsToDelete.push(attachment) attachmentsToDelete = attachmentsToDelete.push(attachment)
@ -332,7 +342,7 @@ CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService,
inserted = _.find itemtags, (it) -> it[0] == value inserted = _.find itemtags, (it) -> it[0] == value
if !inserted if !inserted
itemtags.push([tag , color]) itemtags.push([value , color])
$scope.us.tags = itemtags $scope.us.tags = itemtags
$scope.deleteTag = (tag) -> $scope.deleteTag = (tag) ->
@ -610,7 +620,7 @@ AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationServic
ctx = { ctx = {
selected: selected selected: selected
users: _.slice(users, 0, 5) users: _.slice(users, 0, 5)
showMore: visibleUsers showMore: users.length > 5
} }
html = usersTemplate(ctx) html = usersTemplate(ctx)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -92,15 +92,16 @@ Loader = ($rootscope) ->
return { return {
pageLoaded: pageLoaded pageLoaded: pageLoaded
open: () -> open
start: (auto=false) -> start: (auto=false) ->
if !open if !open
start() start()
autoClose() if auto autoClose() if auto
onStart: (fn) -> onStart: (fn) ->
$rootscope.$on("loader:start", fn) return $rootscope.$on("loader:start", fn)
onEnd: (fn) -> onEnd: (fn) ->
$rootscope.$on("loader:end", fn) return $rootscope.$on("loader:end", fn)
logRequest: () -> logRequest: () ->
requestCount++ requestCount++

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,489 +0,0 @@
###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: modules/common/wisiwyg.coffee
###
taiga = @.taiga
bindOnce = @.taiga.bindOnce
module = angular.module("taigaCommon")
# How to test lists (-, *, 1.)
# test it with text after & before the list
# + is the cursor position
# CASE 1
# - aa+
# --> enter
# - aa
# - +
# CASE 1
# - +
# --> enter
# +
# CASE 3
# - bb+cc
# --> enter
# - bb
# - cc
# CASE 3
# +- aa
# --> enter
# - aa
#############################################################################
## WYSIWYG markitup editor directive
#############################################################################
MarkitupDirective = ($rootscope, $rs, $selectedText, $template, $compile, $translate, projectService) ->
previewTemplate = $template.get("common/wysiwyg/wysiwyg-markitup-preview.html", true)
link = ($scope, $el, $attrs, $model) ->
if not $scope.project
# for backward compatibility
$scope.project = projectService.project.toJS()
element = angular.element($el)
previewDomNode = $("<div/>", {class: "preview"})
closePreviewMode = ->
element.parents(".markdown").find(".preview").remove()
element.parents(".markItUp").show()
$scope.$on "markdown-editor:submit", ->
closePreviewMode()
cancelablePromise = null
previewInProgress = false
preview = ->
return if previewInProgress
previewInProgress = true
markdownDomNode = element.parents(".markdown")
markItUpDomNode = element.parents(".markItUp")
$rs.mdrender.render($scope.project.id, $model.$modelValue).then (data) ->
html = previewTemplate({data: data.data})
html = $compile(html)($scope)
markdownDomNode.append(html)
markItUpDomNode.hide()
previewInProgress = false
markdown = element.closest(".markdown")
markdown.on "mouseup.preview", ".preview", (event) ->
event.preventDefault()
target = angular.element(event.target)
if !target.is('a') and $selectedText.get().length
return
markdown.off(".preview")
closePreviewMode()
setCaretPosition = (textarea, caretPosition) ->
if textarea.createTextRange
range = textarea.createTextRange()
range.move("character", caretPosition)
range.select()
else if textarea.selectionStart
textarea.focus()
textarea.setSelectionRange(caretPosition, caretPosition)
# Calculate the scroll position
totalLines = textarea.value.split("\n").length
line = textarea.value[0..(caretPosition - 1)].split("\n").length
scrollRelation = line / totalLines
$el.scrollTop((scrollRelation * $el[0].scrollHeight) - ($el.height() / 2))
addLine = (textarea, nline, replace) ->
lines = textarea.value.split("\n")
if replace
lines[nline] = replace + lines[nline]
else
lines[nline] = ""
cursorPosition = 0
for line, key in lines
cursorPosition += line.length + 1 || 1
break if key == nline
textarea.value = lines.join("\n")
#return the new position
if replace
return cursorPosition - lines[nline].length + replace.length - 1
else
return cursorPosition
prepareUrlFormatting = (markItUp) ->
regex = /(<<<|>>>)/gi
result = 0
indices = []
(indices.push(result.index)) while ( (result = regex.exec(markItUp.textarea.value)) )
markItUp.donotparse = indices
urlFormatting = (markItUp) ->
regex = /<<</gi
result = 0
startIndex = 0
loop
result = regex.exec(markItUp.textarea.value)
break if !result
if result.index not in markItUp.donotparse
startIndex = result.index
break
return if !result
regex = />>>/gi
endIndex = 0
loop
result = regex.exec(markItUp.textarea.value)
break if !result
if result.index not in markItUp.donotparse
endIndex = result.index
break
value = markItUp.textarea.value
url = value.substring(startIndex, endIndex).replace('<<<', '').replace('>>>', '')
url = url.replace('(', '%28').replace(')', '%29')
url = url.replace('[', '%5B').replace(']', '%5D')
value = value.substring(0, startIndex) + url + value.substring(endIndex+3, value.length)
markItUp.textarea.value = value
markItUp.donotparse = undefined
markdownTitle = (markItUp, char) ->
heading = ""
n = $.trim(markItUp.selection or markItUp.placeHolder).length
for i in [0..n-1]
heading += char
return "\n"+heading+"\n"
renderMarkItUp = () ->
markdownSettings =
nameSpace: "markdown"
onShiftEnter: {keepDefault:false, openWith:"\n\n"}
onEnter:
keepDefault: false,
replaceWith: () ->
# Allow textcomplete to intercept the enter key if the options list is displayed
# @todo There doesn't seem to be a more graceful way to do this with the textcomplete API.
if not $('.textcomplete-dropdown').is(':visible')
"\n"
afterInsert: (data) ->
lines = data.textarea.value.split("\n")
# Detect if we are in this situation +- aa at the beginning if the textarea
if data.caretPosition > 0
cursorLine = data.textarea.value[0..(data.caretPosition - 1)].split("\n").length
else
cursorLine = 1
newLineContent = data.textarea.value[data.caretPosition..].split("\n")[0]
lastLine = lines[cursorLine - 1]
# unordered list -
match = lastLine.match /^(\s*- ).*/
if match
emptyListItem = lastLine.match /^(\s*)\-\s$/
if emptyListItem
nline = cursorLine - 1
replace = null
else
nline = cursorLine
replace = "#{match[1]}"
markdownCaretPositon = addLine(data.textarea, nline, replace)
# unordered list *
match = lastLine.match /^(\s*\* ).*/
if match
emptyListItem = lastLine.match /^(\s*\* )$/
if emptyListItem
nline = cursorLine - 1
replace = null
else
nline = cursorLine
replace = "#{match[1]}"
markdownCaretPositon = addLine(data.textarea, nline, replace)
# ordered list
match = lastLine.match /^(\s*)(\d+)\.\s/
if match
emptyListItem = lastLine.match /^(\s*)(\d+)\.\s$/
if emptyListItem
nline = cursorLine - 1
replace = null
else
nline = cursorLine
replace = "#{match[1] + (parseInt(match[2], 10) + 1)}. "
markdownCaretPositon = addLine(data.textarea, nline, replace)
setCaretPosition(data.textarea, markdownCaretPositon) if markdownCaretPositon
markupSet: [
{
name: $translate.instant("COMMON.WYSIWYG.H1_BUTTON")
key: "1"
placeHolder: $translate.instant("COMMON.WYSIWYG.H1_SAMPLE_TEXT")
closeWith: (markItUp) -> markdownTitle(markItUp, "=")
},
{
name: $translate.instant("COMMON.WYSIWYG.H2_BUTTON")
key: "2"
placeHolder: $translate.instant("COMMON.WYSIWYG.H2_SAMPLE_TEXT")
closeWith: (markItUp) -> markdownTitle(markItUp, "-")
},
{
name: $translate.instant("COMMON.WYSIWYG.H3_BUTTON")
key: "3"
openWith: "### "
placeHolder: $translate.instant("COMMON.WYSIWYG.H3_SAMPLE_TEXT")
},
{
separator: "---------------"
},
{
name: $translate.instant("COMMON.WYSIWYG.BOLD_BUTTON")
key: "B"
openWith: "**"
closeWith: "**"
placeHolder: $translate.instant("COMMON.WYSIWYG.BOLD_BUTTON_SAMPLE_TEXT")
},
{
name: $translate.instant("COMMON.WYSIWYG.ITALIC_SAMPLE_TEXT")
key: "I"
openWith: "_"
closeWith: "_"
placeHolder: $translate.instant("COMMON.WYSIWYG.ITALIC_SAMPLE_TEXT")
},
{
name: $translate.instant("COMMON.WYSIWYG.STRIKE_BUTTON")
key: "S"
openWith: "~~"
closeWith: "~~"
placeHolder: $translate.instant("COMMON.WYSIWYG.STRIKE_SAMPLE_TEXT")
},
{
separator: "---------------"
},
{
name: $translate.instant("COMMON.WYSIWYG.BULLETED_LIST_BUTTON")
openWith: "- "
placeHolder: $translate.instant("COMMON.WYSIWYG.BULLETED_LIST_SAMPLE_TEXT")
},
{
name: $translate.instant("COMMON.WYSIWYG.NUMERIC_LIST_BUTTON")
openWith: (markItUp) -> markItUp.line+". "
placeHolder: $translate.instant("COMMON.WYSIWYG.NUMERIC_LIST_SAMPLE_TEXT")
},
{
separator: "---------------"
},
{
name: $translate.instant("COMMON.WYSIWYG.PICTURE_BUTTON")
key: "P"
openWith: "!["
closeWith: '](<<<[![Url:!:http://]!]>>> "[![Title]!]")'
placeHolder: $translate.instant("COMMON.WYSIWYG.PICTURE_SAMPLE_TEXT")
beforeInsert:(markItUp) -> prepareUrlFormatting(markItUp)
afterInsert:(markItUp) -> urlFormatting(markItUp)
},
{
name: $translate.instant("COMMON.WYSIWYG.LINK_BUTTON")
key: "L"
openWith: "["
closeWith: '](<<<[![Url:!:http://]!]>>> "[![Title]!]")'
placeHolder: $translate.instant("COMMON.WYSIWYG.LINK_SAMPLE_TEXT")
beforeInsert:(markItUp) -> prepareUrlFormatting(markItUp)
afterInsert:(markItUp) -> urlFormatting(markItUp)
},
{
separator: "---------------"
},
{
name: $translate.instant("COMMON.WYSIWYG.QUOTE_BLOCK_BUTTON")
openWith: "> "
placeHolder: $translate.instant("COMMON.WYSIWYG.QUOTE_BLOCK_SAMPLE_TEXT")
},
{
name: $translate.instant("COMMON.WYSIWYG.CODE_BLOCK_BUTTON")
openWith: "```\n"
placeHolder: $translate.instant("COMMON.WYSIWYG.CODE_BLOCK_SAMPLE_TEXT")
closeWith: "\n```"
},
{
separator: "---------------"
},
{
name: $translate.instant("COMMON.WYSIWYG.PREVIEW_BUTTON")
call: preview
className: "preview-icon"
},
]
afterInsert: (event) ->
target = angular.element(event.textarea)
$model.$setViewValue(target.val())
element
.markItUpRemove()
.markItUp(markdownSettings)
.textcomplete([
# us, task, and issue autocomplete: #id or #<part of title>
{
cache: true
match: /(^|\s)#([a-z0-9]+)$/i,
search: (term, callback) ->
term = taiga.slugify(term)
searchTypes = ['issues', 'tasks', 'userstories', 'epics']
searchProps = ['ref', 'subject']
filter = (item) =>
for prop in searchProps
if taiga.slugify(item[prop]).indexOf(term) >= 0
return true
return false
cancelablePromise.abort() if cancelablePromise
cancelablePromise = $rs.search.do($scope.project.id, term)
cancelablePromise.then (res) =>
# ignore wikipages if they're the only results. can't exclude them in search
if res.count < 1 or res.count == res.wikipages.length
callback([])
else
for type in searchTypes
if res[type] and res[type].length > 0
callback(res[type].filter(filter), true)
# must signal end of lists
callback([])
replace: (res) ->
return "$1\##{res.ref} "
template: (res, term) ->
return "\##{res.ref} - #{res.subject}"
}
# username autocomplete: @username or @<part of name>
{
cache: true
match: /(^|\s)@([a-z0-9\-\._]{2,})$/i
search: (term, callback) ->
username = taiga.slugify(term)
searchProps = ['username', 'full_name', 'full_name_display']
if $scope.project.members.length < 1
callback([])
else
callback $scope.project.members.filter (user) =>
for prop in searchProps
if taiga.slugify(user[prop]).indexOf(username) >= 0
return true
return false
replace: (user) ->
return "$1@#{user.username} "
template: (user) ->
return "#{user.username} - #{user.full_name_display}"
}
# wiki pages autocomplete: [[slug or [[<part of slug>
# if the search function was called with the 3rd param the regex
# like the docs claim, we could combine this with the #123 search
{
cache: true
match: /(^|\s)\[\[([a-z0-9\-]+)$/i
search: (term, callback) ->
term = taiga.slugify(term)
$rs.search.do($scope.project.id, term).then (res) =>
if res.count < 1
callback([])
if res.count < 1 or not res.wikipages or res.wikipages.length <= 0
callback([])
else
callback res.wikipages.filter((page) =>
return taiga.slugify(page['slug']).indexOf(term) >= 0
), true
# must signal end of lists
callback([])
replace: (res) ->
return "$1[[#{res.slug}]]"
template: (res, term) ->
return res.slug
}
],
{
debounce: 200
}
)
renderMarkItUp()
unbind = $rootscope.$on "$translateChangeEnd", renderMarkItUp
element.on "keypress", (event) ->
$scope.$apply()
$scope.$on "$destroy", ->
$el.off()
unbind()
return {link:link, require:"ngModel"}
module.directive("tgMarkitup", ["$rootScope", "$tgResources", "$selectedText", "$tgTemplate", "$compile",
"$translate", "tgProjectService", MarkitupDirective])

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -54,11 +54,12 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgNavUrls", "$tgNavUrls",
"$translate", "$translate",
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location,
@log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService) -> @log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.epicRef = @params.epicref @scope.epicRef = @params.epicref
@ -102,14 +103,15 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.onDeleteGoToUrl = @navUrls.resolve("project-epics", ctx) @scope.onDeleteGoToUrl = @navUrls.resolve("project-epics", ctx)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.immutableProject = Immutable.fromJS(project._attrs) @scope.project = project
@scope.$emit('project:loaded', project) @scope.immutableProject = @projectService.project
@scope.statusList = project.epic_statuses @scope.$emit('project:loaded', project)
@scope.statusById = groupBy(project.epic_statuses, (x) -> x.id) @scope.statusList = project.epic_statuses
return project @scope.statusById = groupBy(project.epic_statuses, (x) -> x.id)
return project
loadEpic: -> loadEpic: ->
return @rs.epics.getByRef(@scope.projectId, @params.epicref).then (epic) => return @rs.epics.getByRef(@scope.projectId, @params.epicref).then (epic) =>
@ -139,10 +141,10 @@ class EpicDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.userstories = data @scope.userstories = data
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadEpic().then(=> @.loadUserstories()) @.loadEpic().then(=> @.loadUserstories())
### ###
# Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button.

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -53,11 +53,12 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
"$tgNavUrls", "$tgNavUrls",
"$translate", "$translate",
"$tgQueueModelTransformation", "$tgQueueModelTransformation",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location,
@log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService) -> @log, @appMetaService, @analytics, @navUrls, @translate, @modelTransform, @errorHandlingService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.issueRef = @params.issueref @scope.issueRef = @params.issueref
@ -112,19 +113,20 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.onDeleteGoToUrl = @navUrls.resolve("project", ctx) @scope.onDeleteGoToUrl = @navUrls.resolve("project", ctx)
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.projectId = project.id
@scope.project = project @scope.projectId = project.id
@scope.$emit('project:loaded', project) @scope.project = project
@scope.statusList = project.issue_statuses @scope.$emit('project:loaded', project)
@scope.statusById = groupBy(project.issue_statuses, (x) -> x.id) @scope.statusList = project.issue_statuses
@scope.typeById = groupBy(project.issue_types, (x) -> x.id) @scope.statusById = groupBy(project.issue_statuses, (x) -> x.id)
@scope.typeList = _.sortBy(project.issue_types, "order") @scope.typeById = groupBy(project.issue_types, (x) -> x.id)
@scope.severityList = project.severities @scope.typeList = _.sortBy(project.issue_types, "order")
@scope.severityById = groupBy(project.severities, (x) -> x.id) @scope.severityList = project.severities
@scope.priorityList = project.priorities @scope.severityById = groupBy(project.severities, (x) -> x.id)
@scope.priorityById = groupBy(project.priorities, (x) -> x.id) @scope.priorityList = project.priorities
return project @scope.priorityById = groupBy(project.priorities, (x) -> x.id)
return project
loadIssue: -> loadIssue: ->
return @rs.issues.getByRef(@scope.projectId, @params.issueref).then (issue) => return @rs.issues.getByRef(@scope.projectId, @params.issueref).then (issue) =>
@ -149,10 +151,11 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@scope.nextUrl = @navUrls.resolve("project-issues-detail", ctx) @scope.nextUrl = @navUrls.resolve("project-issues-detail", ctx)
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.loadIssue()
return @.loadIssue()
### ###
# Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button. # Note: This methods (onUpvote() and onDownvote()) are related to tg-vote-button.

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -78,6 +78,10 @@ CreateIssueDirective = ($repo, $confirm, $rootscope, lightboxService, $loading,
$scope.addAttachment = (attachment) -> $scope.addAttachment = (attachment) ->
attachmentsToAdd = attachmentsToAdd.push(attachment) attachmentsToAdd = attachmentsToAdd.push(attachment)
$scope.deleteAttachment = (attachment) ->
attachmentsToAdd = attachmentsToAdd.filter (it) ->
return it.get('name') != attachment.get('name')
$scope.addTag = (tag, color) -> $scope.addTag = (tag, color) ->
value = trim(tag.toLowerCase()) value = trim(tag.toLowerCase())

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -58,14 +58,16 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$translate", "$translate",
"tgErrorHandlingService", "tgErrorHandlingService",
"$tgStorage", "$tgStorage",
"tgFilterRemoteStorageService" "tgFilterRemoteStorageService",
"tgProjectService",
"tgUserActivityService"
] ]
filtersHashSuffix: "issues-filters" filtersHashSuffix: "issues-filters"
myFiltersHashSuffix: "issues-my-filters" myFiltersHashSuffix: "issues-my-filters"
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @urls, @params, @q, @location, @appMetaService, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @urls, @params, @q, @location, @appMetaService,
@navUrls, @events, @analytics, @translate, @errorHandlingService, @storage, @filterRemoteStorageService) -> @navUrls, @events, @analytics, @translate, @errorHandlingService, @storage, @filterRemoteStorageService, @projectService) ->
bindMethods(@) bindMethods(@)
@scope.sectionName = "Issues" @scope.sectionName = "Issues"
@ -286,24 +288,25 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_issues_activated
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.is_issues_activated
@scope.project = project @errorHandlingService.permissionDenied()
@scope.$emit('project:loaded', project)
@scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id) @scope.projectId = project.id
@scope.issueStatusList = _.sortBy(project.issue_statuses, "order") @scope.project = project
@scope.severityById = groupBy(project.severities, (x) -> x.id) @scope.$emit('project:loaded', project)
@scope.severityList = _.sortBy(project.severities, "order")
@scope.priorityById = groupBy(project.priorities, (x) -> x.id)
@scope.priorityList = _.sortBy(project.priorities, "order")
@scope.issueTypes = _.sortBy(project.issue_types, "order")
@scope.issueTypeById = groupBy(project.issue_types, (x) -> x.id)
return project @scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id)
@scope.issueStatusList = _.sortBy(project.issue_statuses, "order")
@scope.severityById = groupBy(project.severities, (x) -> x.id)
@scope.severityList = _.sortBy(project.severities, "order")
@scope.priorityById = groupBy(project.priorities, (x) -> x.id)
@scope.priorityList = _.sortBy(project.priorities, "order")
@scope.issueTypes = _.sortBy(project.issue_types, "order")
@scope.issueTypeById = groupBy(project.issue_types, (x) -> x.id)
return project
# We need to guarantee that the last petition done here is the finally used # We need to guarantee that the last petition done here is the finally used
# When searching by text loadIssues can be called fastly with different parameters and # When searching by text loadIssues can be called fastly with different parameters and
@ -328,13 +331,13 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
return promise return promise
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription()
@.generateFilters()
return @.loadIssues() @.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription()
@.generateFilters()
return @.loadIssues()
# Functions used from templates # Functions used from templates
addNewIssue: -> addNewIssue: ->
@ -482,7 +485,10 @@ IssuesDirective = ($log, $location, $template, $compile) ->
currentOrder = $ctrl.getOrderBy() currentOrder = $ctrl.getOrderBy()
newOrder = target.data("fieldname") newOrder = target.data("fieldname")
finalOrder = if currentOrder == newOrder then "-#{newOrder}" else newOrder if newOrder == 'total_voters'
finalOrder = if currentOrder == newOrder then newOrder else "-#{newOrder}"
else
finalOrder = if currentOrder == newOrder then "-#{newOrder}" else newOrder
$scope.$apply -> $scope.$apply ->
$ctrl.replaceFilter("order_by", finalOrder) $ctrl.replaceFilter("order_by", finalOrder)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,5 +1,5 @@
### ###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io> # Copyright (C) 2014-2017 Taiga Agile LLC <taiga@taiga.io>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -170,9 +170,14 @@ class KanbanUserstoriesService extends taiga.Service
userstories = @.userstoriesRaw userstories = @.userstoriesRaw
userstories = _.map userstories, (usModel) => userstories = _.map userstories, (usModel) =>
us = {} us = {}
model = usModel.getAttrs()
us.foldStatusChanged = @.foldStatusChanged[usModel.id] us.foldStatusChanged = @.foldStatusChanged[usModel.id]
us.model = usModel.getAttrs()
us.images = _.filter usModel.attachments, (it) -> return !!it.thumbnail_card_url us.model = model
us.images = _.filter model.attachments, (it) -> return !!it.thumbnail_card_url
us.id = usModel.id us.id = usModel.id
us.assigned_to = @.usersById[usModel.assigned_to] us.assigned_to = @.usersById[usModel.assigned_to]
us.colorized_tags = _.map us.model.tags, (tag) => us.colorized_tags = _.map us.model.tags, (tag) =>

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -58,7 +58,8 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
"$tgModel", "$tgModel",
"tgKanbanUserstories", "tgKanbanUserstories",
"$tgStorage", "$tgStorage",
"tgFilterRemoteStorageService" "tgFilterRemoteStorageService",
"tgProjectService"
] ]
storeCustomFiltersName: 'kanban-custom-filters' storeCustomFiltersName: 'kanban-custom-filters'
@ -66,7 +67,7 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location, constructor: (@scope, @rootscope, @repo, @confirm, @rs, @rs2, @params, @q, @location,
@appMetaService, @navUrls, @events, @analytics, @translate, @errorHandlingService, @appMetaService, @navUrls, @events, @analytics, @translate, @errorHandlingService,
@model, @kanbanUserstoriesService, @storage, @filterRemoteStorageService) -> @model, @kanbanUserstoriesService, @storage, @filterRemoteStorageService, @projectService) ->
bindMethods(@) bindMethods(@)
@kanbanUserstoriesService.reset() @kanbanUserstoriesService.reset()
@.openFilter = false @.openFilter = false
@ -76,6 +77,10 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.sectionName = @translate.instant("KANBAN.SECTION_NAME") @scope.sectionName = @translate.instant("KANBAN.SECTION_NAME")
@.initializeEventHandlers() @.initializeEventHandlers()
taiga.defineImmutableProperty @.scope, "usByStatus", () =>
return @kanbanUserstoriesService.usByStatus
firstLoad: () ->
promise = @.loadInitialData() promise = @.loadInitialData()
# On Success # On Success
@ -90,16 +95,29 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
# On Error # On Error
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
taiga.defineImmutableProperty @.scope, "usByStatus", () =>
return @kanbanUserstoriesService.usByStatus
setZoom: (zoomLevel, zoom) -> setZoom: (zoomLevel, zoom) ->
if @.zoomLevel != zoomLevel if @.zoomLevel == zoomLevel
@kanbanUserstoriesService.resetFolds() return null
@.isFirstLoad = !@.zoomLevel
previousZoomLevel = @.zoomLevel
@.zoomLevel = zoomLevel @.zoomLevel = zoomLevel
@.zoom = zoom @.zoom = zoom
if @.isFirstLoad
@.firstLoad().then () =>
@.isFirstLoad = false
@kanbanUserstoriesService.resetFolds()
else if @.zoomLevel > 1 && previousZoomLevel <= 1
@.zoomLoading = true
@.loadUserstories().then () =>
@.zoomLoading = false
@kanbanUserstoriesService.resetFolds()
filtersReloadContent: () -> filtersReloadContent: () ->
@.loadUserstories().then () => @.loadUserstories().then () =>
openArchived = _.difference(@kanbanUserstoriesService.archivedStatus, openArchived = _.difference(@kanbanUserstoriesService.archivedStatus,
@ -181,13 +199,15 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) => return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) =>
@scope.project.tags_colors = tags_colors._attrs @scope.project.tags_colors = tags_colors._attrs
loadUserstories: -> loadUserstories: () ->
params = { params = {
status__is_archived: false, status__is_archived: false
include_attachments: true,
include_tasks: true
} }
if @.zoomLevel > 1
params.include_attachments = 1
params.include_tasks = 1
params = _.merge params, @location.search() params = _.merge params, @location.search()
promise = @rs.userstories.listAll(@scope.projectId, params).then (userstories) => promise = @rs.userstories.listAll(@scope.projectId, params).then (userstories) =>
@ -237,20 +257,21 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
]) ])
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
if not project.is_kanban_activated
@errorHandlingService.permissionDenied()
@scope.projectId = project.id if not project.is_kanban_activated
@scope.project = project @errorHandlingService.permissionDenied()
@scope.projectId = project.id
@scope.points = _.sortBy(project.points, "order")
@scope.pointsById = groupBy(project.points, (x) -> x.id)
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id)
@scope.usStatusList = _.sortBy(project.us_statuses, "order")
@scope.$emit("project:loaded", project) @scope.projectId = project.id
return project @scope.project = project
@scope.projectId = project.id
@scope.points = _.sortBy(project.points, "order")
@scope.pointsById = groupBy(project.points, (x) -> x.id)
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id)
@scope.usStatusList = _.sortBy(project.us_statuses, "order")
@scope.$emit("project:loaded", project)
return project
initializeSubscription: -> initializeSubscription: ->
routingKey1 = "changes.project.#{@scope.projectId}.userstories" routingKey1 = "changes.project.#{@scope.projectId}.userstories"
@ -258,12 +279,12 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@.loadUserstories() @.loadUserstories()
loadInitialData: -> loadInitialData: ->
promise = @.loadProject() project = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles) @.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription() @.initializeSubscription()
@.loadKanban() @.loadKanban()
@.generateFilters() @.generateFilters()
# Utils methods # Utils methods
@ -407,12 +428,8 @@ module.directive("tgKanbanArchivedStatusIntro", ["$translate", "tgKanbanUserstor
## Kanban Squish Column Directive ## Kanban Squish Column Directive
############################################################################# #############################################################################
KanbanSquishColumnDirective = (rs) -> KanbanSquishColumnDirective = (rs, projectService) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
$scope.$on "project:loaded", (event, project) ->
$scope.folds = rs.kanban.getStatusColumnModes(project.id)
updateTableWidth()
$scope.foldStatus = (status) -> $scope.foldStatus = (status) ->
$scope.folds[status.id] = !!!$scope.folds[status.id] $scope.folds[status.id] = !!!$scope.folds[status.id]
rs.kanban.storeStatusColumnModes($scope.projectId, $scope.folds) rs.kanban.storeStatusColumnModes($scope.projectId, $scope.folds)
@ -425,14 +442,22 @@ KanbanSquishColumnDirective = (rs) ->
return 40 return 40
else else
return 310 return 310
totalWidth = _.reduce columnWidths, (total, width) -> totalWidth = _.reduce columnWidths, (total, width) ->
return total + width return total + width
$el.find('.kanban-table-inner').css("width", totalWidth) $el.find('.kanban-table-inner').css("width", totalWidth)
unwatch = $scope.$watch 'usByStatus', (usByStatus) ->
if usByStatus.size
$scope.folds = rs.kanban.getStatusColumnModes(projectService.project.get('id'))
updateTableWidth()
unwatch()
return {link: link} return {link: link}
module.directive("tgKanbanSquishColumn", ["$tgResources", KanbanSquishColumnDirective]) module.directive("tgKanbanSquishColumn", ["$tgResources", "tgProjectService", KanbanSquishColumnDirective])
############################################################################# #############################################################################
## Kanban WIP Limit Directive ## Kanban WIP Limit Directive

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,8 +0,0 @@
module = angular.module("taigaProject")
createProjectRestrictionDirective = () ->
return {
templateUrl: "project/wizard-restrictions.html"
}
module.directive('tgCreateProjectRestriction', [createProjectRestrictionDirective])

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -29,94 +29,6 @@ debounce = @.taiga.debounce
module = angular.module("taigaProject") module = angular.module("taigaProject")
CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $projectUrl, $loading, lightboxService, $cacheFactory, $translate, currentUserService, $auth) ->
link = ($scope, $el, attrs) ->
$scope.data = {}
$scope.templates = []
currentLoading = null
form = $el.find("form").checksley({"onlyOneErrorElement": true})
onSuccessSubmit = (response) ->
# remove all $http cache
# This is necessary when a project is created with the same name
# than another deleted in the same session
$cacheFactory.get('$http').removeAll()
currentLoading.finish()
$rootscope.$broadcast("projects:reload")
$confirm.notify("success", $translate.instant("COMMON.SAVE"))
$location.url($projectUrl.get(response))
lightboxService.close($el)
currentUserService.loadProjects()
onErrorSubmit = (response) ->
currentLoading.finish()
form.setErrors(response)
selectors = []
for error_field in _.keys(response)
selectors.push("[name=#{error_field}]")
submit = (event) =>
event.preventDefault()
if not form.validate()
return
currentLoading = $loading()
.target(submitButton)
.start()
promise = $repo.create("projects", $scope.data)
promise.then(onSuccessSubmit, onErrorSubmit)
openLightbox = ->
$scope.data = {
is_private: false
}
if !$scope.templates.length
$rs.projects.templates().then (result) =>
$scope.templates = result
$scope.data.creation_template = _.head(_.filter($scope.templates, (x) -> x.slug == "scrum")).id
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")
$el.on "submit", "form", submit
$el.on "click", ".close", (event) ->
event.preventDefault()
lightboxService.close($el)
$scope.$on "$destroy", ->
$el.off()
$auth.refresh().then () ->
openLightbox()
directive = {
link: link,
templateUrl: "project/wizard-create-project.html"
scope: {}
}
return directive
module.directive("tgLbCreateProject", ["$rootScope", "$tgRepo", "$tgConfirm",
"$location", "$tgNavUrls", "$tgResources", "$projectUrl", "$tgLoading",
"lightboxService", "$cacheFactory", "$translate", "tgCurrentUserService", "$tgAuth", CreateProject])
############################################################################# #############################################################################
## Delete Project Lightbox Directive ## Delete Project Lightbox Directive
############################################################################# #############################################################################

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -34,6 +34,8 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem
templateEdit = $template.get("task/related-task-row-edit.html", true) templateEdit = $template.get("task/related-task-row-edit.html", true)
link = ($scope, $el, $attrs, $model) -> link = ($scope, $el, $attrs, $model) ->
@childScope = $scope.$new()
saveTask = debounce 2000, (task) -> saveTask = debounce 2000, (task) ->
task.subject = $el.find('input').val() task.subject = $el.find('input').val()
@ -53,7 +55,10 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem
return promise return promise
renderEdit = (task) -> renderEdit = (task) ->
$el.html($compile(templateEdit({task: task}))($scope)) @childScope.$destroy()
@childScope = $scope.$new()
$el.off()
$el.html($compile(templateEdit({task: task}))(childScope))
$el.find(".task-name input").val(task.subject) $el.find(".task-name input").val(task.subject)
@ -72,6 +77,8 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem
renderView($model.$modelValue) renderView($model.$modelValue)
renderView = (task) -> renderView = (task) ->
@childScope.$destroy()
@childScope = $scope.$new()
$el.off() $el.off()
perms = { perms = {
@ -79,7 +86,7 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem
delete_task: $scope.project.my_permissions.indexOf("delete_task") != -1 delete_task: $scope.project.my_permissions.indexOf("delete_task") != -1
} }
$el.html($compile(templateView({task: task, perms: perms}))($scope)) $el.html($compile(templateView({task: task, perms: perms}))(childScope))
$el.on "click", ".edit-task", -> $el.on "click", ".edit-task", ->
renderEdit($model.$modelValue) renderEdit($model.$modelValue)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -74,6 +74,7 @@ urls = {
"project-unlike": "/projects/%s/unlike" "project-unlike": "/projects/%s/unlike"
"project-watch": "/projects/%s/watch" "project-watch": "/projects/%s/watch"
"project-unwatch": "/projects/%s/unwatch" "project-unwatch": "/projects/%s/unwatch"
"project-contact": "contact"
"project-transfer-validate-token": "/projects/%s/transfer_validate_token" "project-transfer-validate-token": "/projects/%s/transfer_validate_token"
"project-transfer-accept": "/projects/%s/transfer_accept" "project-transfer-accept": "/projects/%s/transfer_accept"
"project-transfer-reject": "/projects/%s/transfer_reject" "project-transfer-reject": "/projects/%s/transfer_reject"
@ -109,6 +110,7 @@ urls = {
"bulk-update-us-milestone": "/userstories/bulk_update_milestone" "bulk-update-us-milestone": "/userstories/bulk_update_milestone"
"bulk-update-us-miles-order": "/userstories/bulk_update_sprint_order" "bulk-update-us-miles-order": "/userstories/bulk_update_sprint_order"
"bulk-update-us-kanban-order": "/userstories/bulk_update_kanban_order" "bulk-update-us-kanban-order": "/userstories/bulk_update_kanban_order"
"bulk-update-us-milestone": "/userstories/bulk_update_milestone"
"userstories-filters": "/userstories/filters_data" "userstories-filters": "/userstories/filters_data"
"userstory-upvote": "/userstories/%s/upvote" "userstory-upvote": "/userstories/%s/upvote"
"userstory-downvote": "/userstories/%s/downvote" "userstory-downvote": "/userstories/%s/downvote"
@ -201,6 +203,31 @@ urls = {
# Stats # Stats
"stats-discover": "/stats/discover" "stats-discover": "/stats/discover"
# Importers
"importers-trello-auth-url": "/importers/trello/auth_url"
"importers-trello-authorize": "/importers/trello/authorize"
"importers-trello-list-projects": "/importers/trello/list_projects"
"importers-trello-list-users": "/importers/trello/list_users"
"importers-trello-import-project": "/importers/trello/import_project"
"importers-jira-auth-url": "/importers/jira/auth_url"
"importers-jira-authorize": "/importers/jira/authorize"
"importers-jira-list-projects": "/importers/jira/list_projects"
"importers-jira-list-users": "/importers/jira/list_users"
"importers-jira-import-project": "/importers/jira/import_project"
"importers-github-auth-url": "/importers/github/auth_url"
"importers-github-authorize": "/importers/github/authorize"
"importers-github-list-projects": "/importers/github/list_projects"
"importers-github-list-users": "/importers/github/list_users"
"importers-github-import-project": "/importers/github/import_project"
"importers-asana-auth-url": "/importers/asana/auth_url"
"importers-asana-authorize": "/importers/asana/authorize"
"importers-asana-list-projects": "/importers/asana/list_projects"
"importers-asana-list-users": "/importers/asana/list_users"
"importers-asana-import-project": "/importers/asana/import_project"
} }
# Initialize api urls service # Initialize api urls service

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,5 +1,5 @@
### ###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io> # Copyright (C) 2014-2017 Taiga Agile LLC <taiga@taiga.io>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -33,9 +33,12 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
hashSuffixStatusColumnModes = "tasks-statuscolumnmodels" hashSuffixStatusColumnModes = "tasks-statuscolumnmodels"
hashSuffixUsRowModes = "tasks-usrowmodels" hashSuffixUsRowModes = "tasks-usrowmodels"
service.get = (projectId, taskId) -> service.get = (projectId, taskId, extraParams) ->
params = service.getQueryParams(projectId) params = service.getQueryParams(projectId)
params.project = projectId params.project = projectId
params = _.extend({}, params, extraParams)
return $repo.queryOne("tasks", taskId, params) return $repo.queryOne("tasks", taskId, params)
service.getByRef = (projectId, ref, extraParams) -> service.getByRef = (projectId, ref, extraParams) ->

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -30,9 +30,12 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
service = {} service = {}
hashSuffix = "userstories-queryparams" hashSuffix = "userstories-queryparams"
service.get = (projectId, usId) -> service.get = (projectId, usId, extraParams) ->
params = service.getQueryParams(projectId) params = service.getQueryParams(projectId)
params.project = projectId params.project = projectId
params = _.extend({}, params, extraParams)
return $repo.queryOne("userstories", usId, params) return $repo.queryOne("userstories", usId, params)
service.getByRef = (projectId, ref, extraParams = {}) -> service.getByRef = (projectId, ref, extraParams = {}) ->
@ -64,6 +67,7 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
params = {"project": projectId} params = {"project": projectId}
params = _.extend({}, params, filters or {}) params = _.extend({}, params, filters or {})
service.storeQueryParams(projectId, params) service.storeQueryParams(projectId, params)
return $repo.queryMany("userstories", params) return $repo.queryMany("userstories", params)
service.bulkCreate = (projectId, status, bulk) -> service.bulkCreate = (projectId, status, bulk) ->
@ -108,6 +112,17 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
params = {project_id: projectId, bulk_stories: data} params = {project_id: projectId, bulk_stories: data}
return $http.post(url, params) return $http.post(url, params)
service.bulkUpdateMilestone = (projectId, milestoneId, data) ->
url = $urls.resolve("bulk-update-us-milestone")
data = _.map data, (us) ->
return {
us_id: us.id
order: us.order
}
params = {project_id: projectId, milestone_id: milestoneId, bulk_stories: data}
return $http.post(url, params)
service.listValues = (projectId, type) -> service.listValues = (projectId, type) ->
params = {"project": projectId} params = {"project": projectId}
service.storeQueryParams(projectId, params) service.storeQueryParams(projectId, params)

View File

@ -1,5 +1,5 @@
### ###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io> # Copyright (C) 2014-2017 Taiga Agile LLC <taiga@taiga.io>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,5 +1,5 @@
### ###
# Copyright (C) 2014-2016 Taiga Agile LLC <taiga@taiga.io> # Copyright (C) 2014-2017 Taiga Agile LLC <taiga@taiga.io>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -49,23 +49,22 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
"tgAppMetaService", "tgAppMetaService",
"$tgNavUrls", "$tgNavUrls",
"$translate", "$translate",
"tgErrorHandlingService" "tgErrorHandlingService",
"tgProjectService"
] ]
constructor: (@scope, @repo, @rs, @params, @q, @location, @appMetaService, @navUrls, @translate, @errorHandlingService) -> constructor: (@scope, @repo, @rs, @params, @q, @location, @appMetaService, @navUrls, @translate, @errorHandlingService, @projectService) ->
@scope.sectionName = "Search" @scope.sectionName = "Search"
promise = @.loadInitialData() @.loadInitialData()
promise.then () => title = @translate.instant("SEARCH.PAGE_TITLE", {projectName: @scope.project.name})
title = @translate.instant("SEARCH.PAGE_TITLE", {projectName: @scope.project.name}) description = @translate.instant("SEARCH.PAGE_DESCRIPTION", {
description = @translate.instant("SEARCH.PAGE_DESCRIPTION", { projectName: @scope.project.name,
projectName: @scope.project.name, projectDescription: @scope.project.description
projectDescription: @scope.project.description })
})
@appMetaService.setAll(title, description)
promise.then null, @.onInitialDataError.bind(@) @appMetaService.setAll(title, description)
# Search input watcher # Search input watcher
@scope.searchTerm = null @scope.searchTerm = null
@ -85,17 +84,18 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
return defered.promise return defered.promise
loadProject: -> loadProject: ->
return @rs.projects.getBySlug(@params.pslug).then (project) => project = @projectService.project.toJS()
@scope.project = project
@scope.$emit('project:loaded', project)
@scope.epicStatusById = groupBy(project.epic_statuses, (x) -> x.id) @scope.project = project
@scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id) @scope.$emit('project:loaded', project)
@scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id)
@scope.severityById = groupBy(project.severities, (x) -> x.id) @scope.epicStatusById = groupBy(project.epic_statuses, (x) -> x.id)
@scope.priorityById = groupBy(project.priorities, (x) -> x.id) @scope.issueStatusById = groupBy(project.issue_statuses, (x) -> x.id)
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id)
return project @scope.severityById = groupBy(project.severities, (x) -> x.id)
@scope.priorityById = groupBy(project.priorities, (x) -> x.id)
@scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id)
return project
loadSearchData: (term = "") -> loadSearchData: (term = "") ->
@scope.loading = true @scope.loading = true
@ -112,9 +112,10 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin)
return @._promise return @._promise
loadInitialData: -> loadInitialData: ->
return @.loadProject().then (project) => project = @.loadProject()
@scope.projectId = project.id
@.fillUsersAndRoles(project.members, project.roles) @scope.projectId = project.id
@.fillUsersAndRoles(project.members, project.roles)
module.controller("SearchController", SearchController) module.controller("SearchController", SearchController)

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as

View File

@ -1,10 +1,10 @@
### ###
# Copyright (C) 2014-2016 Andrey Antukh <niwi@niwi.nz> # Copyright (C) 2014-2017 Andrey Antukh <niwi@niwi.nz>
# Copyright (C) 2014-2016 Jesús Espino Garcia <jespinog@gmail.com> # Copyright (C) 2014-2017 Jesús Espino Garcia <jespinog@gmail.com>
# Copyright (C) 2014-2016 David Barragán Merino <bameda@dbarragan.com> # Copyright (C) 2014-2017 David Barragán Merino <bameda@dbarragan.com>
# Copyright (C) 2014-2016 Alejandro Alonso <alejandro.alonso@kaleidos.net> # Copyright (C) 2014-2017 Alejandro Alonso <alejandro.alonso@kaleidos.net>
# Copyright (C) 2014-2016 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net> # Copyright (C) 2014-2017 Juan Francisco Alcántara <juanfran.alcantara@kaleidos.net>
# Copyright (C) 2014-2016 Xavi Julian <xavier.julian@kaleidos.net> # Copyright (C) 2014-2017 Xavi Julian <xavier.julian@kaleidos.net>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -42,6 +42,9 @@ CreateEditTaskDirective = ($repo, $model, $rs, $rootscope, $loading, lightboxSer
attachmentsToAdd = attachmentsToAdd.push(attachment) attachmentsToAdd = attachmentsToAdd.push(attachment)
$scope.deleteAttachment = (attachment) -> $scope.deleteAttachment = (attachment) ->
attachmentsToAdd = attachmentsToAdd.filter (it) ->
return it.get('name') != attachment.get('name')
if attachment.get("id") if attachment.get("id")
attachmentsToDelete = attachmentsToDelete.push(attachment) attachmentsToDelete = attachmentsToDelete.push(attachment)

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