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

View File

@ -1,9 +1,5 @@
import { import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance, import { click, visit } from "@ember/test-helpers";
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import { visit } from "@ember/test-helpers";
import { test } from "qunit"; import { test } from "qunit";
acceptance("Admin - Plugins", function (needs) { 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"); 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( assert
exists(".admin-plugins .admin-container .alert-error"), .dom("table.admin-plugins tr .plugin-name .name")
"displays an error for unknown routes" .hasText("some-test-plugin", "displays the plugin in the table");
);
assert.strictEqual( assert
table.querySelector("tr .version a.commit-hash").href, .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", "https://github.com/username/some-test-plugin/commit/1234567890abcdef",
"displays a commit hash with a link to commit url" "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)) (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> </StyleguideExample>

View File

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