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([]);