瀏覽代碼

number + date fields

Pouyan Savoli 7 年之前
父節點
當前提交
8b16955cc2

+ 24 - 0
client/components/cards/cardCustomFields.jade

@@ -31,6 +31,30 @@ template(name="cardCustomField-text")
                 else
                     | {{_ 'edit'}}
 
+template(name="cardCustomField-number")
+    if canModifyCard
+        +inlinedForm(classNames="js-card-customfield-number")
+            input(type="number" value=data.value)
+            .edit-controls.clearfix
+                button.primary(type="submit") {{_ 'save'}}
+                a.fa.fa-times-thin.js-close-inlined-form
+        else
+            a.js-open-inlined-form
+                if value
+                    = value
+                else
+                    | {{_ 'edit'}}
+
+template(name="cardCustomField-date")
+    if canModifyCard
+        a.js-edit-date(title="{{showTitle}}" class="{{classes}}")
+            if value
+                div.card-date
+                    time(datetime="{{showISODate}}")
+                        | {{showDate}}
+            else
+                | {{_ 'edit'}}
+
 template(name="cardCustomField-dropdown")
     if canModifyCard
         +inlinedForm(classNames="js-card-customfield-dropdown")

+ 97 - 6
client/components/cards/cardCustomFields.js

@@ -20,6 +20,7 @@ Template.cardCustomFieldsPopup.events({
     }
 });
 
+// cardCustomField
 const CardCustomField = BlazeComponent.extendComponent({
 
     getTemplate() {
@@ -28,6 +29,8 @@ const CardCustomField = BlazeComponent.extendComponent({
 
     onCreated() {
         const self = this;
+        self.card = Cards.findOne(Session.get('currentCard'));
+        self.customFieldId = this.data()._id;
     },
 
     canModifyCard() {
@@ -36,28 +39,118 @@ const CardCustomField = BlazeComponent.extendComponent({
 });
 CardCustomField.register('cardCustomField');
 
+// cardCustomField-text
 (class extends CardCustomField {
 
     onCreated() {
+        super.onCreated();
     }
 
     events() {
         return [{
             'submit .js-card-customfield-text'(evt) {
                 evt.preventDefault();
-                const card = Cards.findOne(Session.get('currentCard'));
-                const customFieldId = this.data()._id;
                 const value = this.currentComponent().getValue();
-                card.setCustomField(customFieldId,value);
+                this.card.setCustomField(this.customFieldId, value);
             },
         }];
     }
 
 }).register('cardCustomField-text');
 
+// cardCustomField-number
 (class extends CardCustomField {
 
     onCreated() {
+        super.onCreated();
+    }
+
+    events() {
+        return [{
+            'submit .js-card-customfield-number'(evt) {
+                evt.preventDefault();
+                const value = parseInt(this.find('input').value);
+                this.card.setCustomField(this.customFieldId, value);
+            },
+        }];
+    }
+
+}).register('cardCustomField-number');
+
+// cardCustomField-date
+(class extends CardCustomField {
+
+    onCreated() {
+        super.onCreated();
+        const self = this;
+        self.date = ReactiveVar();
+        self.now = ReactiveVar(moment());
+        window.setInterval(() => {
+            self.now.set(moment());
+        }, 60000);
+
+        self.autorun(() => {
+            self.date.set(moment(self.data().value));
+        });
+    }
+
+    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',
+        });
+    }
+
+    showISODate() {
+        return this.date.get().toISOString();
+    }
+
+    classes() {
+        if (this.date.get().isBefore(this.now.get(), 'minute') &&
+            this.now.get().isBefore(this.data().value)) {
+            return 'current';
+        }
+        return '';
+    }
+
+    showTitle() {
+        return `${TAPi18n.__('card-start-on')} ${this.date.get().format('LLLL')}`;
+    }
+
+    events() {
+        return [{
+            'click .js-edit-date': Popup.open('cardCustomField-date'),
+        }];
+    }
+
+}).register('cardCustomField-date');
+
+// cardCustomField-datePopup
+(class extends DatePicker {
+    onCreated() {
+        super.onCreated();
+        const self = this;
+        self.card = Cards.findOne(Session.get('currentCard'));
+        self.customFieldId = this.data()._id;
+        this.data().value && this.date.set(moment(this.data().value));
+    }
+
+    _storeDate(date) {
+        this.card.setCustomField(this.customFieldId, date);
+    }
+
+    _deleteDate() {
+        this.card.setCustomField(this.customFieldId, '');
+    }
+}).register('cardCustomField-datePopup');
+
+// cardCustomField-dropdown
+(class extends CardCustomField {
+
+    onCreated() {
+        super.onCreated();
         this._items = this.data().definition.settings.dropdownItems;
         this.items = this._items.slice(0);
         this.items.unshift({
@@ -77,10 +170,8 @@ CardCustomField.register('cardCustomField');
         return [{
             'submit .js-card-customfield-dropdown'(evt) {
                 evt.preventDefault();
-                const card = Cards.findOne(Session.get('currentCard'));
-                const customFieldId = this.data()._id;
                 const value = this.find('select').value;
-                card.setCustomField(customFieldId,value);
+                this.card.setCustomField(this.customFieldId, value);
             },
         }];
     }

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

@@ -1,19 +1,3 @@
-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")
   if canModifyCard
     a.js-edit-date.card-date(title="{{showTitle}}" class="{{classes}}")

+ 2 - 89
client/components/cards/cardDate.js

@@ -1,91 +1,4 @@
 // 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() {
-    const $picker = this.$('.js-datepicker').datepicker({
-      todayHighlight: true,
-      todayBtn: 'linked',
-      language: TAPi18n.getLanguage(),
-    }).on('changeDate', function(evt) {
-      this.find('#date').value = moment(evt.date).format('L');
-      this.error.set('');
-      this.find('#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');
-    return '';
-  },
-  showTime() {
-    if (this.date.get().isValid())
-      return this.date.get().format('LT');
-    return '';
-  },
-  dateFormat() {
-    return moment.localeData().longDateFormat('L');
-  },
-  timeFormat() {
-    return moment.localeData().longDateFormat('LT');
-  },
-
-  events() {
-    return [{
-      'keyup .js-date-field'() {
-        // parse for localized date format in strict mode
-        const dateMoment = moment(this.find('#date').value, 'L', true);
-        if (dateMoment.isValid()) {
-          this.error.set('');
-          this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
-        }
-      },
-      'keyup .js-time-field'() {
-        // parse for localized time format in strict mode
-        const dateMoment = moment(this.find('#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
-        const time = evt.target.time.value || moment(new Date().setHours(12, 0, 0)).format('LT');
-
-        const dateString = `${evt.target.date.value} ${time}`;
-        const newDate = moment(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();
-      },
-    }];
-  },
-});
-
 Template.dateBadge.helpers({
   canModifyCard() {
     return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly();
@@ -93,7 +6,7 @@ Template.dateBadge.helpers({
 });
 
 // editCardStartDatePopup
-(class extends EditCardDate {
+(class extends DatePicker {
   onCreated() {
     super.onCreated();
     this.data().startAt && this.date.set(moment(this.data().startAt));
@@ -109,7 +22,7 @@ Template.dateBadge.helpers({
 }).register('editCardStartDatePopup');
 
 // editCardDueDatePopup
-(class extends EditCardDate {
+(class extends DatePicker {
   onCreated() {
     super.onCreated();
     this.data().dueAt && this.date.set(moment(this.data().dueAt));

+ 0 - 19
client/components/cards/cardDate.styl

@@ -1,22 +1,3 @@
-.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

+ 15 - 0
client/components/forms/datepicker.jade

@@ -0,0 +1,15 @@
+template(name="datepicker")
+    .datepicker-container
+        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'}}

+ 17 - 0
client/components/forms/datepicker.styl

@@ -0,0 +1,17 @@
+.datepicker-container
+  .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

+ 86 - 0
client/lib/datepicker.js

@@ -0,0 +1,86 @@
+DatePicker = BlazeComponent.extendComponent({
+    template() {
+        return 'datepicker';
+    },
+
+    onCreated() {
+        this.error = new ReactiveVar('');
+        this.card = this.data();
+        this.date = new ReactiveVar(moment.invalid());
+    },
+
+    onRendered() {
+        const $picker = this.$('.js-datepicker').datepicker({
+            todayHighlight: true,
+            todayBtn: 'linked',
+            language: TAPi18n.getLanguage(),
+        }).on('changeDate', function(evt) {
+            this.find('#date').value = moment(evt.date).format('L');
+            this.error.set('');
+            this.find('#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');
+        return '';
+    },
+    showTime() {
+        if (this.date.get().isValid())
+            return this.date.get().format('LT');
+        return '';
+    },
+    dateFormat() {
+        return moment.localeData().longDateFormat('L');
+    },
+    timeFormat() {
+        return moment.localeData().longDateFormat('LT');
+    },
+
+    events() {
+        return [{
+            'keyup .js-date-field'() {
+                // parse for localized date format in strict mode
+                const dateMoment = moment(this.find('#date').value, 'L', true);
+                if (dateMoment.isValid()) {
+                    this.error.set('');
+                    this.$('.js-datepicker').datepicker('update', dateMoment.toDate());
+                }
+            },
+            'keyup .js-time-field'() {
+                // parse for localized time format in strict mode
+                const dateMoment = moment(this.find('#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
+                const time = evt.target.time.value || moment(new Date().setHours(12, 0, 0)).format('LT');
+
+                const dateString = `${evt.target.date.value} ${time}`;
+                const newDate = moment(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();
+            },
+        }];
+    },
+});

+ 1 - 0
i18n/en.i18n.json

@@ -111,6 +111,7 @@
     "card-start": "Start",
     "card-start-on": "Starts on",
     "cardAttachmentsPopup-title": "Attach From",
+    "cardCustomField-datePopup-title": "Change date",
     "cardCustomFieldsPopup-title": "Edit custom fields",
     "cardDeletePopup-title": "Delete Card?",
     "cardDetailsActionsPopup-title": "Card Actions",