mirror of
https://github.com/discourse/discourse.git
synced 2025-05-21 18:12:32 +08:00
UX: full revamp of local-dates form (#7357)
This commit is contained in:
@ -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");
|
||||
|
@ -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}}
|
||||
|
Reference in New Issue
Block a user