Browse Source

Fix Regression - Show calendar popup at set due date.

Thanks to xet7 !

Fixes #5978
Lauri Ojansivu 1 day ago
parent
commit
581733d605

+ 21 - 0
client/components/cards/cardDate.jade

@@ -97,6 +97,12 @@ template(name="minicardCustomFieldDate")
 template(name="editCardReceivedDatePopup")
 template(name="editCardReceivedDatePopup")
   form.edit-card-received-date
   form.edit-card-received-date
     .datepicker
     .datepicker
+      // Date input field (existing)
+      // Insert calendar selector right after date input
+      .calendar-selector
+        label(for="calendar-received") 🗓️
+        input#calendar-received.js-calendar-date(type="date")
+      // Time input field (if present)
     .clear-date
     .clear-date
       a.js-clear-date {{_ 'clear'}}
       a.js-clear-date {{_ 'clear'}}
     .datepicker-actions
     .datepicker-actions
@@ -106,6 +112,11 @@ template(name="editCardReceivedDatePopup")
 template(name="editCardStartDatePopup")
 template(name="editCardStartDatePopup")
   form.edit-card-start-date
   form.edit-card-start-date
     .datepicker
     .datepicker
+      // Date input field (existing)
+      .calendar-selector
+        label(for="calendar-start") 🗓️
+        input#calendar-start.js-calendar-date(type="date")
+      // Time input field (if present)
     .clear-date
     .clear-date
       a.js-clear-date {{_ 'clear'}}
       a.js-clear-date {{_ 'clear'}}
     .datepicker-actions
     .datepicker-actions
@@ -115,6 +126,11 @@ template(name="editCardStartDatePopup")
 template(name="editCardDueDatePopup")
 template(name="editCardDueDatePopup")
   form.edit-card-due-date
   form.edit-card-due-date
     .datepicker
     .datepicker
+      // Date input field (existing)
+      .calendar-selector
+        label(for="calendar-due") 🗓️
+        input#calendar-due.js-calendar-date(type="date")
+      // Time input field (if present)
     .clear-date
     .clear-date
       a.js-clear-date {{_ 'clear'}}
       a.js-clear-date {{_ 'clear'}}
     .datepicker-actions
     .datepicker-actions
@@ -124,6 +140,11 @@ template(name="editCardDueDatePopup")
 template(name="editCardEndDatePopup")
 template(name="editCardEndDatePopup")
   form.edit-card-end-date
   form.edit-card-end-date
     .datepicker
     .datepicker
+      // Date input field (existing)
+      .calendar-selector
+        label(for="calendar-end") 🗓️
+        input#calendar-end.js-calendar-date(type="date")
+      // Time input field (if present)
     .clear-date
     .clear-date
       a.js-clear-date {{_ 'clear'}}
       a.js-clear-date {{_ 'clear'}}
     .datepicker-actions
     .datepicker-actions

+ 11 - 0
client/components/cards/cardDate.js

@@ -50,6 +50,17 @@ import {
   onRendered() {
   onRendered() {
     super.onRendered();
     super.onRendered();
     // DatePicker base class handles initialization with native HTML inputs
     // DatePicker base class handles initialization with native HTML inputs
+      const self = this;
+      this.$('.js-calendar-date').on('change', function(evt) {
+        const currentUser = ReactiveCache.getCurrentUser && ReactiveCache.getCurrentUser();
+        const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
+        const value = evt.target.value;
+        if (value) {
+          // Format date according to user preference
+          const formatted = formatDateByUserPreference(new Date(value), dateFormat, true);
+          self._storeDate(new Date(value));
+        }
+      });
   }
   }
 
 
   _storeDate(date) {
   _storeDate(date) {

+ 1 - 1
client/components/forms/datepicker.jade

@@ -4,7 +4,7 @@ template(name="datepicker")
             .fields
             .fields
                 .left
                 .left
                     label(for="date") {{_ 'date'}}
                     label(for="date") {{_ 'date'}}
-                    input.js-date-field#date(type="text" name="date" value=showDate autofocus placeholder=dateFormat)
+                    input.js-date-field#date(type="date" name="date" value=showDate autofocus)
                 .right
                 .right
                     label(for="time") {{_ 'time'}}
                     label(for="time") {{_ 'time'}}
                     input.js-time-field#time(type="time" name="time" value=showTime)
                     input.js-time-field#time(type="time" name="time" value=showTime)

+ 2 - 3
client/components/main/popup.css

@@ -293,6 +293,8 @@
   overflow-y: auto !important;
   overflow-y: auto !important;
 }
 }
 
 
+
+
 .pop-over[data-popup="editCardReceivedDatePopup"] .edit-date button,
 .pop-over[data-popup="editCardReceivedDatePopup"] .edit-date button,
 .pop-over[data-popup="editCardStartDatePopup"] .edit-date button,
 .pop-over[data-popup="editCardStartDatePopup"] .edit-date button,
 .pop-over[data-popup="editCardDueDatePopup"] .edit-date button,
 .pop-over[data-popup="editCardDueDatePopup"] .edit-date button,
@@ -387,9 +389,6 @@
   margin: 0;
   margin: 0;
   visibility: hidden;
   visibility: hidden;
 }
 }
-.pop-over .quiet {
-/*  padding: 6px 6px 4px;*/
-}
 .pop-over.search-over {
 .pop-over.search-over {
   background: #f0f0f0;
   background: #f0f0f0;
   min-height: 14vh;
   min-height: 14vh;

+ 42 - 122
client/lib/datepicker.js

@@ -1,33 +1,27 @@
 import { ReactiveCache } from '/imports/reactiveCache';
 import { ReactiveCache } from '/imports/reactiveCache';
 import { TAPi18n } from '/imports/i18n';
 import { TAPi18n } from '/imports/i18n';
-import { 
-  formatDateTime, 
-  formatDate, 
-  formatDateByUserPreference,
-  formatTime, 
-  getISOWeek, 
-  isValidDate, 
-  isBefore, 
-  isAfter, 
-  isSame, 
-  add, 
-  subtract, 
-  startOf, 
-  endOf, 
-  format, 
-  parseDate, 
-  now, 
-  createDate, 
-  fromNow, 
-  calendar 
-} from '/imports/lib/dateUtils';
 
 
-// Helper function to get time format for 24 hours
-function adjustedTimeFormat() {
-  return 'HH:mm';
+// Helper to check if a date is valid
+function isValidDate(date) {
+  return date instanceof Date && !isNaN(date);
 }
 }
 
 
-//   .replace(/HH/i, 'H');
+// Format date as YYYY-MM-DD
+function formatDate(date) {
+  if (!isValidDate(date)) return '';
+  const year = date.getFullYear();
+  const month = String(date.getMonth() + 1).padStart(2, '0');
+  const day = String(date.getDate()).padStart(2, '0');
+  return `${year}-${month}-${day}`;
+}
+
+// Format time as HH:mm
+function formatTime(date) {
+  if (!isValidDate(date)) return '';
+  const hours = String(date.getHours()).padStart(2, '0');
+  const minutes = String(date.getMinutes()).padStart(2, '0');
+  return `${hours}:${minutes}`;
+}
 
 
 export class DatePicker extends BlazeComponent {
 export class DatePicker extends BlazeComponent {
   template() {
   template() {
@@ -51,35 +45,25 @@ export class DatePicker extends BlazeComponent {
   }
   }
 
 
   onRendered() {
   onRendered() {
-    // Set initial values for text and time inputs
+    // Set initial values for native HTML inputs
     if (isValidDate(this.date.get())) {
     if (isValidDate(this.date.get())) {
       const dateInput = this.find('#date');
       const dateInput = this.find('#date');
       const timeInput = this.find('#time');
       const timeInput = this.find('#time');
       
       
       if (dateInput) {
       if (dateInput) {
-        // Use user's preferred format for text input
-        const currentUser = ReactiveCache.getCurrentUser();
-        const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
-        dateInput.value = formatDateByUserPreference(this.date.get(), userFormat, false);
+        dateInput.value = formatDate(this.date.get());
       }
       }
-      if (timeInput) {
-        if (!timeInput.value && this.defaultTime) {
-          const defaultDate = new Date(this.defaultTime);
-          timeInput.value = formatTime(defaultDate);
-        } else if (isValidDate(this.date.get())) {
-          timeInput.value = formatTime(this.date.get());
-        }
+      if (timeInput && !timeInput.value && this.defaultTime) {
+        const defaultDate = new Date(this.defaultTime);
+        timeInput.value = formatTime(defaultDate);
+      } else if (timeInput && isValidDate(this.date.get())) {
+        timeInput.value = formatTime(this.date.get());
       }
       }
     }
     }
   }
   }
 
 
   showDate() {
   showDate() {
-    if (isValidDate(this.date.get())) {
-      // Use user's preferred format for display, but HTML date input needs YYYY-MM-DD
-      const currentUser = ReactiveCache.getCurrentUser();
-      const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
-      return formatDateByUserPreference(this.date.get(), userFormat, false);
-    }
+    if (isValidDate(this.date.get())) return formatDate(this.date.get());
     return '';
     return '';
   }
   }
   showTime() {
   showTime() {
@@ -87,56 +71,22 @@ export class DatePicker extends BlazeComponent {
     return '';
     return '';
   }
   }
   dateFormat() {
   dateFormat() {
-    const currentUser = ReactiveCache.getCurrentUser();
-    const userFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD';
-    // Convert format to localized placeholder
-    switch (userFormat) {
-      case 'DD-MM-YYYY':
-        return TAPi18n.__('date-format-dd-mm-yyyy') || 'PP-KK-VVVV';
-      case 'MM-DD-YYYY':
-        return TAPi18n.__('date-format-mm-dd-yyyy') || 'KK-PP-VVVV';
-      case 'YYYY-MM-DD':
-      default:
-        return TAPi18n.__('date-format-yyyy-mm-dd') || 'VVVV-KK-PP';
-    }
+    return 'YYYY-MM-DD';
   }
   }
   timeFormat() {
   timeFormat() {
-    return 'LT';
+    return 'HH:mm';
   }
   }
 
 
   events() {
   events() {
     return [
     return [
       {
       {
         'change .js-date-field'() {
         'change .js-date-field'() {
-          // Text input date validation
-          const dateInput = this.find('#date');
-          if (!dateInput) return;
-          
-          const dateValue = dateInput.value;
+          // Native HTML date input validation
+          const dateValue = this.find('#date').value;
           if (dateValue) {
           if (dateValue) {
-            // Try to parse different date formats
-            const formats = [
-              'YYYY-MM-DD',
-              'DD-MM-YYYY', 
-              'MM-DD-YYYY',
-              'DD/MM/YYYY',
-              'MM/DD/YYYY',
-              'DD.MM.YYYY',
-              'MM.DD.YYYY'
-            ];
-            
-            let parsedDate = null;
-            for (const format of formats) {
-              parsedDate = parseDate(dateValue, [format], true);
-              if (parsedDate) break;
-            }
-            
-            // Fallback to native Date parsing
-            if (!parsedDate) {
-              parsedDate = new Date(dateValue);
-            }
-
-            if (isValidDate(parsedDate)) {
+            // HTML date input format is always YYYY-MM-DD
+            const dateObj = new Date(dateValue + 'T12:00:00');
+            if (isValidDate(dateObj)) {
               this.error.set('');
               this.error.set('');
             } else {
             } else {
               this.error.set('invalid-date');
               this.error.set('invalid-date');
@@ -145,12 +95,10 @@ export class DatePicker extends BlazeComponent {
         },
         },
         'change .js-time-field'() {
         'change .js-time-field'() {
           // Native HTML time input validation
           // Native HTML time input validation
-          const timeInput = this.find('#time');
-          if (!timeInput) return;
-          
-          const timeValue = timeInput.value;
+          const timeValue = this.find('#time').value;
           if (timeValue) {
           if (timeValue) {
-            const timeObj = new Date(`1970-01-01T${timeValue}`);
+            // HTML time input format is always HH:mm
+            const timeObj = new Date(`1970-01-01T${timeValue}:00`);
             if (isValidDate(timeObj)) {
             if (isValidDate(timeObj)) {
               this.error.set('');
               this.error.set('');
             } else {
             } else {
@@ -170,44 +118,16 @@ export class DatePicker extends BlazeComponent {
             return;
             return;
           }
           }
 
 
-          // Try to parse different date formats
-          const formats = [
-            'YYYY-MM-DD',
-            'DD-MM-YYYY', 
-            'MM-DD-YYYY',
-            'DD/MM/YYYY',
-            'MM/DD/YYYY',
-            'DD.MM.YYYY',
-            'MM.DD.YYYY'
-          ];
+          // Combine date and time: HTML date input is YYYY-MM-DD, time input is HH:mm
+          const dateTimeString = `${dateValue}T${timeValue}:00`;
+          const newCompleteDate = new Date(dateTimeString);
           
           
-          let parsedDate = null;
-          for (const format of formats) {
-            parsedDate = parseDate(dateValue, [format], true);
-            if (parsedDate) break;
-          }
-          
-          // Fallback to native Date parsing
-          if (!parsedDate) {
-            parsedDate = new Date(dateValue);
-          }
-
-          if (!isValidDate(parsedDate)) {
+          if (!isValidDate(newCompleteDate)) {
             this.error.set('invalid');
             this.error.set('invalid');
             return;
             return;
           }
           }
 
 
-          // Combine with time
-          const timeObj = new Date(`1970-01-01T${timeValue}`);
-          if (!isValidDate(timeObj)) {
-            this.error.set('invalid-time');
-            return;
-          }
-
-          // Set the time on the parsed date
-          parsedDate.setHours(timeObj.getHours(), timeObj.getMinutes(), 0, 0);
-
-          this._storeDate(parsedDate);
+          this._storeDate(newCompleteDate);
           Popup.back();
           Popup.back();
         },
         },
         'click .js-delete-date'(evt) {
         'click .js-delete-date'(evt) {