From 68760cd3a508e6263d5c41ad4f356057a6471508 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=94=A6=E5=BF=83?=
<41134017+Lhcfl@users.noreply.github.com>
Date: Thu, 22 Aug 2024 23:24:12 +0800
Subject: [PATCH] UX: Rewrite date/time param-input using FormKit (#316)
This commit changes the date/time input (including `date`, `time`, and
`datetime` types) to the date/time input provided by FormKit.
---
.../discourse/components/param-input-form.gjs | 56 ++++++++++-
config/locales/client.en.yml | 2 +
.../components/param-input-test.js | 96 +++++++++++++++++++
3 files changed, 151 insertions(+), 3 deletions(-)
diff --git a/assets/javascripts/discourse/components/param-input-form.gjs b/assets/javascripts/discourse/components/param-input-form.gjs
index fef4b90..e53a325 100644
--- a/assets/javascripts/discourse/components/param-input-form.gjs
+++ b/assets/javascripts/discourse/components/param-input-form.gjs
@@ -20,9 +20,9 @@ const layoutMap = {
bigint: "string",
boolean: "boolean",
string: "string",
- time: "generic",
- date: "generic",
- datetime: "generic",
+ time: "time",
+ date: "date",
+ datetime: "datetime",
double: "string",
user_id: "user_id",
post_id: "string",
@@ -45,6 +45,8 @@ export const ERRORS = {
INVALID: I18n.t("explorer.form.errors.invalid"),
NO_SUCH_CATEGORY: I18n.t("explorer.form.errors.no_such_category"),
NO_SUCH_GROUP: I18n.t("explorer.form.errors.no_such_group"),
+ INVALID_DATE: (date) => I18n.t("explorer.form.errors.invalid_date", { date }),
+ INVALID_TIME: (time) => I18n.t("explorer.form.errors.invalid_time", { time }),
};
function digitalizeCategoryId(value) {
@@ -78,6 +80,8 @@ function serializeValue(type, value) {
return value?.join(",");
case "group_id":
return value[0];
+ case "datetime":
+ return value?.replaceAll("T", " ");
default:
return value?.toString();
}
@@ -119,6 +123,18 @@ function componentOf(info) {
return UserListInput;
case "group_list":
return GroupInput;
+ case "date":
+ return
+ <@field.Input @type="date" name={{@info.identifier}} />
+ ;
+ case "time":
+ return
+ <@field.Input @type="time" name={{@info.identifier}} />
+ ;
+ case "datetime":
+ return
+ <@field.Input @type="datetime-local" name={{@info.identifier}} />
+ ;
case "bigint":
case "string":
default:
@@ -213,6 +229,40 @@ export default class ParamInputForm extends Component {
return value[0];
}
return value;
+ case "date":
+ try {
+ if (!value) {
+ return null;
+ }
+ return moment(new Date(value).toISOString()).format("YYYY-MM-DD");
+ } catch (err) {
+ this.addError(info.identifier, ERRORS.INVALID_DATE(String(value)));
+ return null;
+ }
+ case "time":
+ try {
+ if (!value) {
+ return null;
+ }
+ return moment(new Date(`1970/01/01 ${value}`).toISOString()).format(
+ "HH:mm"
+ );
+ } catch (err) {
+ this.addError(info.identifier, ERRORS.INVALID_TIME(String(value)));
+ return null;
+ }
+ case "datetime":
+ try {
+ if (!value) {
+ return null;
+ }
+ return moment(new Date(value).toISOString()).format(
+ "YYYY-MM-DD HH:mm"
+ );
+ } catch (err) {
+ this.addError(info.identifier, ERRORS.INVALID_TIME(String(value)));
+ return null;
+ }
default:
return value;
}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index d5f3a43..1ac237f 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -94,6 +94,8 @@ en:
invalid: "Invalid"
no_such_category: "No such category"
no_such_group: "No such group"
+ invalid_date: "%{date} is a invalid date"
+ invalid_time: "%{time} is a invalid time"
group:
reports: "Reports"
admin:
diff --git a/test/javascripts/components/param-input-test.js b/test/javascripts/components/param-input-test.js
index 09f7b70..0d718cc 100644
--- a/test/javascripts/components/param-input-test.js
+++ b/test/javascripts/components/param-input-test.js
@@ -97,6 +97,54 @@ const InputTestCases = [
},
],
},
+ {
+ type: "date",
+ default: "2024-07-13",
+ initial: "1970-01-01",
+ tests: [
+ {
+ input: null,
+ data_null: undefined,
+ error: ERRORS.REQUIRED,
+ },
+ {
+ input: "2038-01-20",
+ data: "2038-01-20",
+ },
+ ],
+ },
+ {
+ type: "time",
+ default: "12:34",
+ initial: "11:45",
+ tests: [
+ {
+ input: null,
+ data_null: undefined,
+ error: ERRORS.REQUIRED,
+ },
+ {
+ input: "03:14",
+ data: "03:14",
+ },
+ ],
+ },
+ {
+ type: "datetime",
+ default: "2024-07-13 12:00",
+ initial: "1970-01-01 00:00",
+ tests: [
+ {
+ input: null,
+ data_null: undefined,
+ error: ERRORS.REQUIRED,
+ },
+ {
+ input: "2038-01-19 03:15",
+ data: "2038-01-19 03:15",
+ },
+ ],
+ },
];
module("Data Explorer Plugin | Component | param-input", function (hooks) {
@@ -284,4 +332,52 @@ module("Data Explorer Plugin | Component | param-input", function (hooks) {
.field("group_id")
.hasError(`${ERRORS.NO_SUCH_GROUP}: invalid_group_name`);
});
+
+ test("date, time, datetime with initial value in other formats", async function (assert) {
+ this.setProperties({
+ param_info: [
+ {
+ identifier: "date",
+ type: "date",
+ default: null,
+ nullable: false,
+ },
+ {
+ identifier: "time",
+ type: "time",
+ default: null,
+ nullable: false,
+ },
+ {
+ identifier: "datetime",
+ type: "datetime",
+ default: null,
+ nullable: false,
+ },
+ ],
+ initialValues: {
+ date: "19 January 2038",
+ time: "3:15 am",
+ datetime: "19 January 2038 3:15 am",
+ },
+ onRegisterApi: ({ submit }) => {
+ this.submit = submit;
+ },
+ });
+
+ await render(hbs`
+ `);
+
+ this.submit().then((res) => {
+ assert.deepEqual(res, {
+ date: "2038-01-19",
+ time: "03:15",
+ datetime: "2038-01-19 03:15",
+ });
+ });
+ });
});