FIX: Improve admin plugin list and modernize code (#23256)
This commit contains a few improvements: * Use LinkTo instead of a button with a weird action referencing the controller to navigate to the filtered settings for a plugin * Add an AdminPlugin model with tracked properties and use that when toggling the setting on/off and in the templates * Make it so the Settings button for a plugin navigates to the correct site setting category instead of always just going to the generic "plugins" one if possible
This commit is contained in:
parent
4b52269827
commit
5fc93b95cc
|
@ -1,6 +1,6 @@
|
|||
{{#if this.commitHash}}
|
||||
<a
|
||||
href={{@plugin.commit_url}}
|
||||
href={{@plugin.commitUrl}}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="current commit-hash"
|
||||
|
|
|
@ -6,6 +6,6 @@ export default class PluginCommitHash extends Component {
|
|||
}
|
||||
|
||||
get commitHash() {
|
||||
return this.args.plugin.commit_hash;
|
||||
return this.args.plugin.commitHash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Controller from "@ember/controller";
|
||||
import { action, set } from "@ember/object";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import SiteSetting from "admin/models/site-setting";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
@ -9,16 +9,15 @@ export default class AdminPluginsIndexController extends Controller {
|
|||
|
||||
@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);
|
||||
plugin.enabled = newValue;
|
||||
await SiteSetting.update(plugin.enabledSetting, newValue);
|
||||
this.session.requiresRefresh = true;
|
||||
} catch (e) {
|
||||
set(plugin, "enabled", oldValue);
|
||||
plugin.enabled = oldValue;
|
||||
popupAjaxError(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,20 +5,22 @@ export default class AdminPluginsController extends Controller {
|
|||
@service router;
|
||||
|
||||
get adminRoutes() {
|
||||
return this.allAdminRoutes.filter((r) => this.routeExists(r.full_location));
|
||||
return this.allAdminRoutes.filter((route) =>
|
||||
this.routeExists(route.full_location)
|
||||
);
|
||||
}
|
||||
|
||||
get brokenAdminRoutes() {
|
||||
return this.allAdminRoutes.filter(
|
||||
(r) => !this.routeExists(r.full_location)
|
||||
(route) => !this.routeExists(route.full_location)
|
||||
);
|
||||
}
|
||||
|
||||
get allAdminRoutes() {
|
||||
return this.model
|
||||
.filter((p) => p?.enabled)
|
||||
.map((p) => {
|
||||
return p.admin_route;
|
||||
.filter((plugin) => plugin?.enabled)
|
||||
.map((plugin) => {
|
||||
return plugin.adminRoute;
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import { tracked } from "@glimmer/tracking";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default class AdminPlugin {
|
||||
static create(args = {}) {
|
||||
return new AdminPlugin(args);
|
||||
}
|
||||
|
||||
@tracked enabled;
|
||||
|
||||
constructor(args = {}) {
|
||||
this.about = args.about;
|
||||
this.adminRoute = args.admin_route;
|
||||
this.commitHash = args.commit_hash;
|
||||
this.commitUrl = args.commit_url;
|
||||
this.enabled = args.enabled;
|
||||
this.enabledSetting = args.enabled_setting;
|
||||
this.hasSettings = args.has_settings;
|
||||
this.id = args.id;
|
||||
this.isOfficial = args.is_official;
|
||||
this.name = args.name;
|
||||
this.url = args.url;
|
||||
this.version = args.version;
|
||||
}
|
||||
|
||||
get settingCategoryName() {
|
||||
const snakeCaseName = this.name.replaceAll("-", "_");
|
||||
|
||||
// We do this because the site setting list is grouped by category,
|
||||
// with plugins that have their root site setting key defined as `plugins:`
|
||||
// being grouped under the generic "plugins" category.
|
||||
//
|
||||
// If a site setting has defined a proper root key and translated category name,
|
||||
// we can use that instead to go directly to the setting category.
|
||||
//
|
||||
// Over time, no plugins should be missing this data.
|
||||
const translationAttempt = I18n.lookup(
|
||||
`admin.site_settings.categories.${snakeCaseName}`
|
||||
);
|
||||
if (translationAttempt) {
|
||||
return snakeCaseName;
|
||||
}
|
||||
|
||||
return "plugins";
|
||||
}
|
||||
}
|
|
@ -1,28 +1,13 @@
|
|||
import { action } from "@ember/object";
|
||||
import Route from "@ember/routing/route";
|
||||
import AdminPlugin from "admin/models/admin-plugin";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default class AdminPluginsRoute extends Route {
|
||||
@service router;
|
||||
|
||||
model() {
|
||||
return this.store.findAll("plugin");
|
||||
}
|
||||
|
||||
@action
|
||||
showSettings(plugin) {
|
||||
const controller = this.controllerFor("adminSiteSettings");
|
||||
this.router
|
||||
.transitionTo("adminSiteSettingsCategory", "plugins")
|
||||
.then(() => {
|
||||
if (plugin) {
|
||||
// filterContent() is normally on a debounce from typing.
|
||||
// Because we don't want the default of "All Results", we tell it
|
||||
// to skip the next debounce.
|
||||
controller.set("filter", `plugin:${plugin.id}`);
|
||||
controller.set("_skipBounce", true);
|
||||
controller.filterContentNow("plugins");
|
||||
}
|
||||
});
|
||||
return this.store
|
||||
.findAll("plugin")
|
||||
.then((plugins) => plugins.map((plugin) => AdminPlugin.create(plugin)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
{{#each this.model as |plugin|}}
|
||||
<tr data-plugin-name={{plugin.name}}>
|
||||
<td>
|
||||
{{#if plugin.is_official}}
|
||||
{{#if plugin.isOfficial}}
|
||||
{{d-icon
|
||||
"check-circle"
|
||||
title="admin.plugins.official"
|
||||
|
@ -47,7 +47,7 @@
|
|||
</td>
|
||||
<td class="col-enabled">
|
||||
<div class="label">{{i18n "admin.plugins.enabled"}}</div>
|
||||
{{#if plugin.enabled_setting}}
|
||||
{{#if plugin.enabledSetting}}
|
||||
<DToggleSwitch
|
||||
@state={{plugin.enabled}}
|
||||
{{on "click" (fn this.togglePluginEnabled plugin)}}
|
||||
|
@ -58,14 +58,17 @@
|
|||
</td>
|
||||
<td class="settings">
|
||||
{{#if this.currentUser.admin}}
|
||||
{{#if plugin.has_settings}}
|
||||
<DButton
|
||||
@class="btn-default"
|
||||
@action={{route-action "showSettings"}}
|
||||
@actionParam={{plugin}}
|
||||
@icon="cog"
|
||||
@label="admin.plugins.change_settings_short"
|
||||
/>
|
||||
{{#if plugin.hasSettings}}
|
||||
<LinkTo
|
||||
class="btn-default btn btn-icon-text"
|
||||
@route="adminSiteSettingsCategory"
|
||||
@model={{plugin.settingCategoryName}}
|
||||
@query={{hash filter=(concat "plugin:" plugin.name)}}
|
||||
data-plugin-setting-button={{plugin.name}}
|
||||
>
|
||||
{{d-icon "cog"}}
|
||||
{{i18n "admin.plugins.change_settings_short"}}
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</td>
|
||||
|
|
Loading…
Reference in New Issue