From 8028b9f16a33553bd3a6e1955ced98f15843cb77 Mon Sep 17 00:00:00 2001
From: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Date: Fri, 16 Dec 2022 11:41:03 -0600
Subject: [PATCH] Upgrade `param-input` to Octane (#196)
* Convert `param-input` to glimmer components
---
.../discourse/components/param-input.hbs | 55 ++++++
.../discourse/components/param-input.js | 172 +++++++++++-------
.../components/param-inputs-wrapper.hbs | 12 ++
.../controllers/admin-plugins-explorer.js | 7 +
.../admin/components/q-params/boolean.hbs | 12 --
.../admin/components/q-params/generic.hbs | 2 -
.../admin/components/q-params/int.hbs | 2 -
.../admin/components/q-params/string.hbs | 2 -
.../admin/components/q-params/user_id.hbs | 7 -
.../admin/components/q-params/user_list.hbs | 2 -
.../templates/admin/plugins-explorer.hbs | 18 +-
.../templates/group-reports-show.hbs | 13 +-
12 files changed, 196 insertions(+), 108 deletions(-)
create mode 100644 assets/javascripts/discourse/components/param-input.hbs
create mode 100644 assets/javascripts/discourse/components/param-inputs-wrapper.hbs
delete mode 100644 assets/javascripts/discourse/templates/admin/components/q-params/boolean.hbs
delete mode 100644 assets/javascripts/discourse/templates/admin/components/q-params/generic.hbs
delete mode 100644 assets/javascripts/discourse/templates/admin/components/q-params/int.hbs
delete mode 100644 assets/javascripts/discourse/templates/admin/components/q-params/string.hbs
delete mode 100644 assets/javascripts/discourse/templates/admin/components/q-params/user_id.hbs
delete mode 100644 assets/javascripts/discourse/templates/admin/components/q-params/user_list.hbs
diff --git a/assets/javascripts/discourse/components/param-input.hbs b/assets/javascripts/discourse/components/param-input.hbs
new file mode 100644
index 0000000..70590bb
--- /dev/null
+++ b/assets/javascripts/discourse/components/param-input.hbs
@@ -0,0 +1,55 @@
+
+ {{#if (eq this.type "boolean")}}
+ {{#if @info.nullable}}
+
+ {{else}}
+
+ {{/if}}
+ {{@info.identifier}}
+
+ {{else if (eq this.type "int")}}
+
+ {{@info.identifier}}
+
+ {{else if (eq this.type "string")}}
+
+ {{@info.identifier}}
+
+ {{else if (eq this.type "user_id")}}
+
+ {{@info.identifier}}
+
+ {{else if (eq this.type "user_list")}}
+
+ {{@info.identifier}}
+
+ {{else}}
+
+ {{@info.identifier}}
+ {{/if}}
+
diff --git a/assets/javascripts/discourse/components/param-input.js b/assets/javascripts/discourse/components/param-input.js
index 31f7768..f66c321 100644
--- a/assets/javascripts/discourse/components/param-input.js
+++ b/assets/javascripts/discourse/components/param-input.js
@@ -1,10 +1,11 @@
-import Component from "@ember/component";
+import Component from "@glimmer/component";
import I18n from "I18n";
-import discourseComputed from "discourse-common/utils/decorators";
import Category from "discourse/models/category";
import { dasherize } from "@ember/string";
import { isEmpty } from "@ember/utils";
-import { computed } from "@ember/object";
+import { action } from "@ember/object";
+import { tracked } from "@glimmer/tracking";
+import { inject as service } from "@ember/service";
const layoutMap = {
int: "int",
@@ -26,58 +27,73 @@ const layoutMap = {
user_list: "user_list",
};
-function allowsInputTypeTime() {
- try {
- const inp = document.createElement("input");
- inp.attributes.type = "time";
- inp.attributes.type = "date";
- return true;
- } catch (e) {
- return false;
- }
-}
+export default class ParamInput extends Component {
+ @service site;
-export default Component.extend({
- classNameBindings: ["valid:valid:invalid", ":param"],
+ @tracked value;
+ @tracked boolValue;
+ @tracked nullableBoolValue;
- boolTypes: [
+ boolTypes = [
{ name: I18n.t("explorer.types.bool.true"), id: "Y" },
{ name: I18n.t("explorer.types.bool.false"), id: "N" },
{ name: I18n.t("explorer.types.bool.null_"), id: "#null" },
- ],
- initialValues: null,
+ ];
- init() {
- this._super(...arguments);
+ constructor() {
+ super(...arguments);
- if (this.initialValues && this.info.identifier in this.initialValues) {
- this.set("value", this.initialValues[this.info.identifier]);
+ const identifier = this.args.info.identifier;
+ const initialValues = this.args.initialValues;
+
+ // access parsed params if present to update values to previously ran values
+ if (initialValues && identifier in initialValues) {
+ const initialValue = initialValues[identifier];
+ if (this.type === "boolean") {
+ if (this.args.info.nullable) {
+ this.nullableBoolValue = initialValue;
+ } else {
+ this.boolValue = initialValue !== "false";
+ }
+ } else {
+ this.value =
+ this.args.info.type === "category_id"
+ ? this.dasherizeCategoryId(initialValue)
+ : initialValue;
+ }
+ } else {
+ // if no parsed params then get and set default values
+ const params = this.args.params;
+ this.value =
+ this.args.info.type === "category_id"
+ ? this.dasherizeCategoryId(params[identifier])
+ : params[identifier];
+ this.boolValue = params[identifier] !== "false";
+ this.nullableBoolValue = params[identifier];
}
- },
+ }
- value: computed("params", "info.identifier", {
- get() {
- return this.params[this.get("info.identifier")];
- },
- set(key, value) {
- this.params[this.get("info.identifier")] = value?.toString();
- return value;
- },
- }),
+ get type() {
+ const type = this.args.info.type;
+ if ((type === "time" || type === "date") && !allowsInputTypeTime()) {
+ return "string";
+ }
+ return layoutMap[type] || "generic";
+ }
- valueBool: computed("params", "info.identifier", {
- get() {
- return this.params[this.get("info.identifier")] !== "false";
- },
- set(key, value) {
- value = !!value;
- this.params[this.get("info.identifier")] = value.toString();
- return value;
- },
- }),
+ get valid() {
+ const nullable = this.args.info.nullable;
+ // intentionally use 'this.args' here instead of 'this.type'
+ // to get the original key instead of the translated value from the layoutMap
+ const type = this.args.info.type;
+ let value;
+
+ if (type === "boolean") {
+ value = nullable ? this.nullableBoolValue : this.boolValue;
+ } else {
+ value = this.value;
+ }
- @discourseComputed("value", "info.type", "info.nullable")
- valid(value, type, nullable) {
if (isEmpty(value)) {
return nullable;
}
@@ -104,10 +120,6 @@ export default Component.extend({
case "post_id":
return isPositiveInt || /\d+\/\d+(\?u=.*)?$/.test(value);
case "category_id":
- if (!isPositiveInt && value !== dasherize(value)) {
- this.set("value", dasherize(value));
- }
-
if (isPositiveInt) {
return !!this.site.categories.find((c) => c.id === intVal);
} else if (/\//.test(value)) {
@@ -132,21 +144,55 @@ export default Component.extend({
}
}
return true;
- },
+ }
- @discourseComputed("info.type")
- layoutType(type) {
- if ((type === "time" || type === "date") && !allowsInputTypeTime()) {
- return "string";
+ dasherizeCategoryId(value) {
+ const isPositiveInt = /^\d+$/.test(value);
+ if (!isPositiveInt && value !== dasherize(value)) {
+ return dasherize(value);
}
- if (layoutMap[type]) {
- return layoutMap[type];
- }
- return "generic";
- },
+ return value;
+ }
- @discourseComputed("layoutType")
- layoutName(layoutType) {
- return `admin/components/q-params/${layoutType}`;
- },
-});
+ @action
+ updateValue(input) {
+ // handle selectKit inputs as well as traditional inputs
+ const value = input.target ? input.target.value : input;
+ if (value.length) {
+ this.value =
+ this.args.info.type === "category_id"
+ ? this.dasherizeCategoryId(value.toString())
+ : value.toString();
+ } else {
+ this.value = value;
+ }
+
+ this.args.updateParams(this.args.info.identifier, this.value);
+ }
+
+ @action
+ updateBoolValue(input) {
+ this.boolValue = input.target.checked;
+ this.args.updateParams(
+ this.args.info.identifier,
+ this.boolValue.toString()
+ );
+ }
+
+ @action
+ updateNullableBoolValue(input) {
+ this.nullableBoolValue = input;
+ this.args.updateParams(this.args.info.identifier, this.nullableBoolValue);
+ }
+}
+
+function allowsInputTypeTime() {
+ try {
+ const input = document.createElement("input");
+ input.attributes.type = "time";
+ input.attributes.type = "date";
+ return true;
+ } catch (e) {
+ return false;
+ }
+}
diff --git a/assets/javascripts/discourse/components/param-inputs-wrapper.hbs b/assets/javascripts/discourse/components/param-inputs-wrapper.hbs
new file mode 100644
index 0000000..77ce00d
--- /dev/null
+++ b/assets/javascripts/discourse/components/param-inputs-wrapper.hbs
@@ -0,0 +1,12 @@
+{{#if @hasParams}}
+
+ {{#each @paramInfo as |pinfo|}}
+
+ {{/each}}
+
+{{/if}}
diff --git a/assets/javascripts/discourse/controllers/admin-plugins-explorer.js b/assets/javascripts/discourse/controllers/admin-plugins-explorer.js
index 527347e..9e806f6 100644
--- a/assets/javascripts/discourse/controllers/admin-plugins-explorer.js
+++ b/assets/javascripts/discourse/controllers/admin-plugins-explorer.js
@@ -312,6 +312,12 @@ export default Controller.extend({
});
},
+ // This is necessary with glimmer's one way data stream to get the child's
+ // changes of 'params' to bubble up.
+ updateParams(identifier, value) {
+ this.selectedItem.set(`params.${identifier}`, value);
+ },
+
run() {
if (this.get("selectedItem.dirty")) {
return;
@@ -325,6 +331,7 @@ export default Controller.extend({
showResults: false,
params: JSON.stringify(this.selectedItem.params),
});
+
ajax(
"/admin/plugins/explorer/queries/" +
this.get("selectedItem.id") +
diff --git a/assets/javascripts/discourse/templates/admin/components/q-params/boolean.hbs b/assets/javascripts/discourse/templates/admin/components/q-params/boolean.hbs
deleted file mode 100644
index f375e36..0000000
--- a/assets/javascripts/discourse/templates/admin/components/q-params/boolean.hbs
+++ /dev/null
@@ -1,12 +0,0 @@
-{{#if info.nullable}}
- {{combo-box
- valueAttribute="id"
- value=value
- nameProperty="name"
- content=boolTypes
- }}
-{{else}}
- {{input type="checkbox" checked=valueBool}}
-{{/if}}
-
-{{info.identifier}}
diff --git a/assets/javascripts/discourse/templates/admin/components/q-params/generic.hbs b/assets/javascripts/discourse/templates/admin/components/q-params/generic.hbs
deleted file mode 100644
index 2b0fd48..0000000
--- a/assets/javascripts/discourse/templates/admin/components/q-params/generic.hbs
+++ /dev/null
@@ -1,2 +0,0 @@
-{{text-field value=value}}
-{{info.identifier}}
diff --git a/assets/javascripts/discourse/templates/admin/components/q-params/int.hbs b/assets/javascripts/discourse/templates/admin/components/q-params/int.hbs
deleted file mode 100644
index efb887d..0000000
--- a/assets/javascripts/discourse/templates/admin/components/q-params/int.hbs
+++ /dev/null
@@ -1,2 +0,0 @@
-{{input type="number" value=value}}
-{{info.identifier}}
diff --git a/assets/javascripts/discourse/templates/admin/components/q-params/string.hbs b/assets/javascripts/discourse/templates/admin/components/q-params/string.hbs
deleted file mode 100644
index f1c5fdc..0000000
--- a/assets/javascripts/discourse/templates/admin/components/q-params/string.hbs
+++ /dev/null
@@ -1,2 +0,0 @@
-{{text-field value=value type="text"}}
-{{info.identifier}}
diff --git a/assets/javascripts/discourse/templates/admin/components/q-params/user_id.hbs b/assets/javascripts/discourse/templates/admin/components/q-params/user_id.hbs
deleted file mode 100644
index efc8f52..0000000
--- a/assets/javascripts/discourse/templates/admin/components/q-params/user_id.hbs
+++ /dev/null
@@ -1,7 +0,0 @@
-{{email-group-user-chooser
- value=value
- options=(hash maximum=1)
- onChange=(action (mut value))
-}}
-
-{{info.identifier}}
diff --git a/assets/javascripts/discourse/templates/admin/components/q-params/user_list.hbs b/assets/javascripts/discourse/templates/admin/components/q-params/user_list.hbs
deleted file mode 100644
index 141edc6..0000000
--- a/assets/javascripts/discourse/templates/admin/components/q-params/user_list.hbs
+++ /dev/null
@@ -1,2 +0,0 @@
-{{email-group-user-chooser value=value onChange=(action (mut value))}}
-{{info.identifier}}
diff --git a/assets/javascripts/discourse/templates/admin/plugins-explorer.hbs b/assets/javascripts/discourse/templates/admin/plugins-explorer.hbs
index 503a527..11569a8 100644
--- a/assets/javascripts/discourse/templates/admin/plugins-explorer.hbs
+++ b/assets/javascripts/discourse/templates/admin/plugins-explorer.hbs
@@ -212,17 +212,13 @@