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:
Joffrey JAFFEUX 2021-04-22 10:34:23 +02:00 committed by GitHub
parent 0eeedf307a
commit e2e936715e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 62 deletions

View File

@ -68,6 +68,8 @@ export default Component.extend({
showDatesOptions: alias("model.dates_filtering"), showDatesOptions: alias("model.dates_filtering"),
showRefresh: or("showDatesOptions", "model.available_filters.length"), showRefresh: or("showDatesOptions", "model.available_filters.length"),
shouldDisplayTrend: and("showTrend", "model.prev_period"), shouldDisplayTrend: and("showTrend", "model.prev_period"),
endDate: null,
startDate: null,
init() { init() {
this._super(...arguments); this._super(...arguments);
@ -82,25 +84,21 @@ export default Component.extend({
.includes(this.dataSourceName); .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() { didReceiveAttrs() {
this._super(...arguments); 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) { if (this.report) {
this._renderReport(this.report, this.forcedModes, this.currentMode); this._renderReport(this.report, this.forcedModes, this.currentMode);
} else if (this.dataSourceName) { } else if (this.dataSourceName) {
@ -213,7 +211,7 @@ export default Component.extend({
@action @action
onChangeDateRange(range) { onChangeDateRange(range) {
this.send("refreshReport", { this.setProperties({
startDate: range.from, startDate: range.from,
endDate: range.to, endDate: range.to,
}); });

View File

@ -7,16 +7,26 @@ import { action } from "@ember/object";
import loadScript from "discourse/lib/load-script"; import loadScript from "discourse/lib/load-script";
import { schedule } from "@ember/runloop"; 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({ export default Component.extend({
classNames: ["d-date-input"], classNames: ["d-date-input"],
date: null, date: null,
_picker: null, _picker: null,
@discourseComputed("site.mobileView") @discourseComputed("site.mobileView")
inputType(mobileView) { inputType() {
return mobileView ? "date" : "text"; return this.useNativePicker ? "date" : "text";
}, },
useNativePicker: isInputDateSupported(),
click(event) { click(event) {
event.stopPropagation(); event.stopPropagation();
}, },
@ -32,7 +42,7 @@ export default Component.extend({
let promise; let promise;
const container = document.getElementById(this.containerId); const container = document.getElementById(this.containerId);
if (this.site.mobileView) { if (this.useNativePicker) {
promise = this._loadNativePicker(container); promise = this._loadNativePicker(container);
} else { } else {
promise = this._loadPikadayPicker(container); promise = this._loadPikadayPicker(container);

View File

@ -1,27 +1,17 @@
import componentTest, { import componentTest, {
setupRenderingTest, setupRenderingTest,
} from "discourse/tests/helpers/component-test"; } from "discourse/tests/helpers/component-test";
import { import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { click } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function dateInput() { function dateInput() {
return queryAll(".date-picker")[0]; return query(".date-picker");
} }
function setDate(date) { function setDate(date) {
this.set("date", 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() {} function noop() {}
const DEFAULT_DATE = moment("2019-01-29"); const DEFAULT_DATE = moment("2019-01-29");
@ -37,7 +27,7 @@ discourseModule("Integration | Component | date-input", function (hooks) {
}, },
test(assert) { 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) { async test(assert) {
await click(dateInput()); dateInput().value = "2019-01-02";
await pika(2019, 0, 2); dateInput().dispatchEvent(new Event("change"));
assert.ok(this.date.isSame(DEFAULT_DATE)); assert.ok(this.date.isSame(DEFAULT_DATE));
}, },
@ -66,10 +56,10 @@ discourseModule("Integration | Component | date-input", function (hooks) {
}, },
async test(assert) { async test(assert) {
await click(dateInput()); dateInput().value = "2019-02-02";
await pika(2019, 0, 2); dateInput().dispatchEvent(new Event("change"));
assert.ok(this.date.isSame(moment("2019-01-02"))); assert.ok(this.date.isSame(moment("2019-02-02")));
}, },
}); });
}); });

View File

@ -1,26 +1,23 @@
import componentTest, { import componentTest, {
setupRenderingTest, setupRenderingTest,
} from "discourse/tests/helpers/component-test"; } from "discourse/tests/helpers/component-test";
import { import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function fromDateInput() { function fromDateInput() {
return queryAll(".from.d-date-time-input .date-picker")[0]; return query(".from.d-date-time-input .date-picker");
} }
function fromTimeInput() { 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() { function toDateInput() {
return queryAll(".to.d-date-time-input .date-picker")[0]; return query(".to.d-date-time-input .date-picker");
} }
function toTimeInput() { 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"); const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
@ -38,7 +35,7 @@ discourseModule(
}, },
test(assert) { 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(fromTimeInput().dataset.name, "14:45");
assert.equal(toDateInput().value, ""); assert.equal(toDateInput().value, "");
assert.equal(toTimeInput().dataset.name, "--:--"); assert.equal(toTimeInput().dataset.name, "--:--");

View File

@ -4,29 +4,22 @@ import componentTest, {
import { import {
discourseModule, discourseModule,
exists, exists,
queryAll, query,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function dateInput() { function dateInput() {
return queryAll(".date-picker")[0]; return query(".date-picker");
} }
function timeInput() { function timeInput() {
return queryAll(".d-time-input .combo-box-header")[0]; return query(".d-time-input .combo-box-header");
} }
function setDate(date) { function setDate(date) {
this.set("date", 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"); const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
discourseModule("Integration | Component | date-time-input", function (hooks) { discourseModule("Integration | Component | date-time-input", function (hooks) {
@ -40,7 +33,7 @@ discourseModule("Integration | Component | date-time-input", function (hooks) {
}, },
test(assert) { test(assert) {
assert.equal(dateInput().value, "January 29, 2019"); assert.equal(dateInput().value, "2019-01-29");
assert.equal(timeInput().dataset.name, "14:45"); assert.equal(timeInput().dataset.name, "14:45");
}, },
}); });
@ -53,8 +46,7 @@ discourseModule("Integration | Component | date-time-input", function (hooks) {
}, },
async test(assert) { async test(assert) {
await click(dateInput()); dateInput().value = "2019-01-02";
await pika(2019, 0, 2);
assert.ok(this.date.isSame(DEFAULT_DATE_TIME)); assert.ok(this.date.isSame(DEFAULT_DATE_TIME));
}, },
@ -69,8 +61,8 @@ discourseModule("Integration | Component | date-time-input", function (hooks) {
}, },
async test(assert) { async test(assert) {
await click(dateInput()); dateInput().value = "2019-01-02";
await pika(2019, 0, 2); dateInput().dispatchEvent(new Event("change"));
assert.ok(this.date.isSame(moment("2019-01-02 14:45"))); assert.ok(this.date.isSame(moment("2019-01-02 14:45")));
}, },

View File

@ -3,6 +3,7 @@
cursor: pointer; cursor: pointer;
flex-direction: column; flex-direction: column;
min-width: 140px; min-width: 140px;
flex: 1 0 100%;
.date-picker { .date-picker {
cursor: pointer; cursor: pointer;