Due date component

stable
Daniel García 2018-04-09 16:32:49 +02:00
parent 9e561d9b00
commit d18767789d
16 changed files with 257 additions and 4 deletions

View File

@ -162,6 +162,12 @@
"TITLE_ACTION_EDIT_ASSIGNMENT": "Edit assignment",
"SELF": "Assign to me"
},
"DUE_DATE": {
"TITLE_ACTION_SET_DUE_DATE": "Set due date",
"DUE_SOON": "due soon",
"PAST_DUE": "past due",
"NO_LONGER_APPLICABLE": "no longer applicable"
},
"STATUS": {
"CLOSED": "Closed",
"OPEN": "Open"

View File

@ -10,6 +10,11 @@
ng-if="vm.item.getIn(['model', 'total_points'])"
) {{"COMMON.FIELDS.POINTS" | translate}} {{vm.item.getIn(['model', 'total_points'])}}
.card-statistics
tg-due-date.statistic.card-due-date(
due-date="vm.item.getIn(['model', 'due_date'])"
due-date-status="vm.item.getIn(['model', 'due_date_status'])"
is-closed="vm.item.getIn(['model', 'is_closed'])"
)
.statistic.card-iocaine(
ng-if="vm.item.getIn(['model', 'is_iocaine'])"
title="{{'COMMON.IOCAINE_TEXT' | translate}}"

View File

@ -0,0 +1,9 @@
a.due-date-button.button-gray.is-editable(
href=""
ng-if="vm.visible()"
ng-disabled="vm.disabled()"
ng-class="vm.color()"
ng-attr-title="{{ vm.title() }}"
ng-click="vm.setDueDate()"
)
tg-svg(svg-icon="icon-clock")

View File

@ -0,0 +1,72 @@
###
# Copyright (C) 2014-2018 Taiga Agile LLC <taiga@taiga.io>
#
# 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 <http://www.gnu.org/licenses/>.
#
# File: due-date-controller.coffee
###
class DueDateController
@.$inject = [
"$translate"
"tgLightboxFactory"
]
constructor: (@translate, @tgLightboxFactory) ->
visible: () ->
return @.format == 'button' or @.dueDate?
disabled: () ->
return @.isClosed
color: () ->
colors = {
'no_longer_applicable': 'closed',
'due_soon': 'due-soon',
'past_due': 'past-due',
'set': 'due-set',
}
return colors[@.dueDateStatus] or ''
title: () ->
if @.format == 'button'
return if @.dueDate then @._formatTitle() else 'EDIT DUE DATE'
return @._formatTitle()
_formatTitle: () ->
dueDateStatus = 'closed'
titles = {
'no_longer_applicable': 'COMMON.DUE_DATE.NO_LONGER_APPLICABLE',
'due_soon': 'COMMON.DUE_DATE.DUE_SOON',
'past_due': 'COMMON.DUE_DATE.PAST_DUE',
}
prettyDate = @translate.instant("COMMON.PICKERDATE.FORMAT")
formatedDate = moment(@.dueDate).format(prettyDate)
if not titles[@.dueDateStatus]
return formatedDate
return "#{formatedDate} (#{@translate.instant(titles[@.dueDateStatus])})"
setDueDate: () ->
event.preventDefault()
return if @.disabled()
@tgLightboxFactory.create(
"tg-lb-set-due-date",
{"class": "lightbox lightbox-set-due-date"},
{"object": @.item}
)
angular.module('taigaComponents').controller('DueDate', DueDateController)

View File

@ -0,0 +1,7 @@
span.due-date-icon
tg-svg(
ng-if="vm.visible()"
svg-icon="icon-clock"
ng-class="vm.color()"
ng-attr-title="{{ vm.title() }}"
)

View File

@ -0,0 +1,43 @@
###
# Copyright (C) 2014-2018 Taiga Agile LLC <taiga@taiga.io>
#
# 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 <http://www.gnu.org/licenses/>.
#
# File: due-date.directive.coffee
###
module = angular.module("taigaComponents")
dueDateDirective = () ->
templateUrl = (el, attrs) ->
if attrs.format
return "components/due-date/due-date-" + attrs.format + ".html"
return "components/due-date/due-date-icon.html"
return {
link: (scope) ->
controller: "DueDate",
controllerAs: "vm",
bindToController: true,
templateUrl: templateUrl,
scope: {
dueDate: '=',
dueDateStatus: '=',
isClosed: '=',
item: '=',
format: '@'
}
}
module.directive('tgDueDate', dueDateDirective)

View File

@ -0,0 +1,65 @@
tg-due-date .due-date-button {
background: $gray-light;
display: inline-block;
margin-right: .5rem;
padding: 1rem;
transition: background .2s linear;
transition-delay: .1s;
&.closed,
&.closed[disabled] {
background: $gray-lighter;
}
&.due-set {
background: $yellow-green;
}
&.due-soon {
background: $my-sin;
}
&.past-due {
background: $red-light;
}
&:hover {
background: $gray;
}
&.editable {
cursor: pointer;
}
}
tg-due-date .due-date-icon {
display: inline-block;
line-height: .1rem;
margin: 0 .25rem;
position: relative;
top: .1rem;
svg {
fill: $gray-light;
height: 1.1rem;
transition: fill .2s ease-in;
width: 1.1rem;
}
.closed svg {
fill: $gray-lighter;
}
.due-set svg {
fill: $yellow-green;
}
.due-soon svg {
fill: $my-sin;
}
.past-due svg {
fill: $red-light;
}
}
.backlog-table-body .user-story-name .due-date-icon {
top: .25rem;
}
.card-statistics .due-date-icon {
margin: 0;
svg {
height: 1rem;
width: 1rem;
}
}

View File

@ -27,6 +27,11 @@
)
span(tg-bo-ref="us.ref")
span(ng-bind-html="us.subject | emojify")
tg-due-date(
due-date="us.due_date"
due-date-status="us.due_date_status"
ng-if="us.due_date"
)
tg-belong-to-epics(
format="pill"
ng-if="us.epics"

View File

@ -113,6 +113,14 @@ div.wrapper(
)
section.ticket-detail-settings
tg-due-date(
tg-check-permission="modify_issue"
due-date="issue.due_date"
due-date-status="issue.due_date_status"
is-closed="issue.is_closed"
item="issue"
format="button"
)
tg-promote-issue-to-us-button(
tg-check-permission="add_us",
ng-model="issue"

View File

@ -3,7 +3,11 @@
tg-nav="project-tasks-detail:project=project.slug,ref=task.ref")
span #<%- task.ref %>
span(ng-non-bindable) <%= emojify(task.subject) %>
tg-due-date(
due-date="task.due_date"
due-date-status="task.due_date_status"
ng-if="task.due_date"
)
.task-settings
<% if(perms.modify_task) { %>
a.edit-task(

View File

@ -102,6 +102,14 @@ div.wrapper(
)
section.ticket-detail-settings
tg-due-date(
tg-check-permission="modify_task"
due-date="task.due_date"
due-date-status="task.due_date_status"
is-closed="task.is_closed"
item="task"
format="button"
)
tg-task-is-iocaine-button(ng-model="task")
tg-block-button(tg-check-permission="modify_task", ng-model="task")
tg-delete-button(

View File

@ -127,6 +127,14 @@ div.wrapper(
) {{'US.TRIBE.PUBLISH_INFO' | translate}}
section.ticket-detail-settings
tg-due-date(
tg-check-permission="modify_us"
due-date="us.due_date"
due-date-status="us.due_date_status"
is-closed="us.is_closed"
item="us"
format="button"
)
tg-us-team-requirement-button(ng-model="us")
tg-us-client-requirement-button(ng-model="us")
tg-block-button(

View File

@ -244,6 +244,10 @@
class="path1"
d="M202.24-0.179v129.093l-202.24-0.11v895.375h729.6v-234.419h-64v170.419h-601.6v-644.385h601.6v287.086h64v-474.076h-64v0.11h-138.24v-129.093h-325.12zM266.24 63.821h197.12v96.44h0.32v32.653h201.92v58.88h-601.6v-58.88h202.24v-129.093zM129.165 393.242v64h468.838v-64h-468.836zM522.76 515.302l-181.020 181.018 181.020 181.020 45.256-45.253-103.759-103.767h559.744v-64h-559.749l103.764-103.764-45.253-45.256zM129.165 541.722v64h228.086v-64h-228.083zM129.165 690.202v64h150.246v-64h-150.246zM129.165 833.562v64h258.854v-64h-258.854z"></path>
</symbol>
<symbol id="icon-clock" viewBox="0 0 400 400.00001">
<title>clock</title>
<path d="M200 0a200 200 0 1 0 0 400 200 200 0 0 0 0-400zm0 25a175 175 0 1 1 0 350 175 175 0 0 1 0-350zm13 53h-25v113l-87 1v25l112-1z"></path>
</symbol>
<symbol id="icon-document" viewBox="0 0 1024 1024">
<title>document</title>
<path

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -8,6 +8,7 @@ $blackish: #212121;
$grayer: #212121;
$gray: #757575;
$gray-light: #757575;
$gray-lighter: #B8B8B8;
$whitish: #c1c1c1;
$white: #fff;
@ -19,9 +20,11 @@ $primary-dark: #000;
// Mass white
$mass-white: #f5f5f5;
//Warning colors
//Status colors
$red-light: #ff0062;
$red: #ff2400;
$my-sin: #fcaf3e;
$yellow-green: #9dce0a;
//Card color
$card: #F0EFD1;

View File

@ -8,6 +8,7 @@ $blackish: #212121;
$grayer: #424242;
$gray: #757575;
$gray-light: #BDBDBD;
$gray-lighter: #B8B8B8;
$whitish: #EEEEEE;
$white: #fff;
@ -19,9 +20,11 @@ $primary-light: #8c9eff;
$primary: #3f51b5;
$primary-dark: #1a237e;
//Warning colors
// Status colors
$red-light: #ff5252;
$red: #f44336;
$my-sin: #fcaf3e;
$yellow-green: #9dce0a;
//Card color
$card: #fff8e4;

View File

@ -8,6 +8,7 @@ $blackish: #050505;
$grayer: #444;
$gray: #555;
$gray-light: #767676;
$gray-lighter: #B8B8B8;
$whitish: #e4e3e3;
$white: #fff;
@ -19,9 +20,11 @@ $primary-light: #9dce0a;
$primary: #5b8200;
$primary-dark: #879b89;
//Warning colors
//Status colors
$red-light: #ff8282;
$red: #f00;
$my-sin: #fcaf3e;
$yellow-green: #9dce0a;
//Card color
$card: #fff8e4;