From 231dc10bbdc13d2935e148547abcb8e83b75a6c8 Mon Sep 17 00:00:00 2001
From: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Date: Wed, 12 Oct 2022 13:38:42 -0500
Subject: [PATCH] Add replaceContent selectKit modifier (#18569)
Add the ability to modify a selectKit's content with `replaceContent`
Eg.
```
api.modifySelectKit("combo-box").replaceContent(() => {
return {
id: "foo",
name: "Foo",
};
});
```
will override existing content to only include the passed object
---
.../components/select-kit/api-test.js | 30 +++++++++++++++++++
.../select-kit/addon/mixins/plugin-api.js | 21 +++++++++++++
2 files changed, 51 insertions(+)
diff --git a/app/assets/javascripts/discourse/tests/integration/components/select-kit/api-test.js b/app/assets/javascripts/discourse/tests/integration/components/select-kit/api-test.js
index 7ee117c5aab..3bfdebbf004 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/select-kit/api-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/components/select-kit/api-test.js
@@ -102,4 +102,34 @@ module("Integration | Component | select-kit/api", function (hooks) {
assert.strictEqual(query("#test").innerText, "foo");
});
+
+ test("modifySelectKit(identifier).replaceContent", async function (assert) {
+ setDefaultState(this, null, { content: DEFAULT_CONTENT });
+
+ withPluginApi("0.8.43", (api) => {
+ api.modifySelectKit("combo-box").replaceContent(() => {
+ return {
+ id: "alpaca",
+ name: "Alpaca",
+ };
+ });
+ api.modifySelectKit("combo-box").replaceContent(() => {});
+ });
+
+ await render(hbs`
+
+
+ `);
+ await this.comboBox.expand();
+
+ assert.strictEqual(this.comboBox.rows().length, 1);
+
+ const replacementRow = this.comboBox.rowByIndex(0);
+ assert.ok(replacementRow.exists());
+ assert.strictEqual(replacementRow.value(), "alpaca");
+
+ await this.comboBox.collapse();
+
+ assert.notOk(this.singleSelect.rowByValue("alpaca").exists());
+ });
});
diff --git a/app/assets/javascripts/select-kit/addon/mixins/plugin-api.js b/app/assets/javascripts/select-kit/addon/mixins/plugin-api.js
index 7bf055f6578..f206221bdf0 100644
--- a/app/assets/javascripts/select-kit/addon/mixins/plugin-api.js
+++ b/app/assets/javascripts/select-kit/addon/mixins/plugin-api.js
@@ -29,6 +29,15 @@ function onChange(pluginApiIdentifiers, mutationFunction) {
_onChangeCallbacks[pluginApiIdentifiers].push(mutationFunction);
}
+let _replaceContentCallbacks = {};
+function replaceContent(pluginApiIdentifiers, contentFunction) {
+ if (isNone(_replaceContentCallbacks[pluginApiIdentifiers])) {
+ _replaceContentCallbacks[pluginApiIdentifiers] = [];
+ }
+
+ _replaceContentCallbacks[pluginApiIdentifiers].push(contentFunction);
+}
+
export function applyContentPluginApiCallbacks(content, component) {
makeArray(component.pluginApiIdentifiers).forEach((key) => {
(_prependContentCallbacks[key] || []).forEach((c) => {
@@ -43,6 +52,13 @@ export function applyContentPluginApiCallbacks(content, component) {
content = content.concat(makeArray(appendedContent));
}
});
+
+ (_replaceContentCallbacks[key] || []).forEach((c) => {
+ const replacementContent = c(component, content);
+ if (replacementContent) {
+ content = makeArray(replacementContent);
+ }
+ });
});
return content;
@@ -68,6 +84,10 @@ export function modifySelectKit(targetedIdentifier) {
onChange(targetedIdentifier, callback);
return modifySelectKit(targetedIdentifier);
},
+ replaceContent: (callback) => {
+ replaceContent(targetedIdentifier, callback);
+ return modifySelectKit(targetedIdentifier);
+ },
};
}
@@ -75,6 +95,7 @@ export function clearCallbacks() {
_appendContentCallbacks = {};
_prependContentCallbacks = {};
_onChangeCallbacks = {};
+ _replaceContentCallbacks = {};
}
const EMPTY_ARRAY = Object.freeze([]);