mirror of
https://github.com/discourse/discourse.git
synced 2025-03-30 19:39:26 +08:00
UX: uses native date picker when possible (eg: not safari) (#12668)
Note that this is only applied on date-input and not the old date-picker for now. This commit is also slightly modifying admin report dates form to ensure the native picker is correctly used, as a result: it doesn’t auto refresh on date change and fixes a border bug.
This commit is contained in:
parent
0eeedf307a
commit
e2e936715e
app/assets
javascripts
admin/addon/components
discourse
app/components
tests/integration/components
stylesheets/common/components
@ -68,6 +68,8 @@ export default Component.extend({
|
||||
showDatesOptions: alias("model.dates_filtering"),
|
||||
showRefresh: or("showDatesOptions", "model.available_filters.length"),
|
||||
shouldDisplayTrend: and("showTrend", "model.prev_period"),
|
||||
endDate: null,
|
||||
startDate: null,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
@ -82,25 +84,21 @@ export default Component.extend({
|
||||
.includes(this.dataSourceName);
|
||||
}),
|
||||
|
||||
startDate: computed("filters.startDate", function () {
|
||||
if (this.filters && isPresent(this.filters.startDate)) {
|
||||
return moment(this.filters.startDate, "YYYY-MM-DD");
|
||||
} else {
|
||||
return moment();
|
||||
}
|
||||
}),
|
||||
|
||||
endDate: computed("filters.endDate", function () {
|
||||
if (this.filters && isPresent(this.filters.endDate)) {
|
||||
return moment(this.filters.endDate, "YYYY-MM-DD");
|
||||
} else {
|
||||
return moment();
|
||||
}
|
||||
}),
|
||||
|
||||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
let startDate = moment();
|
||||
if (this.filters && isPresent(this.filters.startDate)) {
|
||||
startDate = moment(this.filters.startDate, "YYYY-MM-DD");
|
||||
}
|
||||
this.set("startDate", startDate);
|
||||
|
||||
let endDate = moment();
|
||||
if (this.filters && isPresent(this.filters.endDate)) {
|
||||
endDate = moment(this.filters.endDate, "YYYY-MM-DD");
|
||||
}
|
||||
this.set("endDate", endDate);
|
||||
|
||||
if (this.report) {
|
||||
this._renderReport(this.report, this.forcedModes, this.currentMode);
|
||||
} else if (this.dataSourceName) {
|
||||
@ -213,7 +211,7 @@ export default Component.extend({
|
||||
|
||||
@action
|
||||
onChangeDateRange(range) {
|
||||
this.send("refreshReport", {
|
||||
this.setProperties({
|
||||
startDate: range.from,
|
||||
endDate: range.to,
|
||||
});
|
||||
|
@ -7,16 +7,26 @@ import { action } from "@ember/object";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { schedule } from "@ember/runloop";
|
||||
|
||||
function isInputDateSupported() {
|
||||
const input = document.createElement("input");
|
||||
const value = "a";
|
||||
input.setAttribute("type", "date");
|
||||
input.setAttribute("value", value);
|
||||
return input.value !== value;
|
||||
}
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ["d-date-input"],
|
||||
date: null,
|
||||
_picker: null,
|
||||
|
||||
@discourseComputed("site.mobileView")
|
||||
inputType(mobileView) {
|
||||
return mobileView ? "date" : "text";
|
||||
inputType() {
|
||||
return this.useNativePicker ? "date" : "text";
|
||||
},
|
||||
|
||||
useNativePicker: isInputDateSupported(),
|
||||
|
||||
click(event) {
|
||||
event.stopPropagation();
|
||||
},
|
||||
@ -32,7 +42,7 @@ export default Component.extend({
|
||||
let promise;
|
||||
const container = document.getElementById(this.containerId);
|
||||
|
||||
if (this.site.mobileView) {
|
||||
if (this.useNativePicker) {
|
||||
promise = this._loadNativePicker(container);
|
||||
} else {
|
||||
promise = this._loadPikadayPicker(container);
|
||||
|
@ -1,27 +1,17 @@
|
||||
import componentTest, {
|
||||
setupRenderingTest,
|
||||
} from "discourse/tests/helpers/component-test";
|
||||
import {
|
||||
discourseModule,
|
||||
queryAll,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import { click } from "@ember/test-helpers";
|
||||
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
|
||||
import hbs from "htmlbars-inline-precompile";
|
||||
|
||||
function dateInput() {
|
||||
return queryAll(".date-picker")[0];
|
||||
return query(".date-picker");
|
||||
}
|
||||
|
||||
function setDate(date) {
|
||||
this.set("date", date);
|
||||
}
|
||||
|
||||
async function pika(year, month, day) {
|
||||
await click(
|
||||
`.pika-button.pika-day[data-pika-year="${year}"][data-pika-month="${month}"][data-pika-day="${day}"]`
|
||||
);
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
|
||||
const DEFAULT_DATE = moment("2019-01-29");
|
||||
@ -37,7 +27,7 @@ discourseModule("Integration | Component | date-input", function (hooks) {
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(dateInput().value, "January 29, 2019");
|
||||
assert.equal(dateInput().value, "2019-01-29");
|
||||
},
|
||||
});
|
||||
|
||||
@ -50,8 +40,8 @@ discourseModule("Integration | Component | date-input", function (hooks) {
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await click(dateInput());
|
||||
await pika(2019, 0, 2);
|
||||
dateInput().value = "2019-01-02";
|
||||
dateInput().dispatchEvent(new Event("change"));
|
||||
|
||||
assert.ok(this.date.isSame(DEFAULT_DATE));
|
||||
},
|
||||
@ -66,10 +56,10 @@ discourseModule("Integration | Component | date-input", function (hooks) {
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await click(dateInput());
|
||||
await pika(2019, 0, 2);
|
||||
dateInput().value = "2019-02-02";
|
||||
dateInput().dispatchEvent(new Event("change"));
|
||||
|
||||
assert.ok(this.date.isSame(moment("2019-01-02")));
|
||||
assert.ok(this.date.isSame(moment("2019-02-02")));
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -1,26 +1,23 @@
|
||||
import componentTest, {
|
||||
setupRenderingTest,
|
||||
} from "discourse/tests/helpers/component-test";
|
||||
import {
|
||||
discourseModule,
|
||||
queryAll,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
|
||||
import hbs from "htmlbars-inline-precompile";
|
||||
|
||||
function fromDateInput() {
|
||||
return queryAll(".from.d-date-time-input .date-picker")[0];
|
||||
return query(".from.d-date-time-input .date-picker");
|
||||
}
|
||||
|
||||
function fromTimeInput() {
|
||||
return queryAll(".from.d-date-time-input .d-time-input .combo-box-header")[0];
|
||||
return query(".from.d-date-time-input .d-time-input .combo-box-header");
|
||||
}
|
||||
|
||||
function toDateInput() {
|
||||
return queryAll(".to.d-date-time-input .date-picker")[0];
|
||||
return query(".to.d-date-time-input .date-picker");
|
||||
}
|
||||
|
||||
function toTimeInput() {
|
||||
return queryAll(".to.d-date-time-input .d-time-input .combo-box-header")[0];
|
||||
return query(".to.d-date-time-input .d-time-input .combo-box-header");
|
||||
}
|
||||
|
||||
const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
|
||||
@ -38,7 +35,7 @@ discourseModule(
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(fromDateInput().value, "January 29, 2019");
|
||||
assert.equal(fromDateInput().value, "2019-01-29");
|
||||
assert.equal(fromTimeInput().dataset.name, "14:45");
|
||||
assert.equal(toDateInput().value, "");
|
||||
assert.equal(toTimeInput().dataset.name, "--:--");
|
||||
|
@ -4,29 +4,22 @@ import componentTest, {
|
||||
import {
|
||||
discourseModule,
|
||||
exists,
|
||||
queryAll,
|
||||
query,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
import { click } from "@ember/test-helpers";
|
||||
import hbs from "htmlbars-inline-precompile";
|
||||
|
||||
function dateInput() {
|
||||
return queryAll(".date-picker")[0];
|
||||
return query(".date-picker");
|
||||
}
|
||||
|
||||
function timeInput() {
|
||||
return queryAll(".d-time-input .combo-box-header")[0];
|
||||
return query(".d-time-input .combo-box-header");
|
||||
}
|
||||
|
||||
function setDate(date) {
|
||||
this.set("date", date);
|
||||
}
|
||||
|
||||
async function pika(year, month, day) {
|
||||
await click(
|
||||
`.pika-button.pika-day[data-pika-year="${year}"][data-pika-month="${month}"][data-pika-day="${day}"]`
|
||||
);
|
||||
}
|
||||
|
||||
const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
|
||||
|
||||
discourseModule("Integration | Component | date-time-input", function (hooks) {
|
||||
@ -40,7 +33,7 @@ discourseModule("Integration | Component | date-time-input", function (hooks) {
|
||||
},
|
||||
|
||||
test(assert) {
|
||||
assert.equal(dateInput().value, "January 29, 2019");
|
||||
assert.equal(dateInput().value, "2019-01-29");
|
||||
assert.equal(timeInput().dataset.name, "14:45");
|
||||
},
|
||||
});
|
||||
@ -53,8 +46,7 @@ discourseModule("Integration | Component | date-time-input", function (hooks) {
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await click(dateInput());
|
||||
await pika(2019, 0, 2);
|
||||
dateInput().value = "2019-01-02";
|
||||
|
||||
assert.ok(this.date.isSame(DEFAULT_DATE_TIME));
|
||||
},
|
||||
@ -69,8 +61,8 @@ discourseModule("Integration | Component | date-time-input", function (hooks) {
|
||||
},
|
||||
|
||||
async test(assert) {
|
||||
await click(dateInput());
|
||||
await pika(2019, 0, 2);
|
||||
dateInput().value = "2019-01-02";
|
||||
dateInput().dispatchEvent(new Event("change"));
|
||||
|
||||
assert.ok(this.date.isSame(moment("2019-01-02 14:45")));
|
||||
},
|
||||
|
@ -3,6 +3,7 @@
|
||||
cursor: pointer;
|
||||
flex-direction: column;
|
||||
min-width: 140px;
|
||||
flex: 1 0 100%;
|
||||
|
||||
.date-picker {
|
||||
cursor: pointer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user