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/'); + }); + });