From 7226240df31a9508b6a8840d697bd9f0f1988207 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Thu, 11 Apr 2019 11:14:34 +0200 Subject: [PATCH] UX: full revamp of local-dates form (#7357) --- .../components/timezone-input.js.es6 | 31 +++ .../discourse-local-dates-create-form.js.es6 | 107 ++++++- .../discourse-local-dates-create-form.hbs | 118 ++++---- .../common/discourse-local-dates.scss | 262 ++++++++++++------ .../config/locales/client.en.yml | 1 + 5 files changed, 352 insertions(+), 167 deletions(-) create mode 100644 app/assets/javascripts/select-kit/components/timezone-input.js.es6 diff --git a/app/assets/javascripts/select-kit/components/timezone-input.js.es6 b/app/assets/javascripts/select-kit/components/timezone-input.js.es6 new file mode 100644 index 00000000000..e141839a1d1 --- /dev/null +++ b/app/assets/javascripts/select-kit/components/timezone-input.js.es6 @@ -0,0 +1,31 @@ +import ComboBoxComponent from "select-kit/components/combo-box"; +import { default as computed } from "ember-addons/ember-computed-decorators"; + +export default ComboBoxComponent.extend({ + pluginApiIdentifiers: ["timezone-input"], + classNames: "timezone-input", + allowAutoSelectFirst: false, + fullWidthOnMobile: true, + filterable: true, + allowAny: false, + + @computed + content() { + let timezones; + + if ( + moment.locale() !== "en" && + typeof moment.tz.localizedNames === "function" + ) { + timezones = moment.tz.localizedNames(); + } + timezones = moment.tz.names(); + + return timezones.map(t => { + return { + id: t, + name: t + }; + }); + } +}); diff --git a/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 b/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 index 3274b724843..fcf9bbe41ee 100644 --- a/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 +++ b/plugins/discourse-local-dates/assets/javascripts/discourse/components/discourse-local-dates-create-form.js.es6 @@ -1,3 +1,6 @@ +/* global Pikaday:true */ +import { propertyNotEqual } from "discourse/lib/computed"; +import loadScript from "discourse/lib/load-script"; import { default as computed } from "ember-addons/ember-computed-decorators"; import { cookAsync } from "discourse/lib/text"; import debounce from "discourse/lib/debounce"; @@ -16,11 +19,16 @@ export default Ember.Component.extend({ advancedMode: false, isValid: true, timezone: null, - timezones: null, + fromSelected: null, + fromFilled: Ember.computed.notEmpty("date"), + toSelected: null, + toFilled: Ember.computed.notEmpty("toDate"), init() { this._super(...arguments); + this._picker = null; + this.setProperties({ timezones: [], formats: (this.siteSettings.discourse_local_dates_default_formats || "") @@ -34,7 +42,10 @@ export default Ember.Component.extend({ didInsertElement() { this._super(...arguments); - this._renderPreview(); + this._setupPicker().then(picker => { + this._picker = picker; + this.send("focusFrom"); + }); }, _renderPreview: debounce(function() { @@ -167,6 +178,11 @@ export default Ember.Component.extend({ return moment.tz.guess(); }, + timezoneIsDifferentFromUserTimezone: propertyNotEqual( + "currentUserTimezone", + "options.timezone" + ), + @computed("currentUserTimezone") formatedCurrentUserTimezone(timezone) { return timezone @@ -225,17 +241,6 @@ export default Ember.Component.extend({ ]; }, - @computed() - allTimezones() { - if ( - moment.locale() !== "en" && - typeof moment.tz.localizedNames === "function" - ) { - return moment.tz.localizedNames(); - } - return moment.tz.names(); - }, - _generateDateMarkup(config, options, isRange) { let text = `[date=${config.date}`; @@ -287,7 +292,36 @@ export default Ember.Component.extend({ return text; }, + @computed("fromConfig.dateTime") + formattedFrom(dateTime) { + return dateTime.format("LLLL"); + }, + + @computed("toConfig.dateTime", "toSelected") + formattedTo(dateTime, toSelected) { + const emptyText = toSelected + ? " " + : I18n.t("discourse_local_dates.create.form.until"); + + return dateTime.isValid() ? dateTime.format("LLLL") : emptyText; + }, + actions: { + eraseToDateTime() { + this.setProperties({ toDate: null, toTime: null }); + this._setPickerDate(null); + }, + + focusFrom() { + this.setProperties({ fromSelected: true, toSelected: false }); + this._setPickerDate(this.get("fromConfig.date")); + }, + + focusTo() { + this.setProperties({ toSelected: true, fromSelected: false }); + this._setPickerDate(this.get("toConfig.date")); + }, + advancedMode() { this.toggleProperty("advancedMode"); }, @@ -306,6 +340,53 @@ export default Ember.Component.extend({ } }, + _setupPicker() { + return new Ember.RSVP.Promise(resolve => { + loadScript("/javascripts/pikaday.js").then(() => { + const options = { + field: this.$(`.fake-input`)[0], + container: this.$(`#picker-container-${this.elementId}`)[0], + bound: false, + format: "YYYY-MM-DD", + reposition: false, + firstDay: 1, + defaultDate: moment(this.get("date"), this.dateFormat).toDate(), + setDefaultDate: true, + i18n: { + previousMonth: I18n.t("dates.previous_month"), + nextMonth: I18n.t("dates.next_month"), + months: moment.months(), + weekdays: moment.weekdays(), + weekdaysShort: moment.weekdaysShort() + }, + onSelect: date => { + const formattedDate = moment(date).format("YYYY-MM-DD"); + + if (this.get("fromSelected")) { + this.set("date", formattedDate); + } + + if (this.get("toSelected")) { + this.set("toDate", formattedDate); + } + } + }; + + resolve(new Pikaday(options)); + }); + }); + }, + + _setPickerDate(date) { + if (date && !moment(date, this.dateFormat).isValid()) { + date = null; + } + + Ember.run.schedule("afterRender", () => { + this._picker.setDate(date, true); + }); + }, + _closeModal() { const composer = Discourse.__container__.lookup("controller:composer"); composer.send("closeModal"); diff --git a/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs b/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs index 3ed2875420c..f18ec6573b1 100644 --- a/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs +++ b/plugins/discourse-local-dates/assets/javascripts/discourse/templates/components/discourse-local-dates-create-form.hbs @@ -9,83 +9,71 @@ {{i18n "discourse_local_dates.create.form.invalid_date"}} {{else}} -
- {{formatedCurrentUserTimezone}} {{currentPreview}} -
+ {{#if timezoneIsDifferentFromUserTimezone}} +
+ {{formatedCurrentUserTimezone}} {{currentPreview}} +
+ {{/if}} {{/unless}} {{computeDate}}
-
-
-
- -
- {{date-picker - onSelect=(action (mut date)) - class="date-input" - value=date - defaultDate="DD-MM-YYYY"}} -
-
- -
- -
- {{input input=(mut time) type="time" value=time class="time-input"}} -
-
+
+
+ {{d-icon "calendar-alt"}} + {{d-button + action=(action "focusFrom") + translatedLabel=formattedFrom + class="date-time"}}
-
- {{if site.mobileView "↓" "→"}} +
+ {{d-icon "calendar-alt"}} + {{d-button + action=(action "focusTo") + translatedLabel=formattedTo + class="date-time"}} + {{#if toFilled}} + {{d-button icon="times" action=(action "eraseToDateTime") class="delete-to-date"}} + {{/if}}
-
-
- -
- {{date-picker - onSelect=(action (mut toDate)) - class="date-input" - value=toDate - defaultDate="DD-MM-YYYY"}} -
-
- -
- -
- {{input input=(mut toTime) type="time" value=toTime class="time-input"}} -
-
-
+ {{#unless site.mobileView}} + {{timezone-input + headerIcon="globe" + value=timezone + onSelect=(action (mut timezone))}} + {{/unless}}
-
-
- -
- {{combo-box - class="timezone-input" - allowAny=false - content=allTimezones - value=timezone - onSelect=(action (mut timezone))}} +
+ {{input class="fake-input"}} +
+ + {{#if fromSelected}} +
+ {{d-icon "far-clock"}} + {{input input=(mut time) type="time" value=time class="time-picker"}}
-
+ {{/if}} + + {{#if toSelected}} + {{#if toDate}} +
+ {{d-icon "far-clock"}} + {{input input=(mut toTime) type="time" value=toTime class="time-picker"}} +
+ {{/if}} + {{/if}}
+ + {{#if site.mobileView}} + {{timezone-input + headerIcon="globe" + value=timezone + onSelect=(action (mut timezone))}} + {{/if}}
{{#if advancedMode}} @@ -148,7 +136,7 @@