From 9e561d9b00e63f507c47b2da08aa79451fcfc7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Mon, 9 Apr 2018 16:30:10 +0200 Subject: [PATCH] Lightbox for due date editing --- app/coffee/modules/common/confirm.coffee | 6 +- app/coffee/modules/common/lightboxes.coffee | 74 ++++++++++++++++++- app/locales/taiga/locale-en.json | 17 +++++ .../common/lightbox/lightbox-due-date.jade | 44 +++++++++++ app/styles/modules/common/lightbox.scss | 60 +++++++++++++++ 5 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 app/partials/common/lightbox/lightbox-due-date.jade diff --git a/app/coffee/modules/common/confirm.coffee b/app/coffee/modules/common/confirm.coffee index 67227343..af2948c8 100644 --- a/app/coffee/modules/common/confirm.coffee +++ b/app/coffee/modules/common/confirm.coffee @@ -86,8 +86,10 @@ class ConfirmService extends taiga.Service return defered.promise - askOnDelete: (title, message) -> - return @.ask(title, @translate.instant("NOTIFICATION.ASK_DELETE"), message) + askOnDelete: (title, message, subtitle) -> + if not subtitle? + subtitle = @translate.instant("NOTIFICATION.ASK_DELETE") + return @.ask(title, subtitle, message) askChoice: (title, subtitle, choices, replacement, warning, lightboxSelector=".lightbox-ask-choice") -> defered = @q.defer() diff --git a/app/coffee/modules/common/lightboxes.coffee b/app/coffee/modules/common/lightboxes.coffee index 9ff7e739..f17ef740 100644 --- a/app/coffee/modules/common/lightboxes.coffee +++ b/app/coffee/modules/common/lightboxes.coffee @@ -54,10 +54,10 @@ class LightboxService extends taiga.Service @animationFrame.add -> $el.addClass("open") $el.one "transitionend", => - firstField = $el.find('input,textarea').first() + firstField = $el.find('input:not(.no-focus),textarea:not(.no-focus)').first() if firstField.length - $el.find('input,textarea').first().focus() + firstField.focus() else if document.activeElement $(document.activeElement).blur() @@ -802,3 +802,73 @@ LightboxLeaveProjectWarningDirective = (lightboxService, $template, $compile) -> } module.directive("tgLightboxLeaveProjectWarning", ["lightboxService", LightboxLeaveProjectWarningDirective]) + + +############################################################################# +## Set Due Date Lightbox Directive +############################################################################# + +SetDueDateDirective = (lightboxService, $loading, $translate, $confirm, $modelTransform) -> + link = ($scope, $el, attrs) -> + prettyDate = $translate.instant("COMMON.PICKERDATE.FORMAT") + lightboxService.open($el) + + if ($scope.object.due_date) + $scope.new_due_date = moment($scope.object.due_date).format(prettyDate) + + $el.on "click", ".suggestion", (event) -> + target = angular.element(event.currentTarget) + quantity = target.data('quantity') + unit = target.data('unit') + value = moment().add(quantity, unit).format(prettyDate) + $el.find(".due-date").val(value) + + save = -> + currentLoading = $loading() + .target($el.find(".submit-button")) + .start() + + transform = $modelTransform.save (object) -> + new_due_date = $('.due-date').val() + object.due_date = if (new_due_date) \ + then moment(new_due_date, prettyDate).format("YYYY-MM-DD") \ + else null + return object + + transform.then -> + $confirm.notify("success") + + transform.then null, -> + $confirm.notify("error") + + transform.finally -> + currentLoading.finish() + lightboxService.close($el) + + $el.on "click", ".submit-button", (event) -> + event.preventDefault() + save() + + remove = -> + title = $translate.instant("LIGHTBOX.DELETE_DUE_DATE.TITLE") + subtitle = $translate.instant("LIGHTBOX.DELETE_DUE_DATE.SUBTITLE") + message = moment($scope.object.due_date).format(prettyDate) + + $confirm.askOnDelete(title, message, subtitle).then (askResponse) -> + askResponse.finish() + $('.due-date').val(null) + $scope.object.due_date_reason = null + save() + + $el.on "click", ".delete-due-date", (event) -> + event.preventDefault() + remove() + + return { + templateUrl: 'common/lightbox/lightbox-due-date.html', + link: link, + scope: true + } + +module.directive("tgLbSetDueDate", ["lightboxService", "$tgLoading", "$translate", "$tgConfirm" + "$tgQueueModelTransformation", SetDueDateDirective]) diff --git a/app/locales/taiga/locale-en.json b/app/locales/taiga/locale-en.json index 9347aff7..fde336a3 100644 --- a/app/locales/taiga/locale-en.json +++ b/app/locales/taiga/locale-en.json @@ -1076,6 +1076,10 @@ "EDIT_US": "Edit user story", "CONFIRM_CLOSE": "You have not saved changes.\nAre you sure you want to close the form?" }, + "DELETE_DUE_DATE": { + "TITLE": "Delete due date", + "SUBTITLE": "Are you sure you want to delete this due date?" + }, "DELETE_SPRINT": { "TITLE": "Delete sprint" }, @@ -1106,6 +1110,19 @@ "WARNING": "The email will be received by the project admins", "PLACEHOLDER": "Write your message", "SEND": "Send" + }, + "SET_DUE_DATE": { + "TITLE": "Set due date", + "PLACEHOLDER_DUE_DATE": "Select date", + "REASON_FOR_DUE_DATE": "Reason for the due date", + "PLACEHOLDER_REASON_FOR_DUE_DATE": "Is this due date due to something?", + "SUGGESTIONS": { + "IN_ONE_WEEK": "In one week", + "IN_TWO_WEEKS": "In two weeks", + "IN_ONE_MONTH": "In one month", + "IN_THREE_MONTHS": "In three months" + }, + "TITLE_ACTION_DELETE_DUE_DATE": "Delete due date" } }, "EPIC": { diff --git a/app/partials/common/lightbox/lightbox-due-date.jade b/app/partials/common/lightbox/lightbox-due-date.jade new file mode 100644 index 00000000..8529338f --- /dev/null +++ b/app/partials/common/lightbox/lightbox-due-date.jade @@ -0,0 +1,44 @@ +tg-lightbox-close + +form + h2.title(translate="LIGHTBOX.SET_DUE_DATE.TITLE") + + fieldset.date + input.due-date.no-focus( + type="text" + name="due_date" + picker-value="{{ new_due_date }}" + data-required="true" + tg-date-selector + placeholder="{{'LIGHTBOX.SET_DUE_DATE.PLACEHOLDER_DUE_DATE' | translate}}" + ) + + ul.due-date-suggestions + li.suggestion.clickable(data-quantity=1, data-unit="weeks") + span {{ 'LIGHTBOX.SET_DUE_DATE.SUGGESTIONS.IN_ONE_WEEK' | translate }} + li.suggestion.clickable(data-quantity=2, data-unit="weeks") + span {{ 'LIGHTBOX.SET_DUE_DATE.SUGGESTIONS.IN_TWO_WEEKS' | translate }} + li.suggestion.clickable(data-quantity=1, data-unit="months") + span {{ 'LIGHTBOX.SET_DUE_DATE.SUGGESTIONS.IN_ONE_MONTH' | translate }} + li.suggestion.clickable(data-quantity=3, data-unit="months") + span {{ 'LIGHTBOX.SET_DUE_DATE.SUGGESTIONS.IN_THREE_MONTHS' | translate }} + + fieldset.reason + span {{ 'LIGHTBOX.SET_DUE_DATE.REASON_FOR_DUE_DATE' | translate }} + textarea.due-date-reason.no-focus( + name="due_date_reason" + ng-attr-placeholder="{{'LIGHTBOX.SET_DUE_DATE.PLACEHOLDER_REASON_FOR_DUE_DATE' | translate}}" + ng-model="object.due_date_reason" + ) + + button.button-green.submit-button( + type="submit" + title="{{'COMMON.SAVE' | translate}}" + translate="COMMON.SAVE" + ) + + a.delete-due-date( + href="" + title="{{'LIGHTBOX.SET_DUE_DATE.TITLE_ACTION_DELETE_DUE_DATE' | translate}}" + ) + tg-svg(svg-icon="icon-trash") diff --git a/app/styles/modules/common/lightbox.scss b/app/styles/modules/common/lightbox.scss index 255254d3..a0cb4161 100644 --- a/app/styles/modules/common/lightbox.scss +++ b/app/styles/modules/common/lightbox.scss @@ -540,3 +540,63 @@ width: 500px; } } + +.lightbox-set-due-date { + z-index: 9999; + form { + flex-basis: 600px; + flex-flow: 0; + max-width: 600px; + } + .date { + margin: 2rem 0 1rem; + } + .reason textarea { + margin-top: .5rem; + } + .due-date-suggestions { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: 1rem 0 .5rem; + } + .suggestion { + background: rgba($gray-lighter, .2); + color: $gray-lighter; + justify-content: flex-start; + margin: 0 .5rem .5rem; + min-height: 2rem; + padding: .5rem .75rem; + position: relative; + &:first-child { + margin-left: 0; + } + &:nth-child(4n + 4) { + margin-right: 0; + } + &.clickable { + &:hover, + &.active { + background: rgba($primary-light, .9); + color: $white; + } + } + } + .delete-due-date { + @include font-size(small); + color: $gray; + float: right; + margin: 1rem .25rem 0 0; + transition: color .3s linear; + .icon { + fill: currentColor; + } + &:hover { + color: $red; + transition: color .3s linear; + .icon { + fill: currentColor; + } + } + } +}