UX: full revamp of local-dates form (#7357)

This commit is contained in:
Joffrey JAFFEUX
2019-04-11 11:14:34 +02:00
committed by GitHub
parent 110512d4d0
commit 7226240df3
5 changed files with 352 additions and 167 deletions

View File

@ -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");

View File

@ -9,83 +9,71 @@
{{i18n "discourse_local_dates.create.form.invalid_date"}}
</div>
{{else}}
<div class="preview alert alert-info">
<b>{{formatedCurrentUserTimezone}} </b>{{currentPreview}}
</div>
{{#if timezoneIsDifferentFromUserTimezone}}
<div class="preview alert alert-info">
<b>{{formatedCurrentUserTimezone}} </b>{{currentPreview}}
</div>
{{/if}}
{{/unless}}
{{computeDate}}
<div class="date-time-configuration">
<div class="range">
<div class="from">
<div class="control-group date">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.date_title"}}
</label>
<div class="controls">
{{date-picker
onSelect=(action (mut date))
class="date-input"
value=date
defaultDate="DD-MM-YYYY"}}
</div>
</div>
<div class="control-group time">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.time_title"}}
</label>
<div class="controls">
{{input input=(mut time) type="time" value=time class="time-input"}}
</div>
</div>
<div class="inputs-panel">
<div class="date-time-control from {{if fromSelected 'is-selected'}} {{if fromFilled 'is-filled'}}">
{{d-icon "calendar-alt"}}
{{d-button
action=(action "focusFrom")
translatedLabel=formattedFrom
class="date-time"}}
</div>
<div class="to-indicator">
{{if site.mobileView "↓" "→"}}
<div class="date-time-control to {{if toSelected 'is-selected'}} {{if toFilled 'is-filled'}}">
{{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}}
</div>
<div class="to">
<div class="control-group date">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.date_title"}}
</label>
<div class="controls">
{{date-picker
onSelect=(action (mut toDate))
class="date-input"
value=toDate
defaultDate="DD-MM-YYYY"}}
</div>
</div>
<div class="control-group time">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.time_title"}}
</label>
<div class="controls">
{{input input=(mut toTime) type="time" value=toTime class="time-input"}}
</div>
</div>
</div>
{{#unless site.mobileView}}
{{timezone-input
headerIcon="globe"
value=timezone
onSelect=(action (mut timezone))}}
{{/unless}}
</div>
<div class="timezone">
<div class="control-group time">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.timezone"}}
</label>
<div class="controls">
{{combo-box
class="timezone-input"
allowAny=false
content=allTimezones
value=timezone
onSelect=(action (mut timezone))}}
<div class="picker-panel">
{{input class="fake-input"}}
<div class="date-picker" id="picker-container-{{elementId}}"></div>
{{#if fromSelected}}
<div class="time-pickers">
{{d-icon "far-clock"}}
{{input input=(mut time) type="time" value=time class="time-picker"}}
</div>
</div>
{{/if}}
{{#if toSelected}}
{{#if toDate}}
<div class="time-pickers">
{{d-icon "far-clock"}}
{{input input=(mut toTime) type="time" value=toTime class="time-picker"}}
</div>
{{/if}}
{{/if}}
</div>
{{#if site.mobileView}}
{{timezone-input
headerIcon="globe"
value=timezone
onSelect=(action (mut timezone))}}
{{/if}}
</div>
{{#if advancedMode}}
@ -148,7 +136,7 @@
<div class="modal-footer discourse-local-dates-create-modal-footer">
{{#if isValid}}
{{d-button class="btn btn-default"
{{d-button class="btn btn-primary"
action=(action "save")
label="discourse_local_dates.create.form.insert"}}
{{/if}}