UX: improves local-dates modal form UI

This commit is contained in:
Joffrey JAFFEUX 2018-05-30 19:05:41 +02:00 committed by GitHub
parent 8128cbd7db
commit c3ec758107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 225 additions and 115 deletions

View File

@ -18,6 +18,7 @@ export default Ember.Component.extend({
this.set("date", moment().format(this.dateFormat));
this.set("time", moment().format(this.timeFormat));
this.set("currentMoment", moment());
this.set("format", `LLL`);
this.set("timezones", (this.siteSettings.discourse_local_dates_default_timezones || "").split("|").filter(f => f));
this.set("formats", (this.siteSettings.discourse_local_dates_default_formats || "").split("|"));
@ -34,6 +35,16 @@ export default Ember.Component.extend({
return moment.tz.guess();
},
@computed("formats")
previewedFormats(formats) {
return formats.map(format => {
return {
format: format,
preview: moment().format(format)
};
});
},
@computed
recurringOptions() {
return [
@ -88,6 +99,11 @@ export default Ember.Component.extend({
return dateTime.isValid();
},
@computed("advancedMode")
toggleModeBtnLabel(advancedMode) {
return advancedMode ? "discourse_local_dates.create.form.simple_mode" : "discourse_local_dates.create.form.advanced_mode";
},
actions: {
advancedMode() {
this.toggleProperty("advancedMode");

View File

@ -5,56 +5,78 @@
style="overflow: auto"}}
<div class="form">
<div class="control-group">
<div class="controls date-time">
{{date-picker-future class="date" value=date defaultDate="DD-MM-YYYY"}}
{{input type="time" value=time class="time"}}
<span>{{currentUserTimezone}}</span>
<div class="date-time-configuration">
<div class="control-group date">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.date_title"}}
</label>
<div class="controls">
{{date-picker-future 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 type="time" value=time class="time-input"}}
</div>
</div>
<span class="preview">{{currentUserTimezone}}</span>
</div>
<h3>{{i18n "discourse_local_dates.create.form.recurring_title"}}</h3>
<div class="control-group">
{{#unless validDate}}
<span class="validation-error">{{i18n "discourse_local_dates.create.form.invalid_date"}}</span>
{{/unless}}
<div class="control-group recurrence">
<label class="control-label">
{{i18n "discourse_local_dates.create.form.recurring_title"}}
</label>
{{#if advancedMode}}
<label>{{{i18n "discourse_local_dates.create.form.recurring_description"}}}</label>
<p>{{{i18n "discourse_local_dates.create.form.recurring_description"}}}</p>
{{/if}}
<div class="controls">
{{combo-box content=recurringOptions value=recurring none="discourse_local_dates.create.form.recurring_none"}}
{{combo-box content=recurringOptions class="recurrence-input" value=recurring none="discourse_local_dates.create.form.recurring_none"}}
</div>
</div>
{{d-button
class="advanced-mode-btn"
action=(action "advancedMode")
icon="cog"
label="discourse_local_dates.create.form.advanced_mode"}}
{{#if advancedMode}}
<div class="advanced-options">
<div class="control-group">
<label>
<div class="control-group format">
<label>{{i18n "discourse_local_dates.create.form.format_title"}}</label>
<p>
{{i18n "discourse_local_dates.create.form.format_description"}}
(<a target="_blank" rel="noopener" href="https://momentjs.com/docs/#/parsing/string-format/">?</a>)
</label>
<a target="_blank" rel="noopener" href="https://momentjs.com/docs/#/parsing/string-format/">
{{d-icon "question-circle"}}
</a>
</p>
<div class="controls">
{{text-field value=format}}
{{text-field value=format class="format-input"}}
</div>
</div>
<div class="control-group">
<ul class="formats">
{{#each formats as |format|}}
{{#each previewedFormats as |previewedFormat|}}
<li class="format">
<a href {{action "fillFormat" format}}>{{format}}</a>
<a class="moment-format" href {{action "fillFormat" previewedFormat.format}}>
{{previewedFormat.format}}
</a>
<span class="previewed-format">
{{previewedFormat.preview}}
</span>
</li>
{{/each}}
</ul>
</div>
<h3>{{i18n "discourse_local_dates.create.form.timezones_title"}}</h3>
<div class="control-group">
<label>{{i18n "discourse_local_dates.create.form.timezones_description"}}</label>
<div class="control-group timezones">
<label>{{i18n "discourse_local_dates.create.form.timezones_title"}}</label>
<p>{{i18n "discourse_local_dates.create.form.timezones_description"}}</p>
<div class="controls">
{{multi-select allowAny=false maximum=5 content=allTimezones values=timezones}}
{{multi-select class="timezones-input" allowAny=false maximum=5 content=allTimezones values=timezones}}
</div>
</div>
</div>
@ -63,16 +85,19 @@
{{/d-modal-body}}
<div class="modal-footer discourse-local-dates-create-modal-footer">
{{#if validDate}}
{{d-button class="btn"
action="save"
label="discourse_local_dates.create.form.insert"}}
{{else}}
<span class="validation-error">{{i18n "discourse_local_dates.create.form.invalid_date"}}</span>
{{/if}}
<a href {{action "cancel"}}>
{{i18n 'cancel'}}
<a class="cancel-action" href {{action "cancel"}}>
{{i18n "cancel"}}
</a>
{{d-button
class="advanced-mode-btn"
action=(action "advancedMode")
icon="cog"
label=toggleModeBtnLabel}}
</div>

View File

@ -0,0 +1,131 @@
.discourse-local-date {
display: inline-block;
vertical-align: top;
&.cooked {
color: $primary;
font-weight: bold;
cursor: pointer;
.d-icon-globe {
margin-right: .25em;
color: $primary-medium;
&:hover {
color: $primary-high;
}
}
&:hover .d-icon-globe {
color: $primary-high;
}
}
+ .discourse-local-date {
margin-left: .5em;
}
}
.discourse-local-dates-create-modal-footer {
display: flex;
align-items: center;
justify-content: flex-start;
&:before, &:after {
content: none;
}
.cancel-action {
margin: 0 5px 5px 0;
}
.btn + .cancel-action {
margin-left: 1em;
}
.advanced-mode-btn {
margin-left: auto;
}
}
.discourse-local-dates-create-modal {
min-height: 300px;
display: flex;
flex-direction: row;
.form {
flex: 1;
label {
font-weight: 700;
}
.date-time-configuration {
display: flex;
align-items: center;
.date {
.date-input {
margin-right: 1em;
.date-picker {
padding-top: 5px;
bottom: 5px;
margin: 0;
width: 120px;
text-align: left;
}
}
}
.time {
margin-right: 1em;
.time-input {
margin: 0 0.5em 0 0;
width: 120px;
padding: 3.5px 10px;
}
}
.preview {
margin-top: 16px;
}
}
.validation-error {
color: $danger;
}
.recurrence {
.recurrence-input {
width: 300px;
}
}
}
.format {
.format-input {
width: 280px;
}
}
.formats {
list-style: none;
padding: 0;
margin: 0;
.format {
.previewed-format {
color: $primary-medium;
}
}
}
.control-group.recurrence, .control-group.format, .control-group.timezones {
margin-top: 1em;
}
.timezones-input {
width: 99%;
}
}

View File

@ -1,83 +0,0 @@
.discourse-local-date {
display: inline-block;
vertical-align: top;
&.cooked {
color: $primary;
font-weight: bold;
cursor: pointer;
.d-icon-globe {
margin-right: .25em;
color: $primary-medium;
&:hover {
color: $primary-high;
}
}
&:hover .d-icon-globe {
color: $primary-high;
}
}
+ .discourse-local-date {
margin-left: .5em;
}
}
.discourse-local-dates-create-modal-footer {
display: flex;
align-items: center;
justify-content: space-between;
.validation-error {
color: $danger;
}
&:before, &:after {
content: none;
}
}
.discourse-local-dates-create-modal {
min-height: 300px;
display: flex;
flex-direction: row;
.form {
flex: 1;
.controls {
&.date-time {
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 1em;
.date {
margin: 0 0.5em 0 0;
}
.date-picker {
padding-top: 5px;
bottom: 5px;
margin: 0;
}
.time {
margin: 0 0.5em 0 0;
max-width: 100px;
}
}
}
.advanced-mode-btn {
margin-top: 2em;
margin-bottom: 1em;
}
}
.select-kit.multi-select {
width: 90%;
}
}

View File

@ -0,0 +1,16 @@
.discourse-local-dates-create-modal {
.form {
.date-time-configuration {
flex-direction: column;
align-items: flex-start;
.date .date-input .date-picker {
width: 200px;
}
.time .time-input {
width: 200px;
}
}
}
}

View File

@ -8,6 +8,7 @@ en:
form:
insert: Insert
advanced_mode: Advanced mode
simple_mode: Simple mode
format_description: "Format used to display the date to the user. Use \"\\T\\Z\" to display the user timezone in words (Europe/Paris)"
timezones_title: Timezones to display
timezones_description: Timezones will be used to display dates in preview and fallback.
@ -15,3 +16,6 @@ en:
recurring_description: "Define the recurrence of an event. You can also manually edit the recurring option generated by the form and use one of the following keys: years, quarters, months, weeks, days, hours, minutes, seconds, milliseconds."
recurring_none: No recurrence
invalid_date: Invalid date, make sure date and time are correct
date_title: Date
time_title: Time
format_title: Date format

View File

@ -5,7 +5,8 @@
hide_plugin if self.respond_to?(:hide_plugin)
register_asset "javascripts/discourse-local-dates.js"
register_asset "stylesheets/discourse-local-dates.scss"
register_asset "stylesheets/common/discourse-local-dates.scss"
register_asset "stylesheets/mobile/discourse-local-dates.scss"
register_asset "moment.js", :vendored_core_pretty_text
register_asset "moment-timezone.js", :vendored_core_pretty_text