UX: Introduce toggle-switch UI for plugins (#22910)

This commit makes some visual tweaks to the admin panel plugin list, and introduces functional 'toggle switches' for admins to enable/disable plugins more easily.

Co-authored-by: Jordan Vidrine <jordan@jordanvidrine.com>
This commit is contained in:
David Taylor 2023-08-03 15:19:33 +01:00 committed by GitHub
parent 2b04301c19
commit 45ae9d9bab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 29 deletions

View File

@ -0,0 +1,25 @@
import Controller from "@ember/controller";
import { action, set } from "@ember/object";
import { inject as service } from "@ember/service";
import SiteSetting from "admin/models/site-setting";
import { popupAjaxError } from "discourse/lib/ajax-error";
export default class AdminPluginsIndexController extends Controller {
@service session;
@action
async togglePluginEnabled(plugin) {
const enabledSettingName = plugin.enabled_setting;
const oldValue = plugin.enabled;
const newValue = !oldValue;
try {
set(plugin, "enabled", newValue);
await SiteSetting.update(enabledSettingName, newValue);
this.session.requiresRefresh = true;
} catch (e) {
set(plugin, "enabled", oldValue);
popupAjaxError(e);
}
}
}

View File

@ -31,7 +31,7 @@
href={{plugin.url}}
rel="noopener noreferrer"
target="_blank"
>{{plugin.name}}</a>
>{{plugin.name}} {{d-icon "external-link-alt"}}</a>
{{else}}
{{plugin.name}}
{{/if}}
@ -48,13 +48,12 @@
<td class="col-enabled">
<div class="label">{{i18n "admin.plugins.enabled"}}</div>
{{#if plugin.enabled_setting}}
{{#if plugin.enabled}}
{{i18n "admin.plugins.is_enabled"}}
<DToggleSwitch
@state={{plugin.enabled}}
{{on "click" (fn this.togglePluginEnabled plugin)}}
/>
{{else}}
{{i18n "admin.plugins.not_enabled"}}
{{/if}}
{{else}}
{{i18n "admin.plugins.is_enabled"}}
<DToggleSwitch @state={{plugin.enabled}} disabled={{true}} />
{{/if}}
</td>
<td class="settings">

View File

@ -1,9 +1,5 @@
import {
acceptance,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import { visit } from "@ember/test-helpers";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers";
import { test } from "qunit";
acceptance("Admin - Plugins", function (needs) {
@ -35,26 +31,39 @@ acceptance("Admin - Plugins", function (needs) {
],
})
);
server.put("/admin/site_settings/testplugin_enabled", () =>
helper.response()
);
});
test("shows plugin list", async function (assert) {
test("shows plugin list and can toggle state", async function (assert) {
await visit("/admin/plugins");
const table = query("table.admin-plugins");
assert.strictEqual(
table.querySelector("tr .plugin-name .name").innerText,
"some-test-plugin",
"displays the plugin in the table"
);
assert.true(
exists(".admin-plugins .admin-container .alert-error"),
"displays an error for unknown routes"
);
assert
.dom("table.admin-plugins tr .plugin-name .name")
.hasText("some-test-plugin", "displays the plugin in the table");
assert.strictEqual(
table.querySelector("tr .version a.commit-hash").href,
assert
.dom(".admin-plugins .admin-container .alert-error")
.exists("shows an error for unknown routes");
assert
.dom("table.admin-plugins tr .version a.commit-hash")
.hasAttribute(
"href",
"https://github.com/username/some-test-plugin/commit/1234567890abcdef",
"displays a commit hash with a link to commit url"
);
const toggleSelector = "table.admin-plugins tr .col-enabled button";
assert
.dom(toggleSelector)
.hasAttribute("aria-checked", "true", "displays the plugin as enabled");
await click(toggleSelector);
assert
.dom(toggleSelector)
.hasAttribute("aria-checked", "false", "displays the plugin as enabled");
});
});

View File

@ -162,4 +162,14 @@
(fn (mut @dummy.toggleSwitchState) (not @dummy.toggleSwitchState))
}}
/>
<DToggleSwitch
disabled="true"
@state={{true}}
title="Disabled with state=true"
/>
<DToggleSwitch
disabled="true"
@state={{false}}
title="Disabled with state=false"
/>
</StyleguideExample>

View File

@ -195,6 +195,10 @@
margin-right: 0.5em;
margin-bottom: 0.5em;
}
.d-toggle-switch {
display: inline-block;
}
}
.icons-examples,