Forráskód Böngészése

Merge branch 'master' of github.com:wekan/wekan

Lauri Ojansivu 5 éve
szülő
commit
5d6c68a9cf

+ 36 - 16
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) {

+ 9 - 1
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),
       );
 

+ 3 - 3
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",

+ 1 - 0
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',

+ 7 - 0
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,

+ 27 - 7
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;

+ 6 - 3
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 :-(

+ 1 - 1
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"