summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLauri Ojansivu <x@xet7.org>2019-09-28 14:56:51 +0300
committerLauri Ojansivu <x@xet7.org>2019-09-28 14:56:51 +0300
commit5d6c68a9cfe1e83b884e3884e17d5ed82d6f5b98 (patch)
tree9f2a26c68e81419d469d33693217aa492ec26081
parent75dc5f226cb3261337c9be9614856efc0b40e377 (diff)
parented4c49090abfb35ebadc77b40eee4af05ae15ac1 (diff)
downloadwekan-5d6c68a9cfe1e83b884e3884e17d5ed82d6f5b98.tar.gz
wekan-5d6c68a9cfe1e83b884e3884e17d5ed82d6f5b98.tar.bz2
wekan-5d6c68a9cfe1e83b884e3884e17d5ed82d6f5b98.zip
Merge branch 'master' of github.com:wekan/wekan
-rw-r--r--client/components/boards/boardBody.js52
-rw-r--r--client/lib/datepicker.js10
-rw-r--r--i18n/en.i18n.json6
-rw-r--r--models/activities.js1
-rw-r--r--models/boards.js7
-rw-r--r--models/cards.js34
-rw-r--r--server/notifications/email.js9
-rwxr-xr-xsnap-src/bin/config2
8 files changed, 90 insertions, 31 deletions
diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js
index 713b6cbc..47042ae7 100644
--- a/client/components/boards/boardBody.js
+++ b/client/components/boards/boardBody.js
@@ -309,26 +309,46 @@ BlazeComponent.extendComponent({
events(start, end, timezone, callback) {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
const events = [];
+ const pushEvent = function(card, title, start, end, extraCls) {
+ start = start || card.startAt;
+ end = end || card.endAt;
+ title = title || card.title;
+ const className =
+ (extraCls ? `${extraCls} ` : '') +
+ (card.color ? `calendar-event-${card.color}` : '');
+ events.push({
+ id: card._id,
+ title,
+ start,
+ end: end || card.endAt,
+ allDay:
+ Math.abs(end.getTime() - start.getTime()) / 1000 === 24 * 3600,
+ url: FlowRouter.url('card', {
+ boardId: currentBoard._id,
+ slug: currentBoard.slug,
+ cardId: card._id,
+ }),
+ className,
+ });
+ };
currentBoard
.cardsInInterval(start.toDate(), end.toDate())
.forEach(function(card) {
- events.push({
- id: card._id,
- title: card.title,
- start: card.startAt,
- end: card.endAt,
- allDay:
- Math.abs(card.endAt.getTime() - card.startAt.getTime()) /
- 1000 ===
- 24 * 3600,
- url: FlowRouter.url('card', {
- boardId: currentBoard._id,
- slug: currentBoard.slug,
- cardId: card._id,
- }),
- className: card.color ? `calendar-event-${card.color}` : null,
- });
+ pushEvent(card);
+ });
+ currentBoard
+ .cardsDueInBetween(start.toDate(), end.toDate())
+ .forEach(function(card) {
+ pushEvent(
+ card,
+ `${card.title} ${TAPi18n.__('card-due')}`,
+ card.dueAt,
+ new Date(card.dueAt.getTime() + 36e5),
+ );
});
+ events.sort(function(first, second) {
+ return first.id > second.id ? 1 : -1;
+ });
callback(events);
},
eventResize(event, delta, revertFunc) {
diff --git a/client/lib/datepicker.js b/client/lib/datepicker.js
index eb5b60b8..da44bbc5 100644
--- a/client/lib/datepicker.js
+++ b/client/lib/datepicker.js
@@ -21,7 +21,15 @@ DatePicker = BlazeComponent.extendComponent({
function(evt) {
this.find('#date').value = moment(evt.date).format('L');
this.error.set('');
- this.find('#time').focus();
+ const timeInput = this.find('#time');
+ timeInput.focus();
+ if (!timeInput.value) {
+ const currentHour = evt.date.getHours();
+ const defaultMoment = moment(
+ currentHour > 0 ? evt.date : '1970-01-01 08:00:00',
+ ); // default to 8:00 am local time
+ timeInput.value = defaultMoment.format('LT');
+ }
}.bind(this),
);
diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json
index 44304305..58fda954 100644
--- a/i18n/en.i18n.json
+++ b/i18n/en.i18n.json
@@ -731,12 +731,12 @@
"almostdue": "current due time %s is approaching",
"pastdue": "current due time %s is past",
"duenow": "current due time %s is today",
- "act-newDue": "__card__ has 1st due reminder [__board__]",
- "act-withDue": "__card__ due reminders [__board__]",
+ "act-newDue": "__list__/__card__ has 1st due reminder [__board__]",
+ "act-withDue": "__list__/__card__ due reminders [__board__]",
"act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching",
"act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past",
"act-duenow": "was reminding the current due (__timeValue__) of __card__ is now",
- "act-atUserComment": "You were mentioned in [__board__] __card__",
+ "act-atUserComment": "You were mentioned in [__board__] __list__/__card__",
"delete-user-confirm-popup": "Are you sure you want to delete this account? There is no undo.",
"accounts-allowUserDelete": "Allow users to self delete their account",
"hide-minicard-label-text": "Hide minicard label text",
diff --git a/models/activities.js b/models/activities.js
index cb1dddaf..19e3fb7d 100644
--- a/models/activities.js
+++ b/models/activities.js
@@ -289,6 +289,7 @@ if (Meteor.isServer) {
activities: { $in: [description, 'all'] },
}).fetch();
if (integrations.length > 0) {
+ params.watchers = watchers;
integrations.forEach(integration => {
Meteor.call(
'outgoingWebhooks',
diff --git a/models/boards.js b/models/boards.js
index af7685ae..a9348478 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -699,6 +699,13 @@ Boards.helpers({
return result;
},
+ cardsDueInBetween(start, end) {
+ return Cards.find({
+ boardId: this._id,
+ dueAt: { $gte: start, $lte: end },
+ });
+ },
+
cardsInInterval(start, end) {
return Cards.find({
boardId: this._id,
diff --git a/models/cards.js b/models/cards.js
index d30baaf1..371ad185 100644
--- a/models/cards.js
+++ b/models/cards.js
@@ -1579,18 +1579,38 @@ const findDueCards = days => {
const now = new Date(),
aday = 3600 * 24 * 1e3,
then = day => new Date(now.setHours(0, 0, 0, 0) + day * aday);
- seekDue(then(1), then(days), 'almostdue');
- seekDue(then(0), then(1), 'duenow');
- seekDue(then(-days), now, 'pastdue');
+ if (!days) return;
+ if (!days.map) days = [days];
+ days.map(day => {
+ let args = [];
+ if (day === 0) {
+ args = [then(0), then(1), 'duenow'];
+ } else if (day > 0) {
+ args = [then(1), then(day), 'almostdue'];
+ } else {
+ args = [then(day), now, 'pastdue'];
+ }
+ seekDue(...args);
+ });
};
const addCronJob = _.debounce(
Meteor.bindEnvironment(function findDueCardsDebounced() {
- const notifydays =
- parseInt(process.env.NOTIFY_DUE_DAYS_BEFORE_AND_AFTER, 10) || 2; // default as 2 days before and after
- if (!(notifydays > 0 && notifydays < 15)) {
- // notifying due is disabled
+ const envValue = process.env.NOTIFY_DUE_DAYS_BEFORE_AND_AFTER;
+ if (!envValue) {
return;
}
+ const notifydays = envValue
+ .split(',')
+ .map(value => {
+ const iValue = parseInt(value, 10);
+ if (!(iValue > 0 && iValue < 15)) {
+ // notifying due is disabled
+ return false;
+ } else {
+ return iValue;
+ }
+ })
+ .filter(Boolean);
const notifyitvl = process.env.NOTIFY_DUE_AT_HOUR_OF_DAY; //passed in the itvl has to be a number standing for the hour of current time
const defaultitvl = 8; // default every morning at 8am, if the passed env variable has parsing error use default
const itvl = parseInt(notifyitvl, 10) || defaultitvl;
diff --git a/server/notifications/email.js b/server/notifications/email.js
index 0373deb0..acafb4de 100644
--- a/server/notifications/email.js
+++ b/server/notifications/email.js
@@ -13,11 +13,14 @@ Meteor.startup(() => {
const lan = user.getLanguage();
const subject = TAPi18n.__(title, params, lan); // the original function has a fault, i believe the title should be used according to original author
const existing = user.getEmailBuffer().length > 0;
- const text = `${existing ? `<br/>\n${subject}<br/>\n` : ''}${
+ const htmlEnabled =
+ Meteor.settings.public &&
+ Meteor.settings.public.RICHER_CARD_COMMENT_EDITOR !== false;
+ const text = `${existing ? `\n${subject}\n` : ''}${
params.user
- } ${TAPi18n.__(description, quoteParams, lan)}<br/>\n${params.url}`;
+ } ${TAPi18n.__(description, quoteParams, lan)}\n${params.url}`;
- user.addEmailBuffer(text);
+ user.addEmailBuffer(htmlEnabled ? text.replace(/\n/g, '<br/>') : text);
// unlike setTimeout(func, delay, args),
// Meteor.setTimeout(func, delay) does not accept args :-(
diff --git a/snap-src/bin/config b/snap-src/bin/config
index 855caa32..21e2608d 100755
--- a/snap-src/bin/config
+++ b/snap-src/bin/config
@@ -108,7 +108,7 @@ DESCRIPTION_BIGEVENTS_PATTERN="Big events pattern: Notify always due etc regardl
DEFAULT_BIGEVENTS_PATTERN="NONE"
KEY_BIGEVENTS_PATTERN="bigevents-pattern"
-DESCRIPTION_NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="Notify due days, default 2 days before and after. 0 = due notifications disabled. Default: 2"
+DESCRIPTION_NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="Notify due days, accepts ',' delimited string, i.e. 2,0 means notify will be sent out 2 days before and right on due day. Default: empty"
DEFAULT_NOTIFY_DUE_DAYS_BEFORE_AND_AFTER=""
KEY_NOTIFY_DUE_DAYS_BEFORE_AND_AFTER="notify-due-days-before-and-after"