diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4246e874..dfe2d59b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
### Features
- Ability to create url custom fields. (thanks to [@astagi](https://github.com/astagi)).
+- Blocked projects support
- Moved from iconfont to SVG sprite icon system and redesign.
- Redesign 'Admin > Project > Modules' panel.
- Add badge to project owners
diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee
index 83976ab3..d0a750f5 100644
--- a/app/coffee/app.coffee
+++ b/app/coffee/app.coffee
@@ -111,6 +111,16 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
}
)
+
+ $routeProvider.when("/blocked-project/:pslug/",
+ {
+ templateUrl: "projects/project/blocked-project.html",
+ loader: true,
+ controller: "Project",
+ controllerAs: "vm"
+ }
+ )
+
$routeProvider.when("/project/:pslug/",
{
templateUrl: "projects/project/project.html",
@@ -515,6 +525,42 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
$httpProvider.interceptors.push("versionCheckHttpIntercept")
+
+ blockingIntercept = ($q, $routeParams, $location, $navUrls) ->
+ # API calls can return blocked elements and in that situation the user will be redirected
+ # to the blocked project page
+ # This can happens in two scenarios
+ # - An ok response containing a blocked_code in the data
+ # - An error reponse when updating/creating/deleting including a 451 error code
+ redirectToBlockedPage = ->
+ pslug = $routeParams.pslug
+ blockedUrl = $navUrls.resolve("blocked-project", {project: pslug})
+ currentUrl = $location.url()
+ if currentUrl.indexOf(blockedUrl) == -1
+ $location.replace().path(blockedUrl)
+
+ responseOk = (response) ->
+ if response.data.blocked_code
+ redirectToBlockedPage()
+
+ return response
+
+ responseError = (response) ->
+ if response.status == 451
+ redirectToBlockedPage()
+
+ return $q.reject(response)
+
+ return {
+ response: responseOk
+ responseError: responseError
+ }
+
+ $provide.factory("blockingIntercept", ["$q", "$routeParams", "$location", "$tgNavUrls", blockingIntercept])
+
+ $httpProvider.interceptors.push("blockingIntercept")
+
+
$compileProvider.debugInfoEnabled(window.taigaConfig.debugInfo || false)
if localStorage.userInfo
diff --git a/app/coffee/modules/base.coffee b/app/coffee/modules/base.coffee
index e0b8c33b..2806d182 100644
--- a/app/coffee/modules/base.coffee
+++ b/app/coffee/modules/base.coffee
@@ -67,6 +67,7 @@ urls = {
"profile": "/profile"
"user-profile": "/profile/:username"
+ "blocked-project": "/blocked-project/:project"
"project": "/project/:project"
"project-backlog": "/project/:project/backlog"
"project-taskboard": "/project/:project/taskboard/:sprint"
diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json
index c53fc45b..368d9784 100644
--- a/app/locales/taiga/locale-en.json
+++ b/app/locales/taiga/locale-en.json
@@ -740,6 +740,11 @@
"FANS_COUNTER_TITLE": "{total, plural, one{one fan} other{# fans}}",
"WATCHERS_COUNTER_TITLE": "{total, plural, one{one watcher} other{# watchers}}",
"MEMBERS_COUNTER_TITLE": "{total, plural, one{one member} other{# members}}",
+ "BLOCKED_PROJECT": {
+ "BLOCKED": "Blocked project",
+ "THIS_PROJECT_IS_BLOCKED": "This project is temporarily blocked",
+ "TO_UNBLOCK_CONTACT_THE_ADMIN_STAFF": "To unblock your projects you must contact with the admin staff"
+ },
"STATS": {
"PROJECT": "project
points",
"DEFINED": "defined
points",
diff --git a/app/modules/home/duties/duty.jade b/app/modules/home/duties/duty.jade
index ee04e0b8..c0678e0a 100644
--- a/app/modules/home/duties/duty.jade
+++ b/app/modules/home/duties/duty.jade
@@ -1,7 +1,7 @@
a.list-itemtype-ticket(
href="{{ ::vm.duty.get('url') }}"
title="{{ ::duty.get('subject') }}"
- ng-class="{'blocked': vm.duty.get('is_blocked')}"
+ ng-class="{'blocked': vm.duty.get('is_blocked'), 'blocked-project': vm.duty.get('blockedProject')}"
)
div.list-itemtype-avatar(ng-if="::vm.duty.get('assigned_to_extra_info')")
img(
@@ -16,8 +16,12 @@ a.list-itemtype-ticket(
div.list-itemtype-ticket-data
p
span.ticket-project {{ ::vm.duty.get('projectName')}}
+
span.ticket-type {{ ::vm.getDutyType() }}
span.ticket-status(ng-style="{'color': vm.duty.get('status_extra_info').get('color')}") {{ ::vm.duty.get('status_extra_info').get('name') }}
+ svg.icon.icon-blocked-project(ng-if="vm.duty.get('blockedProject')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
h2
span.ticket-id(tg-bo-ref="duty.get('ref')")
diff --git a/app/modules/home/home.service.coffee b/app/modules/home/home.service.coffee
index 625b31a2..47aa069f 100644
--- a/app/modules/home/home.service.coffee
+++ b/app/modules/home/home.service.coffee
@@ -41,6 +41,7 @@ class HomeService extends taiga.Service
duty = duty.set('url', url)
duty = duty.set('projectName', project.get('name'))
+ duty = duty.set('blockedProject', project.get('blocked_code'))
duty = duty.set("_name", objType)
return duty
diff --git a/app/modules/home/home.service.spec.coffee b/app/modules/home/home.service.spec.coffee
index 24b1f01f..41b162ff 100644
--- a/app/modules/home/home.service.spec.coffee
+++ b/app/modules/home/home.service.spec.coffee
@@ -128,6 +128,7 @@ describe "tgHome", ->
project: '1',
url: '/testing-project/us/1',
projectName: 'fake1',
+ blockedProject: undefined,
_name: 'userstories'
}]
tasks: [{
@@ -136,6 +137,7 @@ describe "tgHome", ->
project: '1',
url: '/testing-project/tasks/1',
projectName: 'fake1',
+ blockedProject: undefined,
_name: 'tasks'
}]
issues: [{
@@ -144,6 +146,7 @@ describe "tgHome", ->
project: '1',
url: '/testing-project/issues/1',
projectName: 'fake1',
+ blockedProject: undefined,
_name: 'issues'
}]
}
@@ -154,6 +157,7 @@ describe "tgHome", ->
project: '1',
url: '/testing-project/us/1',
projectName: 'fake1',
+ blockedProject: undefined,
_name: 'userstories'
}]
tasks: [{
@@ -162,6 +166,7 @@ describe "tgHome", ->
project: '1',
url: '/testing-project/tasks/1',
projectName: 'fake1',
+ blockedProject: undefined,
_name: 'tasks'
}]
issues: [{
@@ -170,6 +175,7 @@ describe "tgHome", ->
project: '1',
url: '/testing-project/issues/1',
projectName: 'fake1',
+ blockedProject: undefined,
_name: 'issues'
}]
}
diff --git a/app/modules/home/projects/home-project-list.jade b/app/modules/home/projects/home-project-list.jade
index a5d4c52a..7bb4820a 100644
--- a/app/modules/home/projects/home-project-list.jade
+++ b/app/modules/home/projects/home-project-list.jade
@@ -1,6 +1,10 @@
section.home-project-list(ng-if="vm.projects.size")
- .home-project(tg-bind-scope, tg-repeat="project in vm.projects")
+ .home-project(
+ tg-bind-scope
+ tg-repeat="project in vm.projects"
+ ng-class="{'blocked-project': project.get('blocked_code')}"
+ )
.tags-container
.project-tag(
style="background: {{tag.get('color')}}"
@@ -19,7 +23,7 @@ section.home-project-list(ng-if="vm.projects.size")
alt="{{::project.get('name')}}"
)
h2.project-card-name
- a(
+ a.project-title(
href="#"
tg-nav="project:project=project.get('slug')"
title="{{::project.get('name')}}"
@@ -27,6 +31,10 @@ section.home-project-list(ng-if="vm.projects.size")
svg.look-for-people.icon.icon-recruit(ng-if="project.get('is_looking_for_people')")
use(xlink:href="#icon-recruit")
title="{{ ::project.get('looking_for_people_note') }}"
+ svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
+
p.project-card-description {{::project.get('description')| limitTo:100 }}
span(ng-if="::project.get('description').length > 100") ...
.project-card-statistics
diff --git a/app/modules/home/projects/home-project-list.scss b/app/modules/home/projects/home-project-list.scss
index 503b1155..d87810e0 100644
--- a/app/modules/home/projects/home-project-list.scss
+++ b/app/modules/home/projects/home-project-list.scss
@@ -9,6 +9,20 @@
&:hover {
border: 1px solid $primary-light;
}
+ &.blocked-project {
+ border: $whitish;
+ &:hover {
+ border: $whitish;
+ }
+ .tags-container,
+ .project-card-logo,
+ .project-card-name a,
+ .icon-recruit,
+ .project-card-description,
+ .project-card-statistics {
+ opacity: .3;
+ }
+ }
}
.projects-empty {
diff --git a/app/modules/home/working-on/working-on.jade b/app/modules/home/working-on/working-on.jade
index 62e3d755..6b301ba8 100644
--- a/app/modules/home/working-on/working-on.jade
+++ b/app/modules/home/working-on/working-on.jade
@@ -20,7 +20,11 @@ section.watching-container
.title-bar.watching-title(translate="HOME.WATCHING_SECTION")
.watching(ng-if="vm.watching.size")
- .duty-single(tg-duty="duty", tg-repeat="duty in vm.watching", ng-class="{'blocked': duty.is_blocked}")
+ .duty-single(
+ tg-duty="duty"
+ tg-repeat="duty in vm.watching"
+ ng-class="{'blocked': duty.is_blocked}"
+ )
.watching-empty(ng-if="vm.watching != undefined && vm.watching.size === 0")
p(translate="HOME.EMPTY_WATCHING")
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 47a2a7c0..c52a9961 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
@@ -4,8 +4,16 @@ a(href="", title="Projects", tg-nav="projects")
div.navbar-dropdown.dropdown-project-list
ul
- li(tg-repeat="project in vm.projects track by project.get('id')")
- a(href="#", tg-nav="project:project=project.get('slug')") {{::project.get("name")}}
+ li(tg-repeat="project in vm.projects track by project.get('id')")
+ a(
+ href="#"
+ tg-nav="project:project=project.get('slug')"
+ ng-class="{'blocked-project': project.get('blocked_code')}"
+ )
+ span {{::project.get("name")}}
+ svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
a.see-more-projects-btn.button-gray(
href="#",
diff --git a/app/modules/navigation-bar/navigation-bar.scss b/app/modules/navigation-bar/navigation-bar.scss
index 4a6f78a0..26f0fadf 100644
--- a/app/modules/navigation-bar/navigation-bar.scss
+++ b/app/modules/navigation-bar/navigation-bar.scss
@@ -173,6 +173,14 @@ $dropdown-width: 350px;
&.create-project-btn {
flex: 1;
}
+ &.blocked-project {
+ color: $gray;
+ svg {
+ margin-left: .5rem;
+ position: relative;
+ top: .25rem;
+ }
+ }
}
.import-project-button {
&:hover {
diff --git a/app/modules/profile/profile-favs/items/project.jade b/app/modules/profile/profile-favs/items/project.jade
index c298b272..99f58d66 100644
--- a/app/modules/profile/profile-favs/items/project.jade
+++ b/app/modules/profile/profile-favs/items/project.jade
@@ -1,7 +1,6 @@
-.list-itemtype-project
+.list-itemtype-project(ng-class="{'blocked-project': vm.item.get('project_blocked_code')}")
.list-itemtype-project-left
.list-itemtype-project-data-wrapper
-
a.list-itemtype-project-image(
href="#"
tg-nav="project:project=vm.item.get('slug')"
@@ -14,20 +13,21 @@
.list-itemtype-project-data
h2
- a(
+ a.list-itemtype-project-name(
href="#"
tg-nav="project:project=vm.item.get('slug')"
title="{{ ::vm.item.get('name') }}"
) {{ ::vm.item.get('name') }}
- span.private(ng-if="::project.get('is_private')", title="{{'PROJECT.PRIVATE' | translate}}")
- p {{ ::vm.item.get('description') }}
-
- .list-itemtype-project-tags.tags-container(ng-if="::vm.item.get('tags_colors').size")
- span.tag(
- tg-repeat="tag in ::vm.item.get('tags_colors')"
- style='border-left: 5px solid {{ ::tag.get("color") }};'
- )
- span.tag-name {{ ::tag.get('name') }}
+ span.private(
+ ng-if="::vm.item.get('project_is_private')"
+ title="{{'PROJECT.PRIVATE' | translate}}"
+ )
+ svg.icon.icon-lock
+ use(xlink:href="#icon-lock")
+ svg.icon.icon-blocked-project(ng-if="vm.item.get('project_blocked_code')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
+ p.list-itemtype-project-description {{ ::vm.item.get('description') }}
.list-itemtype-track
span.list-itemtype-track-likers(
diff --git a/app/modules/profile/profile-favs/items/ticket.jade b/app/modules/profile/profile-favs/items/ticket.jade
index d938466a..599fd041 100644
--- a/app/modules/profile/profile-favs/items/ticket.jade
+++ b/app/modules/profile/profile-favs/items/ticket.jade
@@ -1,4 +1,4 @@
-div.list-itemtype-ticket
+div.list-itemtype-ticket(ng-class="{'blocked-project': vm.item.get('project_blocked_code')}")
a.list-itemtype-avatar(
href=""
ng-if="::vm.item.get('assigned_to')"
@@ -38,6 +38,9 @@ div.list-itemtype-ticket
)
span.ticket-status(ng-style="::{'color': vm.item.get('status_color')}")
| {{:: vm.item.get('status') }}
+ svg.icon.icon-blocked-project(ng-if="vm.item.get('project_blocked_code')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
h2
span.ticket-id(tg-bo-ref="vm.item.get('ref')")
a.ticket-title(
@@ -45,22 +48,19 @@ div.list-itemtype-ticket
ng-if="::vm.item.get('type') === 'userstory'"
tg-nav="project-userstories-detail:project=vm.item.get('project_slug'),ref=vm.item.get('ref')"
title="#{{ ::vm.item.get('ref') }} {{ ::vm.item.get('subject') }}"
- )
- | {{ ::vm.item.get('subject') }}
+ ) {{ ::vm.item.get('subject') }}
a.ticket-title(
href="#"
ng-if="::vm.item.get('type') === 'task'"
tg-nav="project-tasks-detail:project=vm.item.get('project_slug'),ref=vm.item.get('ref')"
title="#{{ ::vm.item.get('ref') }} {{ ::vm.item.get('subject') }}"
- )
- | {{ ::vm.item.get('subject') }}
+ ) {{ ::vm.item.get('subject') }}
a.ticket-title(
href="#"
ng-if="::vm.item.get('type') === 'issue'"
tg-nav="project-issues-detail:project=vm.item.get('project_slug'),ref=vm.item.get('ref')"
title="#{{ ::vm.item.get('ref') }} {{ ::vm.item.get('subject') }}"
- )
- | {{ ::vm.item.get('subject') }}
+ ) {{ ::vm.item.get('subject') }}
div.list-itemtype-track
span.list-itemtype-track-likers(
diff --git a/app/modules/profile/profile-favs/profile-favs.controller.coffee b/app/modules/profile/profile-favs/profile-favs.controller.coffee
index 2022ee4a..5bd5917d 100644
--- a/app/modules/profile/profile-favs/profile-favs.controller.coffee
+++ b/app/modules/profile/profile-favs/profile-favs.controller.coffee
@@ -184,4 +184,3 @@ class ProfileWatchedController extends FavsBaseController
angular.module("taigaProfile")
.controller("ProfileWatched", ProfileWatchedController)
-
diff --git a/app/modules/profile/profile-favs/profile-favs.jade b/app/modules/profile/profile-favs/profile-favs.jade
index 24120ccb..9ec621c7 100644
--- a/app/modules/profile/profile-favs/profile-favs.jade
+++ b/app/modules/profile/profile-favs/profile-favs.jade
@@ -60,10 +60,26 @@ section.profile-favs
tg-repeat="item in vm.items track by $index"
ng-switch="item.get('type')"
)
- div(ng-switch-when="project", tg-fav-item="item", item-type="project")
- div(ng-switch-when="userstory", tg-fav-item="item", item-type="userstory")
- div(ng-switch-when="task", tg-fav-item="item", item-type="task")
- div(ng-switch-when="issue", tg-fav-item="item", item-type="issue")
+ div(
+ ng-switch-when="project"
+ tg-fav-item="item"
+ item-type="project"
+ )
+ div(
+ ng-switch-when="userstory"
+ tg-fav-item="item"
+ item-type="userstory"
+ )
+ div(
+ ng-switch-when="task"
+ tg-fav-item="item"
+ item-type="task"
+ )
+ div(
+ ng-switch-when="issue"
+ tg-fav-item="item"
+ item-type="issue"
+ )
div(ng-if="vm.isLoading")
div.spin
diff --git a/app/modules/profile/profile-projects/profile-projects.jade b/app/modules/profile/profile-projects/profile-projects.jade
index 19e943c8..5e3ff52d 100644
--- a/app/modules/profile/profile-projects/profile-projects.jade
+++ b/app/modules/profile/profile-projects/profile-projects.jade
@@ -11,8 +11,10 @@ section.profile-projects
translate="USER.PROFILE.PROJECTS_EMPTY"
translate-values="{username: vm.user.get('full_name_display')}"
)
-
- .list-itemtype-project(tg-repeat="project in vm.projects")
+ .list-itemtype-project(
+ tg-repeat="project in vm.projects"
+ ng-class="{'blocked-project': project.get('blocked_code')}"
+ )
.list-itemtype-project-left
.project-list-single-title-wrapper
a.list-itemtype-project-image(
@@ -26,19 +28,15 @@ section.profile-projects
)
.project-list-single-title
h2
- a(
+ a.project-title(
href="#"
tg-nav="project:project=project.get('slug')"
title="{{ ::project.get('name') }}"
) {{::project.get('name')}}
- p {{ ::project.get('description') | limitTo:300 }}
-
- .list-itemtype-project-tags.tags-container(ng-if="::project.get('tags').size")
- span.tag(
- style='border-left: 5px solid {{::tag.get("color")}};'
- tg-repeat="tag in ::project.get('colorized_tags')"
- )
- span.tag-name {{::tag.get('name')}}
+ svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
+ p.project-description {{ ::project.get('description') | limitTo:300 }}
.list-itemtype-project-right
diff --git a/app/modules/profile/profile.scss b/app/modules/profile/profile.scss
index d11826f6..a2b22bb7 100644
--- a/app/modules/profile/profile.scss
+++ b/app/modules/profile/profile.scss
@@ -11,7 +11,6 @@
padding: 0;
}
.timeline-wrapper {
- background: lighten($whitish, 10%);
margin-right: 3.5rem;
width: 768px;
> div {
diff --git a/app/modules/projects/components/blocked-project-explanation.directive.coffee b/app/modules/projects/components/blocked-project-explanation.directive.coffee
new file mode 100644
index 00000000..fac3ed91
--- /dev/null
+++ b/app/modules/projects/components/blocked-project-explanation.directive.coffee
@@ -0,0 +1,25 @@
+###
+# Copyright (C) 2014-2016 Taiga Agile LLC
+#
+# 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 .
+#
+# File: blocked-project-explanation.directive.coffee
+###
+
+BlockedProjectExplanationDirective = () ->
+ return {
+ templateUrl: "projects/project/blocked-project-explanation.html"
+ }
+
+angular.module("taigaProjects").directive("tgBlockedProjectExplanation", BlockedProjectExplanationDirective)
diff --git a/app/modules/projects/listing/projects-listing.jade b/app/modules/projects/listing/projects-listing.jade
index 237e1061..65414a43 100644
--- a/app/modules/projects/listing/projects-listing.jade
+++ b/app/modules/projects/listing/projects-listing.jade
@@ -23,6 +23,7 @@
li.list-itemtype-project(
tg-bind-scope
tg-repeat="project in vm.projects track by project.get('id')"
+ ng-class="{'blocked-project': project.get('blocked_code')}"
)
.list-itemtype-project-left
@@ -38,7 +39,7 @@
)
.list-itemtype-project-data
h2
- a(
+ a.project-title(
href="#"
tg-nav="project:project=project.get('slug')"
title="{{ ::project.get('name') }}"
@@ -53,9 +54,12 @@
svg.icon.icon-badge(ng-if="project.get('i_am_owner')")
use(xlink:href="#icon-badge")
title(translate="COMMON.OWNER")
+ svg.icon.icon-blocked-project(ng-if="project.get('blocked_code')")
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
- p {{ ::project.get('description') | limitTo:300 }}
+ p.project-description {{ ::project.get('description') | limitTo:300 }}
span(ng-if="::project.get('description').length > 300") ...
svg.drag.icon.icon-drag
diff --git a/app/modules/projects/listing/styles/profile-projects.scss b/app/modules/projects/listing/styles/profile-projects.scss
index e068e7c7..2a2a6041 100644
--- a/app/modules/projects/listing/styles/profile-projects.scss
+++ b/app/modules/projects/listing/styles/profile-projects.scss
@@ -3,7 +3,16 @@
.list-itemtype-project {
display: flex;
justify-content: space-between;
- min-height: 10rem;
+ min-height: 9rem;
+ padding: .75rem;
+ &.blocked-project {
+ .list-itemtype-project-image,
+ .project-title,
+ .project-description,
+ .list-itemtype-project-right {
+ opacity: .4;
+ }
+ }
.project-list-single-title-wrapper {
display: flex;
}
@@ -14,7 +23,11 @@
display: flex;
flex-direction: column;
flex-shrink: 0;
+ justify-content: space-between;
width: 200px;
}
+ .icon-blocked-project {
+ @include svg-size();
+ }
}
}
diff --git a/app/modules/projects/listing/styles/project-list.scss b/app/modules/projects/listing/styles/project-list.scss
index f2599a51..fe26d12c 100644
--- a/app/modules/projects/listing/styles/project-list.scss
+++ b/app/modules/projects/listing/styles/project-list.scss
@@ -14,7 +14,8 @@
}
}
.icon-lock,
- .icon-badge {
+ .icon-badge,
+ .icon-blocked-project {
@include svg-size();
}
.icon-badge {
@@ -62,6 +63,16 @@
opacity: 1;
}
}
+ &.blocked-project {
+ .list-itemtype-project-image,
+ .project-title,
+ .private,
+ .project-description,
+ .icon-badge,
+ .icon-drag {
+ opacity: .25;
+ }
+ }
.list-itemtype-project-data-wrapper {
display: flex;
}
diff --git a/app/modules/projects/project/blocked-project-explanation.jade b/app/modules/projects/project/blocked-project-explanation.jade
new file mode 100644
index 00000000..0ce3441b
--- /dev/null
+++ b/app/modules/projects/project/blocked-project-explanation.jade
@@ -0,0 +1,5 @@
+div(ng-if="!vm.project.get('i_am_owner')")
+ div {{'PROJECT.BLOCKED_PROJECT.THIS_PROJECT_IS_BLOCKED' | translate}}
+
+div(ng-if="vm.project.get('i_am_owner')")
+ div {{'PROJECT.BLOCKED_PROJECT.TO_UNBLOCK_CONTACT_THE_ADMIN_STAFF' | translate}}
diff --git a/app/modules/projects/project/blocked-project.jade b/app/modules/projects/project/blocked-project.jade
new file mode 100644
index 00000000..be6b75b8
--- /dev/null
+++ b/app/modules/projects/project/blocked-project.jade
@@ -0,0 +1,15 @@
+.blocked-project-detail
+ .blocked-project-inner
+ .blocked-project-title
+ .project-image
+ img(
+ tg-project-logo-small-src="vm.project"
+ alt="{{::vm.project.get('name')}}"
+ )
+ svg.icon.icon-blocked-project
+ use(xlink:href="#icon-blocked-project")
+ title(translate="PROJECT.BLOCKED_PROJECT.BLOCKED")
+ span.project-title {{::vm.project.get("name")}}
+ .blocked-project-message
+ h1.project-block-title {{'PROJECT.BLOCKED_PROJECT.BLOCKED' | translate}}
+ tg-blocked-project-explanation.project-block-message
diff --git a/app/modules/projects/project/blocked-project.scss b/app/modules/projects/project/blocked-project.scss
new file mode 100644
index 00000000..40bbc218
--- /dev/null
+++ b/app/modules/projects/project/blocked-project.scss
@@ -0,0 +1,42 @@
+.blocked-project-detail {
+ align-items: center;
+ background: url('../images/discover.png') bottom center repeat-x;
+ display: flex;
+ justify-content: center;
+ min-height: calc(100vh - 40px);
+}
+
+.blocked-project-inner {
+ width: 330px;
+}
+
+.blocked-project-title {
+ align-items: center;
+ display: flex;
+ .project-image {
+ flex-basis: 6rem;
+ margin-right: 1rem;
+ max-width: 6rem;
+ position: relative;
+ }
+ img {
+ width: 100%;
+ }
+ .icon-blocked-project {
+ @include svg-size(1.5rem);
+ position: absolute;
+ right: -.5rem;
+ top: -.5rem;
+ }
+ .project-title {
+ @extend %larger;
+ }
+}
+
+.blocked-project-message {
+ margin-top: 4rem;
+ text-align: center;
+ .project-block-title {
+ @extend %xlarge;
+ }
+}
diff --git a/app/styles/components/list-items.scss b/app/styles/components/list-items.scss
index 0b715bac..547c4294 100644
--- a/app/styles/components/list-items.scss
+++ b/app/styles/components/list-items.scss
@@ -32,9 +32,21 @@
.list-itemtype-project {
@include list-itemtype-common;
justify-content: space-between;
+ &.blocked-project {
+ .list-itemtype-track,
+ .list-itemtype-project-image,
+ .list-itemtype-project-name,
+ .list-itemtype-project-description,
+ .list-itemtype-project-private {
+ opacity: .4;
+ }
+ }
h2 {
@extend %large;
}
+ .icon-blocked-project {
+ @include svg-size();
+ }
.list-itemtype-project-data-wrapper {
display: flex;
}
@@ -75,6 +87,20 @@
.list-itemtype-ticket {
@include list-itemtype-common;
+ position: relative;
+ &.blocked-project {
+ .ticket-project,
+ .ticket-type,
+ .ticket-status,
+ .list-itemtype-avatar,
+ .list-itemtype-track,
+ .ticket-title {
+ opacity: .4;
+ }
+ .icon-blocked-project {
+ @include svg-size();
+ }
+ }
h2 {
@extend %medium;
}
@@ -97,7 +123,6 @@
color: $red;
margin-left: .3rem;
}
-
}
diff --git a/app/svg/sprite.svg b/app/svg/sprite.svg
index 68d91a7e..2a25e0c5 100644
--- a/app/svg/sprite.svg
+++ b/app/svg/sprite.svg
@@ -418,5 +418,12 @@
+
+ Blocked Project
+
+
+
diff --git a/e2e/suites/project-home.e2e.js b/e2e/suites/project-home.e2e.js
index 5afb2343..dfaf8295 100644
--- a/e2e/suites/project-home.e2e.js
+++ b/e2e/suites/project-home.e2e.js
@@ -138,4 +138,11 @@ describe('project home', function() {
expect(watchCounter).to.be.equal(watchCounterOld + 1);
});
+ it('blocked project', async function() {
+ browser.get(browser.params.glob.host + 'project/project-6/');
+ await utils.common.waitLoader();
+ await utils.common.takeScreenshot("project", "blocked-project");
+ expect(browser.getCurrentUrl()).to.be.eventually.equal(browser.params.glob.host + 'blocked-project/project-6/');
+ });
+
});