diff --git a/CHANGELOG.md b/CHANGELOG.md index 2969887e..d452b6f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ # Changelog # - ## 3.1.0 No name yet (no date yet) + +### Features +- Contact with the project: if the projects have this module enabled Taiga users can contact them. - Velocity forecasting. Create sprints according to team velocity. - Remove bower - Add new wysiwyg editor (like the Medunm editor) with emojis, local storage changes, mentions... diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index f8b0a7be..adc6daed 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -74,6 +74,7 @@ urls = { "project-unlike": "/projects/%s/unlike" "project-watch": "/projects/%s/watch" "project-unwatch": "/projects/%s/unwatch" + "project-contact": "contact" "project-transfer-validate-token": "/projects/%s/transfer_validate_token" "project-transfer-accept": "/projects/%s/transfer_accept" "project-transfer-reject": "/projects/%s/transfer_reject" diff --git a/app/images/looking-for-people.png b/app/images/looking-for-people.png index 89800164..01b4e4ed 100644 Binary files a/app/images/looking-for-people.png and b/app/images/looking-for-people.png differ diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json index 9eb45448..c82506d2 100644 --- a/app/locales/taiga/locale-en.json +++ b/app/locales/taiga/locale-en.json @@ -194,6 +194,7 @@ "BUTTON_TITLE": "Upvote/Downvote this item", "COUNTER_TITLE": "{total, plural, one{one vote} other{# votes}}" }, + "CUSTOM_ATTRIBUTES": { "CUSTOM_FIELDS": "Custom Fields", "SAVE": "Save Custom Field", @@ -519,6 +520,7 @@ "RECRUITING": "Is this project looking for people?", "RECRUITING_MESSAGE": "Who are you looking for?", "RECRUITING_PLACEHOLDER": "Define the profiles you are looking for", + "FEEDBACK": "Receive feedback from Taiga users?", "PUBLIC_PROJECT": "Public project", "PRIVATE_PROJECT": "Private project", "PRIVATE_OR_PUBLIC": "What's the difference between public and private projects?", @@ -959,6 +961,10 @@ "UNWATCH": "Unwatch", "UNWATCH_TITLE": "Unwatch this project" } + }, + "CONTACT_BUTTON": { + "CONTACT_TITLE": "Contact the project team", + "CONTACT_BUTTON": "Contact the project" } }, "LIGHTBOX": { @@ -1044,6 +1050,12 @@ "TITLE": "Who do you want to be the new project owner?", "ADD_COMMENT": "Add comment", "BUTTON": "Ask this project member to become the new project owner" + }, + "CONTACT_PROJECT": { + "TITLE": "Send an email to", + "WARNING": "The email will be received by the project admins", + "PLACEHOLDER": "Write your message", + "SEND": "Send" } }, "EPIC": { diff --git a/app/modules/projects/components/contact-project-button/contact-project-button.controller.coffee b/app/modules/projects/components/contact-project-button/contact-project-button.controller.coffee new file mode 100644 index 00000000..839b28b2 --- /dev/null +++ b/app/modules/projects/components/contact-project-button/contact-project-button.controller.coffee @@ -0,0 +1,38 @@ +### +# 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: like-project-button.controller.coffee +### + +class ContactProjectButtonController + @.$inject = ['tgLightboxFactory'] + + constructor: (@lightboxFactory)-> + + launchContactForm: () -> + @lightboxFactory.create( + 'tg-lb-contact-project', + { + "class": "lightbox lightbox-contact-project e2e-lightbox-contact-project", + "project": "project" + }, + { + "project": @.project + } + ) + + +angular.module("taigaProjects").controller("ContactProjectButtonCtrl", ContactProjectButtonController) diff --git a/app/modules/projects/components/contact-project-button/contact-project-button.controller.spec.coffee b/app/modules/projects/components/contact-project-button/contact-project-button.controller.spec.coffee new file mode 100644 index 00000000..13c42bc6 --- /dev/null +++ b/app/modules/projects/components/contact-project-button/contact-project-button.controller.spec.coffee @@ -0,0 +1,50 @@ +### +# 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: contact-project-button.controller.spec.coffee +### + +describe "ContactProjectButton", -> + provide = null + controller = null + mocks = {} + + _mockTgLightboxFactory = () -> + mocks.tgLightboxFactory = { + create: sinon.stub() + } + + provide.value "tgLightboxFactory", mocks.tgLightboxFactory + + _mocks = () -> + module ($provide) -> + provide = $provide + _mockTgLightboxFactory() + + return null + + beforeEach -> + module "taigaProjects" + + _mocks() + + inject ($controller) -> + controller = $controller + + it "Launch Contact Form", () -> + ctrl = controller("ContactProjectButtonCtrl") + ctrl.launchContactForm() + expect(mocks.tgLightboxFactory.create).have.been.called diff --git a/app/modules/projects/components/contact-project-button/contact-project-button.directive.coffee b/app/modules/projects/components/contact-project-button/contact-project-button.directive.coffee new file mode 100644 index 00000000..ed41564f --- /dev/null +++ b/app/modules/projects/components/contact-project-button/contact-project-button.directive.coffee @@ -0,0 +1,32 @@ +### +# 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: contact-project-button.directive.coffee +### + +ContactProjectButtonDirective = -> + return { + scope: {} + controller: "ContactProjectButtonCtrl", + bindToController: { + project: '=' + layout: '@' + } + controllerAs: "vm", + templateUrl: "projects/components/contact-project-button/contact-project-button.html", + } + +angular.module("taigaProjects").directive("tgContactProjectButton", ContactProjectButtonDirective) diff --git a/app/modules/projects/components/contact-project-button/contact-project-button.jade b/app/modules/projects/components/contact-project-button/contact-project-button.jade new file mode 100644 index 00000000..7b6638f4 --- /dev/null +++ b/app/modules/projects/components/contact-project-button/contact-project-button.jade @@ -0,0 +1,10 @@ +button.track-button.contact-team.e2e-contact-team( + title="{{ 'PROJECT.CONTACT_BUTTON.CONTACT_TITLE' | translate }}" + ng-click="vm.launchContactForm()" + ng-class="{'contact-team-large': vm.layout == 'large'}" +) + tg-svg(svg-icon="icon-mail") + span( + ng-if="vm.layout == 'large'" + translate="PROJECT.CONTACT_BUTTON.CONTACT_BUTTON" + ) diff --git a/app/modules/projects/components/contact-project-button/contact-project-button.scss b/app/modules/projects/components/contact-project-button/contact-project-button.scss new file mode 100644 index 00000000..ece4ccba --- /dev/null +++ b/app/modules/projects/components/contact-project-button/contact-project-button.scss @@ -0,0 +1,14 @@ +.contact-team { + margin-left: .75rem; + &-large { + @include font-size(small); + @include font-type(light); + justify-content: center; + margin-left: 0; + width: 100%; + .icon-mail { + margin-right: .5rem; + vertical-align: center; + } + } +} diff --git a/app/modules/projects/components/lb-contact-project/lb-contact-project.controller.coffee b/app/modules/projects/components/lb-contact-project/lb-contact-project.controller.coffee new file mode 100644 index 00000000..33657083 --- /dev/null +++ b/app/modules/projects/components/lb-contact-project/lb-contact-project.controller.coffee @@ -0,0 +1,41 @@ +### +# 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: lb-contact-team.controller.coffee +### + +class ContactProjectLbController + @.$inject = [ + "lightboxService", + "tgResources", + "$tgConfirm", + ] + + constructor: (@lightboxService, @rs, @confirm) -> + @.contact = {} + + contactProject: () -> + project = @.project.get('id') + message = @.contact.message + + promise = @rs.projects.contactProject(project, message) + @.sendingFeedback = true + promise.then => + @lightboxService.closeAll() + @.sendingFeedback = false + @confirm.notify("success") + +angular.module("taigaProjects").controller("ContactProjectLbCtrl", ContactProjectLbController) diff --git a/app/modules/projects/components/lb-contact-project/lb-contact-project.controller.spec.coffee b/app/modules/projects/components/lb-contact-project/lb-contact-project.controller.spec.coffee new file mode 100644 index 00000000..6700e424 --- /dev/null +++ b/app/modules/projects/components/lb-contact-project/lb-contact-project.controller.spec.coffee @@ -0,0 +1,85 @@ +### +# 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: lb/contact-project-button.controller.spec.coffee +### + +describe "LbContactProject", -> + provide = null + controller = null + mocks = {} + + _mockTgLightboxSercice = () -> + mocks.tglightboxService = { + closeAll: sinon.stub() + } + + provide.value "lightboxService", mocks.tglightboxService + + _mockTgResources = () -> + mocks.tgResources = { + projects: { + contactProject: sinon.stub() + } + } + + provide.value "tgResources", mocks.tgResources + + _mockTgConfirm = () -> + mocks.tgConfirm = { + notify: sinon.stub() + } + + provide.value "$tgConfirm", mocks.tgConfirm + + _mocks = () -> + module ($provide) -> + provide = $provide + _mockTgLightboxSercice() + _mockTgResources() + _mockTgConfirm() + + return null + + beforeEach -> + module "taigaProjects" + + _mocks() + + inject ($controller) -> + controller = $controller + + it "Contact Project", (done) -> + ctrl = controller("ContactProjectLbCtrl") + ctrl.contact = { + message: 'abcde' + } + ctrl.project = Immutable.fromJS({ + id: 1 + }) + + project = ctrl.project.get('id') + message = ctrl.contact.message + + promise = mocks.tgResources.projects.contactProject.withArgs(project, message).promise().resolve() + + ctrl.sendingFeedback = true + + ctrl.contactProject().then () -> + expect(mocks.tglightboxService.closeAll).have.been.called + expect(ctrl.sendingFeedback).to.be.false + expect(mocks.tgConfirm.notify).have.been.calledWith("success") + done() diff --git a/app/modules/projects/components/lb-contact-project/lb-contact-project.directive.coffee b/app/modules/projects/components/lb-contact-project/lb-contact-project.directive.coffee new file mode 100644 index 00000000..8a8bd88f --- /dev/null +++ b/app/modules/projects/components/lb-contact-project/lb-contact-project.directive.coffee @@ -0,0 +1,37 @@ +### +# 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: lb-contact-team.directive.coffee +### + +ContactProjectLbDirective = (lightboxService) -> + + @.inject = ['lightboxService'] + + link = (scope, el) -> + lightboxService.open(el) + + return { + controller: "ContactProjectLbCtrl", + bindToController: { + project: '=' + } + controllerAs: "vm", + templateUrl: "projects/components/lb-contact-project/lb-contact-project.html", + link: link + } + +angular.module("taigaProjects").directive("tgLbContactProject", ["lightboxService", ContactProjectLbDirective]) diff --git a/app/modules/projects/components/lb-contact-project/lb-contact-project.jade b/app/modules/projects/components/lb-contact-project/lb-contact-project.jade new file mode 100644 index 00000000..f43fd711 --- /dev/null +++ b/app/modules/projects/components/lb-contact-project/lb-contact-project.jade @@ -0,0 +1,27 @@ +tg-lightbox-close + +form.lightbox-contact-project-container + img.lightbox-contact-project-logo( + ng-if="vm.project.logo_big_url" + alt="{{vm.project.get('name')}}" + ng-src="vm.project.logo_big_url" + ) + img.lightbox-contact-project-logo( + ng-if="!vm.project.logo_big_url" + tg-project-logo-big-src="vm.project" + alt="{{vm.project.get('name')}}" + ) + h2.lightbox-contact-project-title(translate="LIGHTBOX.CONTACT_PROJECT.TITLE") + h3.lightbox-contact-project-name {{vm.project.get('name')}} + p(translate="LIGHTBOX.CONTACT_PROJECT.WARNING") + textarea.lightbox-contact-project-message.e2e-lightbox-contact-project-message( + ng-model="vm.contact.message" + required + placeholder="{{'LIGHTBOX.CONTACT_PROJECT.PLACEHOLDER' | translate}}" + ) + button.button-green.lightbox-contact-project-button.e2e-lightbox-contact-project-button( + translate="LIGHTBOX.CONTACT_PROJECT.SEND" + ng-click="vm.contactProject()" + tg-loading="vm.sendingFeedback" + ng-disabled="!vm.contact.message.length" + ) diff --git a/app/modules/projects/components/lb-contact-project/lb-contact-project.scss b/app/modules/projects/components/lb-contact-project/lb-contact-project.scss new file mode 100644 index 00000000..4cc6e3af --- /dev/null +++ b/app/modules/projects/components/lb-contact-project/lb-contact-project.scss @@ -0,0 +1,29 @@ +.lightbox-contact-project { + align-items: center; + display: flex; + justify-content: center; + &-container { + max-width: 600px; + text-align: center; + width: 90%; + } + &-logo { + width: 5rem; + } + &-title { + margin: 0; + } + &-name { + @include font-size(larger); + color: $primary; + margin-bottom: 1rem; + } + &-message { + max-height: 400px; + } + &-button { + display: block; + margin-top: .5rem; + width: 100%; + } +} diff --git a/app/modules/projects/components/like-project-button/like-project-button.jade b/app/modules/projects/components/like-project-button/like-project-button.jade index de8da23f..57fc69b0 100644 --- a/app/modules/projects/components/like-project-button/like-project-button.jade +++ b/app/modules/projects/components/like-project-button/like-project-button.jade @@ -1,5 +1,4 @@ -a.track-button.like-button.like-container( - href="", +button.track-button.like-button( title="{{ 'PROJECT.LIKE_BUTTON.BUTTON_TITLE' | translate }}" ng-click="vm.toggleLike()" ng-class="{'active':vm.project.get('is_fan'), 'is-hover':vm.project.get('is_fan') && vm.isMouseOver}" @@ -21,9 +20,7 @@ a.track-button.like-button.like-container( ng-if="vm.project.get('is_fan') && vm.isMouseOver" translate="PROJECT.LIKE_BUTTON.UNLIKE" ) - span.track-button-counter( title="{{ 'PROJECT.LIKE_BUTTON.COUNTER_TITLE'|translate:{total:vm.project.get(\"total_fans\")||0}:'messageformat' }}", tg-loading="vm.loading" - ) - | {{ vm.project.get('total_fans') }} + ) {{ vm.project.get('total_fans') }} diff --git a/app/modules/projects/components/watch-project-button/watch-project-button.jade b/app/modules/projects/components/watch-project-button/watch-project-button.jade index dff7401a..2ad65e58 100644 --- a/app/modules/projects/components/watch-project-button/watch-project-button.jade +++ b/app/modules/projects/components/watch-project-button/watch-project-button.jade @@ -1,5 +1,4 @@ -a.track-button.watch-button.watch-container( - href="", +button.track-button.watch-button( title="{{ 'PROJECT.WATCH_BUTTON.BUTTON_TITLE' | translate }}" ng-click="vm.toggleWatcherOptions()" ng-class="{'active': vm.project.get('is_watcher')}" @@ -7,24 +6,25 @@ a.track-button.watch-button.watch-container( span.track-inner span.track-icon tg-svg(svg-icon="icon-watch") - span(ng-if="!vm.project.get('is_watcher')", translate="PROJECT.WATCH_BUTTON.WATCH") - span(ng-if="vm.project.get('is_watcher')", translate="PROJECT.WATCH_BUTTON.WATCHING") + span( + ng-if="!vm.project.get('is_watcher')" + translate="PROJECT.WATCH_BUTTON.WATCH" + ) + span( + ng-if="vm.project.get('is_watcher')" + translate="PROJECT.WATCH_BUTTON.WATCHING" + ) tg-svg.watch-options-arrow(svg-icon="icon-arrow-down") span.track-button-counter( - title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.project.get(\"total_watchers\")||0}:'messageformat' }}", + title="{{ 'PROJECT.WATCH_BUTTON.COUNTER_TITLE'|translate:{total:vm.project.get(\"total_watchers\")||0}:'messageformat' }}" tg-loading="vm.loading" - ) - | {{ vm.project.get('total_watchers') }} + ) {{ vm.project.get('total_watchers') }} ul.watch-options( ng-class="{'hidden': !vm.showWatchOptions}" ng-mouseleave="vm.closeWatcherOptions()" ) - //- NOTIFY LEVEL CHOICES: - //- 1 - Only involved - //- 2 - Receive all - //- 3 - No notifications li a( diff --git a/app/modules/projects/project/project.jade b/app/modules/projects/project/project.jade index 01feadbc..fd5949e1 100644 --- a/app/modules/projects/project/project.jade +++ b/app/modules/projects/project/project.jade @@ -25,6 +25,10 @@ div.wrapper div.track-buttons-container(ng-if="vm.user") tg-like-project-button(project="vm.project") tg-watch-project-button(project="vm.project") + tg-contact-project-button( + ng-if="vm.project.get('is_contact_activated')" + project="vm.project" + ) div.track-container(ng-if="!vm.user") .list-itemtype-track @@ -56,9 +60,13 @@ div.wrapper src="/#{v}/images/looking-for-people.png" title="{{'PROJECT.LOOKING_FOR_PEOPLE' | translate}}" ) - h3 {{'PROJECT.LOOKING_FOR_PEOPLE' | translate}} - p(ng-if="vm.project.get('looking_for_people_note')") - | {{::vm.project.get('looking_for_people_note')}} + h3(ng-class="{'is-empty': !vm.project.get('looking_for_people_note')}") {{'PROJECT.LOOKING_FOR_PEOPLE' | translate}} + p(ng-if="vm.project.get('looking_for_people_note')") {{::vm.project.get('looking_for_people_note')}} + tg-contact-project-button( + ng-if="vm.project.get('is_contact_activated')" + project="vm.project" + layout="large" + ) h2.title {{"PROJECT.SECTION.TEAM" | translate}} ul.involved-team diff --git a/app/modules/resources/projects-resource.service.coffee b/app/modules/resources/projects-resource.service.coffee index 9df02c3a..82942b37 100644 --- a/app/modules/resources/projects-resource.service.coffee +++ b/app/modules/resources/projects-resource.service.coffee @@ -108,6 +108,15 @@ Resource = (urlsService, http, paginateResponseService) -> url = urlsService.resolve("project-unwatch", projectId) return http.post(url) + service.contactProject = (projectId, message) -> + params = { + project: projectId, + comment: message + } + + url = urlsService.resolve("project-contact") + return http.post(url, params) + service.transferValidateToken = (projectId, token) -> data = { token: token diff --git a/app/partials/admin/admin-project-profile.jade b/app/partials/admin/admin-project-profile.jade index 50a41dc9..bd37c9cb 100644 --- a/app/partials/admin/admin-project-profile.jade +++ b/app/partials/admin/admin-project-profile.jade @@ -119,6 +119,18 @@ div.wrapper( ng-model="project.looking_for_people_note" placeholder="{{ 'ADMIN.PROJECT_PROFILE.RECRUITING_PLACEHOLDER' | translate }}" ) + + fieldset.get-feedback + .get-feedback-inner + span {{ 'ADMIN.PROJECT_PROFILE.FEEDBACK' | translate }} + div.check + input( + type="checkbox", + ng-model="project.is_contact_activated" + ) + div + span.check-text.check-yes(translate="COMMON.YES") + span.check-text.check-no(translate="COMMON.NO") tg-admin-project-restrictions(project="project") diff --git a/app/styles/components/track-btn.scss b/app/styles/components/track-btn.scss index 221d893a..62d76f5a 100644 --- a/app/styles/components/track-btn.scss +++ b/app/styles/components/track-btn.scss @@ -1,6 +1,3 @@ -////////////////////// -//Watch like buttons -////////////////////// .track-buttons-container { @include font-size(small); @@ -9,75 +6,80 @@ .track-button { align-items: stretch; - display: inline-flex; - position: relative; - .track-inner { - align-items: center; - background: $mass-white; - border-radius: 4px 0 0 4px; - display: flex; - flex: 1; - flex-basis: 140px; - justify-content: flex-start; - margin-right: .1rem; - min-width: 140px; - &:hover { - background: darken($mass-white, 5%); - transition: background .3s; - } - } - .watch-options-arrow { - margin: 0 .5rem 0 auto; - svg { - @include svg-size(.75rem); - } - } - &:hover { - color: $blackish; - } + display: flex; + margin: 0; + padding: 0; &.active { .track-inner { background: rgba($primary-light, .2); } - .track-icon { - svg { - fill: $primary; - } + .icon { + fill: $primary; + } + .track-button-counter { + background: rgba($primary-light, .4); } } - &.watch-container { - margin-right: 1rem; - position: relative; - } - .track-icon { - padding: .3rem .6rem .3rem .75rem; - svg { - fill: $grayer; - position: relative; - top: 2px; + &.is-hover { + .track-inner { + background: lighten($red, 10%); + color: $whitish; + transition: background .2s; + } + .icon { + fill: $red-light; + } + .track-button-counter { + background: $red; + color: $whitish; + transition: background .2s; } } - .track-button-counter { - align-items: center; - border: 1px solid $whitish; - display: flex; - justify-content: center; - min-width: 2rem; + .watch-options-arrow { + margin-left: auto; + } + .icon-arrow-down { + @include svg-size(.75rem); } } -.watch-button, -.like-button { - &.active { - &.is-hover { - .track-inner { - background: $red; - color: $whitish; - transition: background .3s; - } - svg { - fill: $red-light; - } - } + +.track-inner { + align-items: center; + background: $whitish; + border-radius: 4px 0 0 4px; + display: flex; + flex: 1; + flex-basis: 140px; + justify-content: flex-start; + min-width: 140px; + padding: .25rem 1rem; + &:hover { + background: darken($whitish, 5%); + transition: background .3s; + } +} + +.track-icon { + fill: $grayer; + margin-right: .5rem; + position: relative; + top: 2px; +} + +.track-button-counter { + align-items: center; + background: darken($whitish, 5%); + border-radius: 0 4px 4px 0; + padding: .25rem .75rem; +} + +.contact-team { + background: $whitish; + border-radius: 4px; + padding: .25rem .75rem; + &:hover { + background: darken($whitish, 5%); + transition: background .3s; } } diff --git a/app/styles/modules/admin/admin-project-profile.scss b/app/styles/modules/admin/admin-project-profile.scss index 31060629..0984f6f6 100644 --- a/app/styles/modules/admin/admin-project-profile.scss +++ b/app/styles/modules/admin/admin-project-profile.scss @@ -1,13 +1,18 @@ @import '../dependencies/mixins/profile-form'; .project-details { @include profile-form; - .looking-for-people { + .looking-for-people, + .get-feedback { @include font-type(light); border-bottom: 1px solid $whitish; - border-top: 1px solid $whitish; padding: 1rem 0; } - .looking-for-people-selector { + .looking-for-people { + border-top: 1px solid $whitish; + margin-bottom: 0; + } + .looking-for-people-selector, + .get-feedback-inner { align-items: center; display: flex; svg { diff --git a/app/styles/modules/home-project.scss b/app/styles/modules/home-project.scss index 3da70541..db929b69 100644 --- a/app/styles/modules/home-project.scss +++ b/app/styles/modules/home-project.scss @@ -79,9 +79,16 @@ h3 { @include font-size(small); } + .is-empty { + margin-bottom: .5rem; + } p { @include font-size(small); @include font-type(light); + margin-bottom: .5rem; + } + .contact-team { + margin-bottom: 1rem; } } .involved-data { diff --git a/app/svg/sprite.svg b/app/svg/sprite.svg index 869e7c00..bfbdeb26 100644 --- a/app/svg/sprite.svg +++ b/app/svg/sprite.svg @@ -454,5 +454,8 @@ Broken Link + + + diff --git a/e2e/helpers/project-detail-helper.js b/e2e/helpers/project-detail-helper.js index 88f2c81a..784612d2 100644 --- a/e2e/helpers/project-detail-helper.js +++ b/e2e/helpers/project-detail-helper.js @@ -14,6 +14,14 @@ helper.toggleIsLookingForPeople = function() { helper.lookingForPeople().click(); }; +helper.receiveFeedback = function() { + return $$('.get-feedback input').get(0); +}; + +helper.togglereceiveFeedback = function() { + helper.receiveFeedback().click(); +}; + helper.editLogo = function() { let inputFile = $('#logo-field'); diff --git a/e2e/suites/admin/project/project-detail.e2e.js b/e2e/suites/admin/project/project-detail.e2e.js index 033015a4..2034f4d0 100644 --- a/e2e/suites/admin/project/project-detail.e2e.js +++ b/e2e/suites/admin/project/project-detail.e2e.js @@ -67,6 +67,21 @@ describe('project detail', function() { expect(utils.notifications.success.open()).to.be.eventually.equal(true); }); + it('receive feedback', async function() { + let checked = !! await adminHelper.receiveFeedback().getAttribute('checked'); + + if(!checked) { + adminHelper.togglereceiveFeedback(); + } + + $('button[type="submit"]').click(); + + checked = !! await adminHelper.receiveFeedback().getAttribute('checked'); + + expect(checked).to.be.true; + expect(utils.notifications.success.open()).to.be.eventually.equal(true); + }); + it('edit logo', async function() { let imageContainer = $('.image-container'); diff --git a/e2e/suites/project-home.e2e.js b/e2e/suites/project-home.e2e.js index 087e3477..6278abd7 100644 --- a/e2e/suites/project-home.e2e.js +++ b/e2e/suites/project-home.e2e.js @@ -14,7 +14,7 @@ describe('project home', function() { await utils.common.takeScreenshot("project", "home-like"); //reset - let link = $('tg-like-project-button a'); + let link = $('tg-like-project-button button'); let likeActive = await utils.common.hasClass(link, 'active'); if (!likeActive) { @@ -47,7 +47,7 @@ describe('project home', function() { }); */ it('unlike', async function() { - let link = $('tg-like-project-button a'); + let link = $('tg-like-project-button button'); let likesCounterOld = parseInt(await link.$('.track-button-counter').getText(), 10); link.click(); @@ -62,7 +62,7 @@ describe('project home', function() { }); it('like', async function() { - let link = $('tg-like-project-button a'); + let link = $('tg-like-project-button button'); let likesCounterOld = parseInt(await link.$('.track-button-counter').getText(), 10); link.click(); @@ -77,8 +77,24 @@ describe('project home', function() { expect(likesCounter).to.be.equal(likesCounterOld + 1); }); + it('contact project', async function() { + $('tg-contact-project-button > .e2e-contact-team').click(); + + let contactProjectLb = $('div[tg-lb-contact-project]'); + + await utils.lightbox.open(contactProjectLb); + await utils.common.takeScreenshot("project", "contact-form"); + + let form = $('.e2e-lightbox-contact-project'); + + await form.$('.e2e-lightbox-contact-project-message').sendKeys('contact'); + form.$('.e2e-lightbox-contact-project-button').click(); + await utils.notifications.success.open(); + + }); + it('unwatch', async function() { - let link = $('tg-watch-project-button > a'); + let link = $('tg-watch-project-button > button'); let watchOptions = $('tg-watch-project-button .watch-options'); let watchCounterOld = parseInt(await link.$('.track-button-counter').getText(), 10); @@ -104,7 +120,7 @@ describe('project home', function() { }); it('watch', async function() { - let link = $('tg-watch-project-button > a'); + let link = $('tg-watch-project-button > button'); let watchOptions = $('tg-watch-project-button .watch-options'); let watchCounterOld = parseInt(await link.$('.track-button-counter').getText(), 10);