Add basic start and due dates for cards.

This commit is contained in:
shoetten 2016-02-05 20:23:09 +01:00
parent 182c9af123
commit d4497d7aeb
7 changed files with 290 additions and 1 deletions

View file

@ -0,0 +1,20 @@
template(name="editCardDate")
.edit-card-date
form.edit-date
.fields
.left
label(for="date") {{_ 'date'}}
input.js-date-field#date(type="text" name="date" value=showDate placeholder=dateFormat autofocus)
.right
label(for="time") {{_ 'time'}}
input.js-time-field#time(type="text" name="time" value=showTime placeholder=timeFormat)
.js-datepicker
if error.get
.warning {{_ error.get}}
button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}}
button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}}
template(name="dateBadge")
a.js-edit-date.card-date(title="{{showTitle}}")
time(datetime="{{showISODate}}")
| {{showDate}}

View file

@ -0,0 +1,193 @@
// Edit start & due dates
const EditCardDate = BlazeComponent.extendComponent({
template() {
return 'editCardDate';
},
onCreated() {
this.error = new ReactiveVar('');
this.card = this.data();
this.date = new ReactiveVar(moment.invalid());
},
onRendered() {
let $picker = this.$('.js-datepicker').datepicker({
todayHighlight: true,
todayBtn: 'linked',
language: TAPi18n.getLanguage()
}).on('changeDate', function(e) {
const localDate = moment(e.date).format('L');
date.value = localDate;
this.error.set('');
time.focus();
}.bind(this));
if (this.date.get().isValid()) {
$picker.datepicker('update', this.date.get().toDate());
}
},
showDate() {
if (this.date.get().isValid())
return this.date.get().format('L');
},
showTime() {
if (this.date.get().isValid())
return this.date.get().format('LT');
},
dateFormat() {
return moment.localeData().longDateFormat('L');
},
timeFormat() {
return moment.localeData().longDateFormat('LT');
},
events() {
return [{
'keyup .js-date-field'(evt) {
// parse for localized date format in strict mode
const dateMoment = moment(date.value, 'L', true);
if (dateMoment.isValid()) {
this.error.set('');
this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
}
},
'keyup .js-time-field'(evt) {
// parse for localized time format in strict mode
const dateMoment = moment(time.value, 'LT', true);
if (dateMoment.isValid()) {
this.error.set('');
}
},
'submit .edit-date'(evt) {
evt.preventDefault();
// if no time was given, init with 12:00
var time = evt.target.time.value || moment(new Date().setHours(12,0,0)).format('LT');
const dateString = evt.target.date.value + ' ' + time;
const newDate = moment.utc(dateString, 'L LT', true);
if (newDate.isValid()) {
this._storeDate(newDate.toDate());
Popup.close();
}
else {
this.error.set('invalid-date');
evt.target.date.focus();
}
},
'click .js-delete-date'(evt) {
evt.preventDefault();
this._deleteDate();
Popup.close();
},
}];
},
});
// editCardStartDatePopup
(class extends EditCardDate {
onCreated() {
super();
if (this.data().startAt) {
this.date.set(moment.utc(this.data().startAt));
}
}
_storeDate(date) {
this.card.setStart(date);
}
_deleteDate() {
this.card.unsetStart();
}
}).register('editCardStartDatePopup');
// editCardDueDatePopup
(class extends EditCardDate {
onCreated() {
super();
if (this.data().dueAt !== undefined) {
this.date.set(moment.utc(this.data().dueAt));
}
}
onRendered() {
super();
if (moment.isDate(this.card.startAt)) {
this.$('.js-datepicker').datepicker('setStartDate', this.card.startAt);
}
}
_storeDate(date) {
this.card.setDue(date);
}
_deleteDate() {
this.card.unsetDue();
}
}).register('editCardDueDatePopup');
// Display start & due dates
const CardDate = BlazeComponent.extendComponent({
template() {
return 'dateBadge';
},
onCreated() {
this.date = ReactiveVar();
},
showDate() {
// this will start working once mquandalle:moment
// is updated to at least moment.js 2.10.5
// until then, the date is displayed in the "L" format
return this.date.get().calendar(null, {
sameElse: 'llll'
});
},
showTitle() {
return this.date.get().format('LLLL');
},
showISODate() {
return this.date.get().toISOString();
},
});
// cardStartDate
(class extends CardDate {
onCreated() {
super();
let self = this;
this.autorun(() => {
self.date.set(moment.utc(this.data().startAt));
});
}
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editCardStartDate'),
});
}
}).register('cardStartDate');
// cardDueDate
(class extends CardDate {
onCreated() {
super();
let self = this;
this.autorun(() => {
self.date.set(moment.utc(this.data().dueAt));
});
}
events() {
return super.events().concat({
'click .js-edit-date': Popup.open('editCardDueDate'),
});
}
}).register('cardDueDate');

View file

@ -0,0 +1,50 @@
.edit-card-date
.fields
.left
width: 56%
.right
width: 38%
.datepicker
width: 100%
table
width: 100%
border: none
border-spacing: 0
border-collapse: collapse
thead
background: none
td, th
box-sizing: border-box
.card-date
display: block
border-radius: 4px
padding: 1px 3px;
background-color: #dbdbdb
&:hover, &.is-active
background-color: #b3b3b3
&.current
background-color: #42ca00
&:hover, &.is-active
background-color: darken(#42ca00, 15)
&.almost-due
background-color: #fad900
&:hover, &.is-active
background-color: darken(#fad900, 15)
&.due
background-color: #fa3f00
&:hover, &.is-active
background-color: darken(#fa3f00, 15)
time
&::before
font: normal normal normal 14px/1 FontAwesome
font-size: inherit
-webkit-font-smoothing: antialiased
content: "\f017" // clock symbol
margin-right: 0.3em

View file

@ -35,6 +35,17 @@ template(name="cardDetails")
a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
i.fa.fa-plus
if startAt
.card-details-item.card-details-item-start
h3.card-details-item-title {{_ 'start-at'}}
+cardStartDate
if dueAt
.card-details-item.card-details-item-due
h3.card-details-item-title {{_ 'due-at'}}
+cardDueDate
//- XXX We should use "editable" to avoid repetiting ourselves
if currentUser.isBoardMember
h3.card-details-item-title {{_ 'description'}}
@ -91,6 +102,8 @@ template(name="cardDetailsActionsPopup")
li: a.js-members {{_ 'card-edit-members'}}
li: a.js-labels {{_ 'card-edit-labels'}}
li: a.js-attachments {{_ 'card-edit-attachments'}}
li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
li: a.js-due-date {{_ 'editCardDueDatePopup-title'}}
hr
ul.pop-over-list
li: a.js-move-card-to-top {{_ 'moveCardToTop-title'}}

View file

@ -143,6 +143,8 @@ Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
'click .js-labels': Popup.open('cardLabels'),
'click .js-attachments': Popup.open('cardAttachments'),
'click .js-start-date': Popup.open('editCardStartDate'),
'click .js-due-date': Popup.open('editCardDueDate'),
'click .js-move-card': Popup.open('moveCard'),
'click .js-move-card-to-top'(evt) {
evt.preventDefault();

View file

@ -73,8 +73,13 @@
margin: 15px 0
.card-details-item
margin-right: 0.5em
&:last-child
margin-right: 0
&.card-details-item-labels,
&.card-details-item-members
&.card-details-item-members,
&.card-details-item-start,
&.card-details-item-due
width: 50%
flex-shrink: 1

View file

@ -133,6 +133,7 @@
"createBoardPopup-title": "Create Board",
"createLabelPopup-title": "Create Label",
"current": "current",
"date": "Date",
"decline": "Decline",
"default-avatar": "Default avatar",
"delete": "Delete",
@ -143,9 +144,12 @@
"discard": "Discard",
"done": "Done",
"download": "Download",
"due-at": "Due",
"edit": "Edit",
"edit-avatar": "Change Avatar",
"edit-profile": "Edit Profile",
"editCardStartDatePopup-title": "Change start date",
"editCardDueDatePopup-title": "Change due date",
"editLabelPopup-title": "Change Label",
"editNotificationPopup-title": "Edit Notification",
"editProfilePopup-title": "Edit Profile",
@ -282,10 +286,12 @@
"star-board-title": "Click to star this board. It will show up at top of your boards list.",
"starred-boards": "Starred Boards",
"starred-boards-description": "Starred boards show up at the top of your boards list.",
"start-at": "Start",
"subscribe": "Subscribe",
"team": "Team",
"this-board": "this board",
"this-card": "this card",
"time": "Time",
"title": "Title",
"tracking": "Tracking",
"tracking-info": "You will be notified of any changes to those cards you are involved as creator or member.",