From 967391412d027b2419db8dfe6b3602ec8169b594 Mon Sep 17 00:00:00 2001 From: Allister Antosik Date: Sun, 29 Nov 2015 22:04:57 +0000 Subject: [PATCH] Add 'assign to me' button One of the most common scenarios I found while using Taiga is that I assign User Stories, Tasks or Issues to myself, looking at other tools such as Gitlab it comes with a quick 'Assign to me' button for merge requests. In this pull request I have added a 'Assign to me' button with the same styling as the 'Add Watchers' button. This shows in Stories, Tasks and Issues. --- AUTHORS.rst | 17 ++++--- CHANGELOG.md | 1 + app/coffee/modules/common/components.coffee | 27 ++++++---- app/locales/taiga/locale-en.json | 4 +- .../common/components/assigned-to.jade | 49 +++++++++++++------ app/styles/modules/common/assigned-to.scss | 16 +++--- 6 files changed, 74 insertions(+), 40 deletions(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index b061f9f6..31e3c168 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -16,16 +16,17 @@ And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS -- people who have submitted patches, reported bugs, added translations, helped answer newbie questions, and generally made Taiga that much better: -- Pilar Esteban -- Guilhem Got -- Ramiro Sánchez -- Miguel de la Cruz +- Allister Antosik - Andrea Stagi -- Jordan Rinke -- Wil Wade +- Brett Profitt +- Chris Wilson - Daniel Koch - Florian Bezagu +- Guilhem Got +- Jordan Rinke +- Miguel de la Cruz +- Pilar Esteban +- Ramiro Sánchez - Ryan Swanstrom -- Chris Wilson -- Brett Profitt - Vlad Topala +- Wil Wade diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a67b5f2..1f8d388f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Drag files from desktop in wysiwyg textareas. - New design for the detail pages slidebar. - Sticky project navigation bar. +- Added 'Assign to me' button in User Stories, Tasks and Issues detail pages. (thanks to [@allistera](https://github.com/allistera)). ### Misc - Lots of small and not so small bugfixes. diff --git a/app/coffee/modules/common/components.coffee b/app/coffee/modules/common/components.coffee index e10451eb..e5d3850d 100644 --- a/app/coffee/modules/common/components.coffee +++ b/app/coffee/modules/common/components.coffee @@ -258,7 +258,7 @@ module.directive("tgWatchers", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgQqueu ## Assigned to directive ############################################################################# -AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template, $translate, $compile) -> +AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template, $translate, $compile, $currentUserService) -> # You have to include a div with the tg-lb-assignedto directive in the page # where use this directive template = $template.get("common/components/assigned-to.html", true) @@ -287,18 +287,21 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template return promise renderAssignedTo = (assignedObject) -> - if assignedObject?.assigned_to_extra_info? - assignedTo = assignedObject?.assigned_to_extra_info + if assignedObject?.assigned_to? + fullName = assignedObject.assigned_to_extra_info.full_name_display + photo = assignedObject.assigned_to_extra_info.photo + isUnassigned = false else - assignedTo = { - full_name_display: $translate.instant("COMMON.ASSIGNED_TO.NOT_ASSIGNED") - photo: "/#{window._version}/images/unnamed.png" - } + fullName = $translate.instant("COMMON.ASSIGNED_TO.ASSIGN") + photo = "/#{window._version}/images/unnamed.png" + isUnassigned = true isIocaine = assignedObject?.is_iocaine ctx = { - assignedTo: assignedTo + fullName: fullName + photo: photo + isUnassigned: isUnassigned isEditable: isEditable() isIocaine: isIocaine } @@ -311,6 +314,12 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template $scope.$apply -> $rootscope.$broadcast("assigned-to:add", $model.$modelValue) + $el.on "click", ".assign-to-me", (event) -> + event.preventDefault() + return if not isEditable() + $model.$modelValue.assigned_to = $currentUserService.getUser().get('id') + save($currentUserService.getUser().get('id')) + $el.on "click", ".icon-delete", (event) -> event.preventDefault() return if not isEditable() @@ -337,7 +346,7 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template require:"ngModel" } -module.directive("tgAssignedTo", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgLoading", "$tgQqueue", "$tgTemplate", "$translate", "$compile", +module.directive("tgAssignedTo", ["$rootScope", "$tgConfirm", "$tgRepo", "$tgLoading", "$tgQqueue", "$tgTemplate", "$translate", "$compile","tgCurrentUserService", AssignedToDirective]) diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json index 378421bf..199bb05c 100644 --- a/app/locales/taiga/locale-en.json +++ b/app/locales/taiga/locale-en.json @@ -143,11 +143,13 @@ }, "ASSIGNED_TO": { "NOT_ASSIGNED": "Not assigned", + "ASSIGN": "Assign", "DELETE_ASSIGNMENT": "Delete assignment", "REMOVE_ASSIGNED": "Remove assigned", "TOO_MANY": "...too many users, keep filtering", "CONFIRM_UNASSIGNED": "Are you sure you want to leave it unassigned?", - "TITLE_ACTION_EDIT_ASSIGNMENT": "Edit assignment" + "TITLE_ACTION_EDIT_ASSIGNMENT": "Edit assignment", + "SELF": "Assign to me" }, "STATUS": { "CLOSED": "Closed", diff --git a/app/partials/common/components/assigned-to.jade b/app/partials/common/components/assigned-to.jade index 79ae8748..cd3c90ef 100644 --- a/app/partials/common/components/assigned-to.jade +++ b/app/partials/common/components/assigned-to.jade @@ -1,22 +1,41 @@ -<% if (assignedTo) { %> -.user-avatar(class!="<% if(isIocaine){ %> is-iocaine <% }; %>") - img(src!="<%- assignedTo.photo %>", alt!="<%- assignedTo.full_name_display %>") - <% if(isIocaine){ %> +.user-avatar(class!="<% if (isIocaine) { %> is-iocaine <% }; %>") + img(src!="<%- photo %>", alt!="<%- fullName %>") + <% if (isIocaine) { %> .iocaine-symbol(title="{{ 'TASK.TITLE_ACTION_IOCAINE' | translate }}") include ../../../svg/iocaine.svg <% }; %> -<% } %> .assigned-to - span.assigned-title(translate="COMMON.FIELDS.ASSIGNED_TO") + <% if (isUnassigned) { %> + .assigned-title {{ "COMMON.ASSIGNED_TO.NOT_ASSIGNED" | translate }} + <% } else { %> + .assigned-title {{ "COMMON.FIELDS.ASSIGNED_TO" | translate }} + <% }; %> - a(href="" title="{{ 'COMMON.ASSIGNED_TO.TITLE_ACTION_EDIT_ASSIGNMENT'|translate }}", - class!="user-assigned <% if(isEditable){ %>editable<% }; %>") - span.assigned-name - <%- assignedTo.full_name_display %> - <% if(isEditable){ %> - span.icon.icon-arrow-bottom - <% }; %> - <% if (assignedTo!==null && isEditable) { %> - a.icon.icon-delete(href="" title="{{'COMMON.ASSIGNED_TO.DELETE_ASSIGNMENT' | translate}}") + .assigned-to-options + a( + href="" + title="{{ 'COMMON.ASSIGNED_TO.TITLE_ACTION_EDIT_ASSIGNMENT'|translate }}" + class!="user-assigned <% if (isEditable) { %>editable<% }; %>" + ) + span.assigned-name + <%- fullName %> + <% if (isEditable && !isUnassigned) { %> + span.icon.icon-arrow-bottom + <% }; %> + + <% if (isEditable && isUnassigned) { %> + span or + a.assign-to-me( + href="#" + title="{{'COMMON.ASSIGNED_TO.SELF' | translate}}" + ) + span {{ "COMMON.ASSIGNED_TO.SELF" | translate }} + <% }; %> + + <% if (isEditable && !isUnassigned) { %> + a.icon.icon-delete( + href="" + title="{{'COMMON.ASSIGNED_TO.DELETE_ASSIGNMENT' | translate}}" + ) <% } %> diff --git a/app/styles/modules/common/assigned-to.scss b/app/styles/modules/common/assigned-to.scss index 15e7d2b9..a30a5e48 100644 --- a/app/styles/modules/common/assigned-to.scss +++ b/app/styles/modules/common/assigned-to.scss @@ -57,20 +57,22 @@ display: block; margin: .2rem 0 .25rem; } - .user-assigned { - @extend %large; + .assigned-to-options { + display: inline-block; + } + .user-assigned, + .assign-to-me { color: $primary; cursor: default; - &.editable { + &:hover { cursor: pointer; } .icon { vertical-align: middle; } - } - .assigned-name { - @include ellipsis(80%); - display: inline-block; + > span { + @include ellipsis(80%); + } } .icon-delete { color: $gray-light;