mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
Fix Due dates to be color coded and have icons.
Thanks to xet7 ! Fixes #5950
This commit is contained in:
parent
5d2bfab0f5
commit
d965faa317
6 changed files with 126 additions and 32 deletions
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
/* Generic date badge and custom field date */
|
||||
.card-date:not(.received-date):not(.start-date):not(.due-date):not(.end-date) time::before {
|
||||
content: "📅"; /* Calendar - represents generic date */
|
||||
/*content: "📅"; // Calendar - represents generic date */
|
||||
}
|
||||
.card-date time::before {
|
||||
font-size: inherit;
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ template(name="dateCustomField")
|
|||
|
||||
template(name="minicardReceivedDate")
|
||||
if canModifyCard
|
||||
a.js-edit-date.card-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.js-edit-date.card-date.received-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
b
|
||||
| {{showWeek}}
|
||||
else
|
||||
a.card-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.card-date.received-date(title="{{_ 'card-received'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
|
|
@ -40,14 +40,14 @@ template(name="minicardReceivedDate")
|
|||
|
||||
template(name="minicardStartDate")
|
||||
if canModifyCard
|
||||
a.js-edit-date.card-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.js-edit-date.card-date.start-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
b
|
||||
| {{showWeek}}
|
||||
else
|
||||
a.card-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.card-date.start-date(title="{{_ 'card-start'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
|
|
@ -56,14 +56,14 @@ template(name="minicardStartDate")
|
|||
|
||||
template(name="minicardDueDate")
|
||||
if canModifyCard
|
||||
a.js-edit-date.card-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.js-edit-date.card-date.due-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
b
|
||||
| {{showWeek}}
|
||||
else
|
||||
a.card-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.card-date.due-date(title="{{_ 'card-due'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
|
|
@ -72,14 +72,14 @@ template(name="minicardDueDate")
|
|||
|
||||
template(name="minicardEndDate")
|
||||
if canModifyCard
|
||||
a.js-edit-date.card-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.js-edit-date.card-date.end-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
b
|
||||
| {{showWeek}}
|
||||
else
|
||||
a.card-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
a.card-date.end-date(title="{{_ 'card-end'}} {{_ 'predicate-week'}} {{#if showWeekOfYear}}{{showWeek}}{{/if}}" class="{{classes}}")
|
||||
time(datetime="{{showISODate}}")
|
||||
| {{showDate}}
|
||||
if showWeekOfYear
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ import {
|
|||
now,
|
||||
createDate,
|
||||
fromNow,
|
||||
calendar
|
||||
calendar,
|
||||
diff
|
||||
} from '/imports/lib/dateUtils';
|
||||
|
||||
// editCardReceivedDatePopup
|
||||
|
|
@ -169,9 +170,7 @@ class CardReceivedDate extends CardDate {
|
|||
}
|
||||
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-received-on')} ${this.date
|
||||
.get()
|
||||
.format('LLLL')}`;
|
||||
return `${TAPi18n.__('card-received-on')} ${format(this.date.get(), 'LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
|
|
@ -198,15 +197,15 @@ class CardStartDate extends CardDate {
|
|||
const theDate = this.date.get();
|
||||
const now = this.now.get();
|
||||
// if dueAt or endAt exist & are > startAt, startAt doesn't need to be flagged
|
||||
if ((endAt && theDate.isAfter(endAt)) || (dueAt && theDate.isAfter(dueAt)))
|
||||
if ((endAt && isAfter(theDate, endAt)) || (dueAt && isAfter(theDate, dueAt)))
|
||||
classes += 'long-overdue';
|
||||
else if (theDate.isAfter(now)) classes += '';
|
||||
else if (isAfter(theDate, now)) classes += '';
|
||||
else classes += 'current';
|
||||
return classes;
|
||||
}
|
||||
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`;
|
||||
return `${TAPi18n.__('card-start-on')} ${format(this.date.get(), 'LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
|
|
@ -232,17 +231,17 @@ class CardDueDate extends CardDate {
|
|||
const theDate = this.date.get();
|
||||
const now = this.now.get();
|
||||
// if the due date is after the end date, green - done early
|
||||
if (endAt && theDate.isAfter(endAt)) classes += 'current';
|
||||
if (endAt && isAfter(theDate, endAt)) classes += 'current';
|
||||
// if there is an end date, don't need to flag the due date
|
||||
else if (endAt) classes += '';
|
||||
else if (now.diff(theDate, 'days') >= 2) classes += 'long-overdue';
|
||||
else if (now.diff(theDate, 'minute') >= 0) classes += 'due';
|
||||
else if (now.diff(theDate, 'days') >= -1) classes += 'almost-due';
|
||||
else if (diff(now, theDate, 'days') >= 2) classes += 'long-overdue';
|
||||
else if (diff(now, theDate, 'minute') >= 0) classes += 'due';
|
||||
else if (diff(now, theDate, 'days') >= -1) classes += 'almost-due';
|
||||
return classes;
|
||||
}
|
||||
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-due-on')} ${this.date.get().format('LLLL')}`;
|
||||
return `${TAPi18n.__('card-due-on')} ${format(this.date.get(), 'LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
|
|
@ -267,13 +266,13 @@ class CardEndDate extends CardDate {
|
|||
const dueAt = this.data().getDue();
|
||||
const theDate = this.date.get();
|
||||
if (!dueAt) classes += '';
|
||||
else if (theDate.isBefore(dueAt)) classes += 'current';
|
||||
else if (theDate.isAfter(dueAt)) classes += 'due';
|
||||
else if (isBefore(theDate, dueAt)) classes += 'current';
|
||||
else if (isAfter(theDate, dueAt)) classes += 'due';
|
||||
return classes;
|
||||
}
|
||||
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
|
||||
return `${TAPi18n.__('card-end-on')} ${format(this.date.get(), 'LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
|
|
@ -315,7 +314,7 @@ class CardCustomFieldDate extends CardDate {
|
|||
}
|
||||
|
||||
showTitle() {
|
||||
return `${this.date.get().format('LLLL')}`;
|
||||
return `${format(this.date.get(), 'LLLL')}`;
|
||||
}
|
||||
|
||||
classes() {
|
||||
|
|
@ -418,10 +417,10 @@ class PokerEndDate extends CardDate {
|
|||
return classes;
|
||||
}
|
||||
showDate() {
|
||||
return this.date.get().format('l LT');
|
||||
return format(this.date.get(), 'l LT');
|
||||
}
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
|
||||
return `${TAPi18n.__('card-end-on')} ${format(this.date.get(), 'LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
|
|
|
|||
|
|
@ -169,6 +169,63 @@
|
|||
margin-right: 0.4vw;
|
||||
}
|
||||
|
||||
/* Unicode icons for minicard dates - matching cardDate.css */
|
||||
.minicard .card-date.end-date time::before {
|
||||
content: "🏁"; /* Finish flag - represents end/completion */
|
||||
}
|
||||
.minicard .card-date.due-date time::before {
|
||||
content: "⏰"; /* Alarm clock - represents due/deadline */
|
||||
}
|
||||
.minicard .card-date.start-date time::before {
|
||||
content: "🚀"; /* Rocket - represents start/launch */
|
||||
}
|
||||
.minicard .card-date.received-date time::before {
|
||||
content: "📥"; /* Inbox tray - represents received/incoming */
|
||||
}
|
||||
|
||||
.minicard .card-date time::before {
|
||||
font-size: inherit;
|
||||
margin-right: 0.3em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Date type specific colors for minicards - matching cardDate.css */
|
||||
.minicard .card-date.received-date {
|
||||
background-color: #dbdbdb; /* Grey for received - same as base card-date */
|
||||
}
|
||||
|
||||
.minicard .card-date.received-date:hover,
|
||||
.minicard .card-date.received-date.is-active {
|
||||
background-color: #b3b3b3;
|
||||
}
|
||||
|
||||
.minicard .card-date.start-date {
|
||||
background-color: #3cb500; /* Green for start */
|
||||
}
|
||||
|
||||
.minicard .card-date.start-date:hover,
|
||||
.minicard .card-date.start-date.is-active {
|
||||
background-color: #2d8f00;
|
||||
}
|
||||
|
||||
.minicard .card-date.due-date {
|
||||
background-color: #ff9f19; /* Orange for due */
|
||||
}
|
||||
|
||||
.minicard .card-date.due-date:hover,
|
||||
.minicard .card-date.due-date.is-active {
|
||||
background-color: #e68a00;
|
||||
}
|
||||
|
||||
.minicard .card-date.end-date {
|
||||
background-color: #a632db; /* Purple for end */
|
||||
}
|
||||
|
||||
.minicard .card-date.end-date:hover,
|
||||
.minicard .card-date.end-date.is-active {
|
||||
background-color: #8a2bb8;
|
||||
}
|
||||
|
||||
/* Font Awesome icons in minicard dates */
|
||||
.minicard .card-date i.fa {
|
||||
margin-right: 0.3vw;
|
||||
|
|
|
|||
|
|
@ -12,11 +12,8 @@ template(name="minicard")
|
|||
a.minicard-details-menu.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") | ☰
|
||||
.dates
|
||||
if getReceived
|
||||
unless getStart
|
||||
unless getDue
|
||||
unless getEnd
|
||||
.date
|
||||
+minicardReceivedDate
|
||||
.date
|
||||
+minicardReceivedDate
|
||||
if getStart
|
||||
.date
|
||||
+minicardStartDate
|
||||
|
|
|
|||
|
|
@ -304,6 +304,10 @@ export function format(date, format = 'L') {
|
|||
return d.toLocaleString();
|
||||
case 'llll':
|
||||
return d.toLocaleString();
|
||||
case 'LLLL':
|
||||
return d.toLocaleString();
|
||||
case 'l LT':
|
||||
return `${month}/${day}/${year} ${hours}:${minutes}`;
|
||||
case 'YYYY-MM-DD':
|
||||
return `${year}-${month}-${day}`;
|
||||
case 'YYYY-MM-DD HH:mm':
|
||||
|
|
@ -490,3 +494,40 @@ export function calendar(date, now = new Date()) {
|
|||
|
||||
return format(d, 'L');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the difference between two dates in the specified unit
|
||||
* @param {Date|string} date1 - First date
|
||||
* @param {Date|string} date2 - Second date
|
||||
* @param {string} unit - Unit of measurement ('millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'year')
|
||||
* @returns {number} Difference in the specified unit
|
||||
*/
|
||||
export function diff(date1, date2, unit = 'millisecond') {
|
||||
const d1 = new Date(date1);
|
||||
const d2 = new Date(date2);
|
||||
|
||||
if (isNaN(d1.getTime()) || isNaN(d2.getTime())) return 0;
|
||||
|
||||
const diffMs = d1.getTime() - d2.getTime();
|
||||
|
||||
switch (unit) {
|
||||
case 'millisecond':
|
||||
return diffMs;
|
||||
case 'second':
|
||||
return Math.floor(diffMs / 1000);
|
||||
case 'minute':
|
||||
return Math.floor(diffMs / (1000 * 60));
|
||||
case 'hour':
|
||||
return Math.floor(diffMs / (1000 * 60 * 60));
|
||||
case 'day':
|
||||
return Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
||||
case 'week':
|
||||
return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 7));
|
||||
case 'month':
|
||||
return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 30));
|
||||
case 'year':
|
||||
return Math.floor(diffMs / (1000 * 60 * 60 * 24 * 365));
|
||||
default:
|
||||
return diffMs;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue