diff --git a/app/coffee/modules/common/importer.coffee b/app/coffee/modules/common/importer.coffee
index de61ce3f..46b84007 100644
--- a/app/coffee/modules/common/importer.coffee
+++ b/app/coffee/modules/common/importer.coffee
@@ -25,8 +25,60 @@
module = angular.module("taigaCommon")
-ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls, $translate) ->
+ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls, $translate, $lightboxFactory, currentUserService, $tgAuth) ->
link = ($scope, $el, $attrs) ->
+ getRestrictionError = (result) ->
+ if result.headers
+ errorKey = ''
+
+ user = currentUserService.getUser()
+ maxMembers = 0
+
+ if result.headers.isPrivate
+ privateError = !currentUserService.canCreatePrivateProjects().valid
+ maxMembers = null
+
+ if user.get('max_members_private_projects') != null && result.headers.members > user.get('max_members_private_projects')
+ membersError = true
+ else
+ membersError = false
+
+ if privateError && membersError
+ errorKey = 'private-space-members'
+ maxMembers = user.get('max_members_private_projects')
+ else if privateError
+ errorKey = 'private-space'
+ else if membersError
+ errorKey = 'private-members'
+ maxMembers = user.get('max_members_private_projects')
+
+ else
+ publicError = !currentUserService.canCreatePublicProjects().valid
+
+ if user.get('max_members_public_projects') != null && result.headers.members > user.get('max_members_public_projects')
+ membersError = true
+ else
+ membersError = false
+
+ if publicError && membersError
+ errorKey = 'public-space-members'
+ maxMembers = user.get('max_members_public_projects')
+ else if publicError
+ errorKey = 'public-space'
+ else if membersError
+ errorKey = 'public-members'
+ maxMembers = user.get('max_members_public_projects')
+
+ return {
+ key: errorKey,
+ values: {
+ max_members: maxMembers,
+ members: result.headers.members
+ }
+ }
+ else
+ return false
+
$el.on "click", ".import-project-button", (event) ->
event.preventDefault()
$el.find("input.import-file").val("")
@@ -53,19 +105,47 @@ ImportProjectButtonDirective = ($rs, $confirm, $location, $navUrls, $translate)
$confirm.notify("success", msg)
onError = (result) ->
- loader.stop()
- errorMsg = $translate.instant("PROJECT.IMPORT.ERROR")
+ $tgAuth.refresh().then () ->
+ restrictionError = getRestrictionError(result)
- 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.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",
+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)
diff --git a/app/coffee/modules/common/lightboxes.coffee b/app/coffee/modules/common/lightboxes.coffee
index fe3dd88d..5db4e843 100644
--- a/app/coffee/modules/common/lightboxes.coffee
+++ b/app/coffee/modules/common/lightboxes.coffee
@@ -74,7 +74,8 @@ class LightboxService extends taiga.Service
$el.removeAttr('style')
$el.removeClass("open").removeClass('close')
- $el.addClass('close')
+ @animationFrame.add ->
+ $el.addClass('close')
if $el.hasClass("remove-on-close")
scope = $el.data("scope")
diff --git a/app/coffee/modules/resources/projects.coffee b/app/coffee/modules/resources/projects.coffee
index a1745420..7c1a372f 100644
--- a/app/coffee/modules/resources/projects.coffee
+++ b/app/coffee/modules/resources/projects.coffee
@@ -128,7 +128,11 @@ resourceProvider = ($config, $repo, $http, $urls, $auth, $q, $translate) ->
catch
response.data = {}
response.status = evt.target.status
-
+ if evt.target.getResponseHeader('Taiga-Info-Project-Is-Private')
+ response.headers = {
+ isPrivate: evt.target.getResponseHeader('Taiga-Info-Project-Is-Private') == 'True',
+ members: parseInt(evt.target.getResponseHeader('Taiga-Info-Project-Memberships'))
+ }
defered.resolve(response) if response.status in [201, 202]
defered.reject(response)
diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json
index 608e67fa..c9b100e2 100644
--- a/app/locales/taiga/locale-en.json
+++ b/app/locales/taiga/locale-en.json
@@ -806,7 +806,32 @@
"ERROR_TOO_MANY_REQUEST": "Sorry, our Oompa Loompas are very busy right now. Please try again in a few minutes.",
"ERROR_MESSAGE": "Our Oompa Loompas have some problems importing your dump data: {{error_message}}",
"ERROR_MAX_SIZE_EXCEEDED": "'{{fileName}}' ({{fileSize}}) is too heavy for our Oompa Loompas, try it with a smaller than ({{maxFileSize}})",
- "SYNC_SUCCESS": "Your project has been imported successfuly"
+ "SYNC_SUCCESS": "Your project has been imported successfuly",
+ "PROJECT_RESTRICTIONS": {
+ "PROJECT_MEMBERS_DESC": "The project you want to import has {{members}} users, but you are only allowed to have {{max_members}} users per project. If you want have more users contact with the administrators.",
+ "PRIVATE_PROJECTS_SPACE": {
+ "TITLE": "You don't have space for another private project",
+ "DESC": "The project you want to import is private, but you don't have space to create more."
+ },
+ "PUBLIC_PROJECTS_SPACE": {
+ "TITLE": "You don't' have space for another public project",
+ "DESC": "The project you want to import is public, but you don't have space to create more."
+ },
+ "PRIVATE_PROJECTS_MEMBERS": {
+ "TITLE": "Your account only allows {{max_members}} users per private project"
+ },
+ "PUBLIC_PROJECTS_MEMBERS": {
+ "TITLE": "Your account only allows {{max_members}} users per public project"
+ },
+ "PRIVATE_PROJECTS_SPACE_MEMBERS": {
+ "TITLE": "You don't have space for another private project and neither for more than {{max_members}} users per private projects",
+ "DESC": "The project that you want to import is private and has {{members}} users."
+ },
+ "PUBLIC_PROJECTS_SPACE_MEMBERS": {
+ "TITLE": "You don't have space for another public project and neither for more than {{max_members}} users per public projects",
+ "DESC": "The public that you want to import is public and has more than {{members}} users."
+ }
+ }
},
"LIKE_BUTTON": {
"LIKE": "Like",
diff --git a/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade b/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade
index c52a9961..10374374 100644
--- a/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade
+++ b/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade
@@ -28,11 +28,11 @@ div.navbar-dropdown.dropdown-project-list
title="{{'PROJECT.NAVIGATION.ACTION_CREATE_PROJECT' | translate}}",
translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT")
- a.button-blackish.import-project-button(
- href=""
- title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}"
- tg-import-project-button
- )
- svg.icon.icon-upload
- use(xlink:href="#icon-upload")
- input.import-file.hidden(type="file")
+ span(tg-import-project-button)
+ a.button-blackish.import-project-button(
+ href=""
+ title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}"
+ )
+ svg.icon.icon-upload
+ use(xlink:href="#icon-upload")
+ input.import-file.hidden(type="file")
\ No newline at end of file
diff --git a/app/partials/common/lightbox/lightbox-import-error.jade b/app/partials/common/lightbox/lightbox-import-error.jade
new file mode 100644
index 00000000..a715445d
--- /dev/null
+++ b/app/partials/common/lightbox/lightbox-import-error.jade
@@ -0,0 +1,44 @@
+a.close(href="", title="{{'COMMON.CLOSE' | translate}}")
+ svg.icon.icon-close
+ use(xlink:href="#icon-close")
+
+.content
+ div(ng-switch="key")
+ div(ng-switch-when="private-space")
+ img(width="80", src="/#{v}/svg/icons/project-limit.svg")
+
+ h2.title(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PRIVATE_PROJECTS_SPACE.TITLE", translate-values="{{values}}")
+ p(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PRIVATE_PROJECTS_SPACE.DESC", translate-values="{{values}}")
+
+ div(ng-switch-when="private-members")
+ img(width="80", src="/#{v}/svg/icons/block-user.svg")
+
+ h2.title(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PRIVATE_PROJECTS_MEMBERS.TITLE", translate-values="{{values}}")
+ p(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PROJECT_MEMBERS_DESC", translate-values="{{values}}")
+
+ div(ng-switch-when="private-space-members")
+ img(width="180", src="/#{v}/svg/icons/multi-block-project.svg")
+
+ h2.title(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PRIVATE_PROJECTS_SPACE_MEMBERS.TITLE", translate-values="{{values}}")
+ p(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PRIVATE_PROJECTS_SPACE_MEMBERS.DESC", translate-values="{{values}}")
+
+ div(ng-switch-when="public-space")
+ img(width="80", src="/#{v}/svg/icons/project-limit.svg")
+
+ h2.title(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PUBLIC_PROJECTS_SPACE.TITLE", translate-values="{{values}}")
+ p(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PUBLIC_PROJECTS_SPACE.DESC", translate-values="{{values}}")
+
+ div(ng-switch-when="public-members")
+ img(width="80", src="/#{v}/svg/icons/block-user.svg")
+
+ h2.title(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PUBLIC_PROJECTS_MEMBERS.TITLE", translate-values="{{values}}")
+ p(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PROJECT_MEMBERS_DESC", translate-values="{{values}}")
+
+ div(ng-switch-when="public-space-members")
+ img(width="180", src="/#{v}/svg/icons/multi-block-project.svg")
+
+ h2.title(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PUBLIC_PROJECTS_SPACE_MEMBERS.TITLE", translate-values="{{values}}")
+ p(translate="PROJECT.IMPORT.PROJECT_RESTRICTIONS.PUBLIC_PROJECTS_SPACE_MEMBERS.DESC", translate-values="{{values}}")
+
+ div.options
+ a.button-green(translate="COMMON.ACCEPT", ng-click="close()")
\ No newline at end of file
diff --git a/app/styles/modules/common/lightbox.scss b/app/styles/modules/common/lightbox.scss
index 1a9b3379..265a5236 100644
--- a/app/styles/modules/common/lightbox.scss
+++ b/app/styles/modules/common/lightbox.scss
@@ -538,3 +538,18 @@
}
}
}
+
+.lightbox-import-error {
+ text-align: center;
+ p {
+ a {
+ color: $primary;
+ }
+ }
+ .content {
+ width: 500px;
+ }
+ h2 {
+ margin-top: 1rem;
+ }
+}
diff --git a/app/svg/icons/block-user.svg b/app/svg/icons/block-user.svg
new file mode 100644
index 00000000..3c43c532
--- /dev/null
+++ b/app/svg/icons/block-user.svg
@@ -0,0 +1,10 @@
+
diff --git a/app/svg/icons/multi-block-project.svg b/app/svg/icons/multi-block-project.svg
new file mode 100644
index 00000000..bc13957a
--- /dev/null
+++ b/app/svg/icons/multi-block-project.svg
@@ -0,0 +1,5 @@
+
diff --git a/app/svg/icons/project-limit.svg b/app/svg/icons/project-limit.svg
new file mode 100644
index 00000000..6f0ac0d5
--- /dev/null
+++ b/app/svg/icons/project-limit.svg
@@ -0,0 +1,8 @@
+