mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 08:49:06 +08:00
DEV: Move admin sidebar out of initializer (#25396)
Having the admin sidebar code in an instance initializer is not ideal because: * It runs during app boot which may not even be necessary based on site settings * It makes it hard for plugins to register additional links in time without resorting to before/after initializer gymnastics This PR moves the admin sidebar into a lib and creates the panel in custom-sections.js, then the sections and links are loaded when the main sidebar component is rendered, which leaves plugins enough time to add additional links in an initializer. --------- Co-authored-by: David Taylor <david@taylorhq.com>
This commit is contained in:
parent
6ad34a0152
commit
57ededb770
|
@ -2,13 +2,13 @@ import Component from "@glimmer/component";
|
|||
import { tracked } from "@glimmer/tracking";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { ADMIN_NAV_MAP } from "discourse/lib/sidebar/admin-nav-map";
|
||||
import {
|
||||
buildAdminSidebar,
|
||||
useAdminNavConfig,
|
||||
} from "discourse/instance-initializers/admin-sidebar";
|
||||
import { ADMIN_NAV_MAP } from "discourse/lib/sidebar/admin-nav-map";
|
||||
} from "discourse/lib/sidebar/admin-sidebar";
|
||||
import { resetPanelSections } from "discourse/lib/sidebar/custom-sections";
|
||||
import { ADMIN_PANEL } from "discourse/services/sidebar-state";
|
||||
import { ADMIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
|
||||
// TODO (martin) (2024-02-01) Remove this experimental UI.
|
||||
export default class AdminConfigAreaSidebarExperiment extends Component {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/services/sidebar-state";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
export default class AdminRoute extends DiscourseRoute {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { inject as service } from "@ember/service";
|
||||
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/services/sidebar-state";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
export default class AdminRoute extends DiscourseRoute {
|
||||
|
|
|
@ -42,7 +42,6 @@ import {
|
|||
} from "discourse/helpers/category-link";
|
||||
import { addUsernameSelectorDecorator } from "discourse/helpers/decorate-username-selector";
|
||||
import { registerCustomAvatarHelper } from "discourse/helpers/user-avatar";
|
||||
import { addAdminSidebarSectionLink } from "discourse/instance-initializers/admin-sidebar";
|
||||
import { addBeforeAuthCompleteCallback } from "discourse/instance-initializers/auth-complete";
|
||||
import { addPopupMenuOption } from "discourse/lib/composer/custom-popup-menu-options";
|
||||
import { registerDesktopNotificationHandler } from "discourse/lib/desktop-notifications";
|
||||
|
@ -67,6 +66,7 @@ import { addTagsHtmlCallback } from "discourse/lib/render-tags";
|
|||
import { addFeaturedLinkMetaDecorator } from "discourse/lib/render-topic-featured-link";
|
||||
import { addSearchResultsCallback } from "discourse/lib/search";
|
||||
import Sharing from "discourse/lib/sharing";
|
||||
import { addAdminSidebarSectionLink } from "discourse/lib/sidebar/admin-sidebar";
|
||||
import { addSectionLink as addCustomCommunitySectionLink } from "discourse/lib/sidebar/custom-community-section-links";
|
||||
import {
|
||||
addSidebarPanel,
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { isEmpty } from "@ember/utils";
|
||||
import PreloadStore from "discourse/lib/preload-store";
|
||||
import { ADMIN_NAV_MAP } from "discourse/lib/sidebar/admin-nav-map";
|
||||
import {
|
||||
addSidebarPanel,
|
||||
addSidebarSection,
|
||||
} from "discourse/lib/sidebar/custom-sections";
|
||||
import { ADMIN_PANEL } from "discourse/services/sidebar-state";
|
||||
import BaseCustomSidebarPanel from "discourse/lib/sidebar/base-custom-sidebar-panel";
|
||||
import BaseCustomSidebarSection from "discourse/lib/sidebar/base-custom-sidebar-section";
|
||||
import BaseCustomSidebarSectionLink from "discourse/lib/sidebar/base-custom-sidebar-section-link";
|
||||
import { ADMIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
import { getOwnerWithFallback } from "discourse-common/lib/get-owner";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
let additionalAdminSidebarSectionLinks = {};
|
||||
|
@ -14,60 +15,52 @@ export function clearAdditionalAdminSidebarSectionLinks() {
|
|||
additionalAdminSidebarSectionLinks = {};
|
||||
}
|
||||
|
||||
function defineAdminSectionLink(BaseCustomSidebarSectionLink) {
|
||||
const SidebarAdminSectionLink = class extends BaseCustomSidebarSectionLink {
|
||||
constructor({ adminSidebarNavLink }) {
|
||||
super(...arguments);
|
||||
this.adminSidebarNavLink = adminSidebarNavLink;
|
||||
}
|
||||
class SidebarAdminSectionLink extends BaseCustomSidebarSectionLink {
|
||||
constructor({ adminSidebarNavLink }) {
|
||||
super(...arguments);
|
||||
this.adminSidebarNavLink = adminSidebarNavLink;
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.adminSidebarNavLink.name;
|
||||
}
|
||||
get name() {
|
||||
return this.adminSidebarNavLink.name;
|
||||
}
|
||||
|
||||
get classNames() {
|
||||
return "admin-sidebar-nav-link";
|
||||
}
|
||||
get classNames() {
|
||||
return "admin-sidebar-nav-link";
|
||||
}
|
||||
|
||||
get route() {
|
||||
return this.adminSidebarNavLink.route;
|
||||
}
|
||||
get route() {
|
||||
return this.adminSidebarNavLink.route;
|
||||
}
|
||||
|
||||
get href() {
|
||||
return this.adminSidebarNavLink.href;
|
||||
}
|
||||
get href() {
|
||||
return this.adminSidebarNavLink.href;
|
||||
}
|
||||
|
||||
get models() {
|
||||
return this.adminSidebarNavLink.routeModels;
|
||||
}
|
||||
get models() {
|
||||
return this.adminSidebarNavLink.routeModels;
|
||||
}
|
||||
|
||||
get text() {
|
||||
return this.adminSidebarNavLink.label
|
||||
? I18n.t(this.adminSidebarNavLink.label)
|
||||
: this.adminSidebarNavLink.text;
|
||||
}
|
||||
get text() {
|
||||
return this.adminSidebarNavLink.label
|
||||
? I18n.t(this.adminSidebarNavLink.label)
|
||||
: this.adminSidebarNavLink.text;
|
||||
}
|
||||
|
||||
get prefixType() {
|
||||
return "icon";
|
||||
}
|
||||
get prefixType() {
|
||||
return "icon";
|
||||
}
|
||||
|
||||
get prefixValue() {
|
||||
return this.adminSidebarNavLink.icon;
|
||||
}
|
||||
get prefixValue() {
|
||||
return this.adminSidebarNavLink.icon;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return this.adminSidebarNavLink.text;
|
||||
}
|
||||
};
|
||||
|
||||
return SidebarAdminSectionLink;
|
||||
get title() {
|
||||
return this.adminSidebarNavLink.text;
|
||||
}
|
||||
}
|
||||
|
||||
function defineAdminSection(
|
||||
adminNavSectionData,
|
||||
BaseCustomSidebarSection,
|
||||
adminSectionLinkClass
|
||||
) {
|
||||
function defineAdminSection(adminNavSectionData) {
|
||||
const AdminNavSection = class extends BaseCustomSidebarSection {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
@ -96,7 +89,7 @@ function defineAdminSection(
|
|||
get links() {
|
||||
return this.sectionLinks.map(
|
||||
(sectionLinkData) =>
|
||||
new adminSectionLinkClass({ adminSidebarNavLink: sectionLinkData })
|
||||
new SidebarAdminSectionLink({ adminSidebarNavLink: sectionLinkData })
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -163,27 +156,6 @@ export function useAdminNavConfig(navMap) {
|
|||
return navMap;
|
||||
}
|
||||
|
||||
let adminSectionLinkClass = null;
|
||||
export function buildAdminSidebar(navConfig) {
|
||||
navConfig.forEach((adminNavSectionData) => {
|
||||
addSidebarSection(
|
||||
(BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
|
||||
// We only want to define the link class once even though we have many different sections.
|
||||
adminSectionLinkClass =
|
||||
adminSectionLinkClass ||
|
||||
defineAdminSectionLink(BaseCustomSidebarSectionLink);
|
||||
|
||||
return defineAdminSection(
|
||||
adminNavSectionData,
|
||||
BaseCustomSidebarSection,
|
||||
adminSectionLinkClass
|
||||
);
|
||||
},
|
||||
ADMIN_PANEL
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// This is used for a plugin API.
|
||||
export function addAdminSidebarSectionLink(sectionName, link) {
|
||||
if (!additionalAdminSidebarSectionLinks.hasOwnProperty(sectionName)) {
|
||||
|
@ -237,41 +209,26 @@ function pluginAdminRouteLinks() {
|
|||
);
|
||||
}
|
||||
|
||||
export default {
|
||||
name: "admin-sidebar-initializer",
|
||||
export default class AdminSidebarPanel extends BaseCustomSidebarPanel {
|
||||
key = ADMIN_PANEL;
|
||||
hidden = true;
|
||||
|
||||
initialize(owner) {
|
||||
this.currentUser = owner.lookup("service:current-user");
|
||||
this.siteSettings = owner.lookup("service:site-settings");
|
||||
|
||||
if (
|
||||
!this.currentUser?.staff ||
|
||||
!this.siteSettings.userInAnyGroups(
|
||||
"admin_sidebar_enabled_groups",
|
||||
this.currentUser
|
||||
)
|
||||
) {
|
||||
return;
|
||||
get sections() {
|
||||
const siteSettings = getOwnerWithFallback().lookup("service:site-settings");
|
||||
if (isEmpty(siteSettings.admin_sidebar_enabled_groups)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
this.adminSidebarExperimentStateManager = owner.lookup(
|
||||
this.adminSidebarExperimentStateManager = getOwnerWithFallback(this).lookup(
|
||||
"service:admin-sidebar-experiment-state-manager"
|
||||
);
|
||||
|
||||
addSidebarPanel(
|
||||
(BaseCustomSidebarPanel) =>
|
||||
class AdminSidebarPanel extends BaseCustomSidebarPanel {
|
||||
key = ADMIN_PANEL;
|
||||
hidden = true;
|
||||
}
|
||||
);
|
||||
|
||||
const savedConfig = this.adminSidebarExperimentStateManager.navConfig;
|
||||
const navMap = savedConfig || ADMIN_NAV_MAP;
|
||||
|
||||
navMap.findBy("name", "plugins").links.push(...pluginAdminRouteLinks());
|
||||
|
||||
if (this.siteSettings.experimental_form_templates) {
|
||||
if (siteSettings.experimental_form_templates) {
|
||||
navMap.findBy("name", "customize").links.push({
|
||||
name: "admin_customize_form_templates",
|
||||
route: "adminCustomizeFormTemplates",
|
||||
|
@ -280,6 +237,10 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
buildAdminSidebar(useAdminNavConfig(navMap), adminSectionLinkClass);
|
||||
},
|
||||
};
|
||||
const navConfig = useAdminNavConfig(navMap);
|
||||
|
||||
return navConfig.map((adminNavSectionData) => {
|
||||
return defineAdminSection(adminNavSectionData);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import BaseCustomSidebarPanel from "discourse/lib/sidebar/base-custom-sidebar-panel";
|
||||
import BaseCustomSidebarSection from "discourse/lib/sidebar/base-custom-sidebar-section";
|
||||
import BaseCustomSidebarSectionLink from "discourse/lib/sidebar/base-custom-sidebar-section-link";
|
||||
import { MAIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
import I18n from "discourse-i18n";
|
||||
import AdminSidebarPanel from "./admin-sidebar";
|
||||
|
||||
class MainSidebarPanel {
|
||||
sections = [];
|
||||
|
@ -23,9 +25,9 @@ class MainSidebarPanel {
|
|||
}
|
||||
}
|
||||
|
||||
export let customPanels = [new MainSidebarPanel()];
|
||||
|
||||
export let currentPanelKey = "main";
|
||||
export let customPanels;
|
||||
export let currentPanelKey;
|
||||
resetSidebarPanels();
|
||||
|
||||
export function addSidebarPanel(func) {
|
||||
const panelClass = func.call(this, BaseCustomSidebarPanel);
|
||||
|
@ -60,6 +62,6 @@ export function resetPanelSections(
|
|||
}
|
||||
|
||||
export function resetSidebarPanels() {
|
||||
customPanels = [new MainSidebarPanel()];
|
||||
currentPanelKey = "main";
|
||||
customPanels = [new MainSidebarPanel(), new AdminSidebarPanel()];
|
||||
currentPanelKey = MAIN_PANEL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export const COMBINED_MODE = "combined";
|
||||
export const SEPARATED_MODE = "separated";
|
||||
export const MAIN_PANEL = "main";
|
||||
export const ADMIN_PANEL = "admin";
|
|
@ -5,11 +5,11 @@ import {
|
|||
currentPanelKey,
|
||||
customPanels as panels,
|
||||
} from "discourse/lib/sidebar/custom-sections";
|
||||
|
||||
const COMBINED_MODE = "combined";
|
||||
const SEPARATED_MODE = "separated";
|
||||
export const MAIN_PANEL = "main";
|
||||
export const ADMIN_PANEL = "admin";
|
||||
import {
|
||||
COMBINED_MODE,
|
||||
MAIN_PANEL,
|
||||
SEPARATED_MODE,
|
||||
} from "discourse/lib/sidebar/panels";
|
||||
|
||||
@disableImplicitInjections
|
||||
export default class SidebarState extends Service {
|
||||
|
|
|
@ -28,7 +28,6 @@ import { resetUserMenuProfileTabItems } from "discourse/components/user-menu/pro
|
|||
import { resetCustomPostMessageCallbacks } from "discourse/controllers/topic";
|
||||
import { clearHTMLCache } from "discourse/helpers/custom-html";
|
||||
import { resetUsernameDecorators } from "discourse/helpers/decorate-username-selector";
|
||||
import { clearAdditionalAdminSidebarSectionLinks } from "discourse/instance-initializers/admin-sidebar";
|
||||
import { resetBeforeAuthCompleteCallbacks } from "discourse/instance-initializers/auth-complete";
|
||||
import { clearPopupMenuOptions } from "discourse/lib/composer/custom-popup-menu-options";
|
||||
import { clearDesktopNotificationHandlers } from "discourse/lib/desktop-notifications";
|
||||
|
@ -50,6 +49,7 @@ import PreloadStore from "discourse/lib/preload-store";
|
|||
import { clearTopicFooterButtons } from "discourse/lib/register-topic-footer-button";
|
||||
import { clearTopicFooterDropdowns } from "discourse/lib/register-topic-footer-dropdown";
|
||||
import { clearTagsHtmlCallbacks } from "discourse/lib/render-tags";
|
||||
import { clearAdditionalAdminSidebarSectionLinks } from "discourse/lib/sidebar/admin-sidebar";
|
||||
import { resetDefaultSectionLinks as resetTopicsSectionLinks } from "discourse/lib/sidebar/custom-community-section-links";
|
||||
import { resetSidebarPanels } from "discourse/lib/sidebar/custom-sections";
|
||||
import {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/services/sidebar-state";
|
||||
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
|
||||
|
||||
export const CHAT_PANEL = "chat";
|
||||
|
|
|
@ -2,9 +2,9 @@ import { tracked } from "@glimmer/tracking";
|
|||
import Service, { inject as service } from "@ember/service";
|
||||
import KeyValueStore from "discourse/lib/key-value-store";
|
||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||
import { MAIN_PANEL } from "discourse/lib/sidebar/panels";
|
||||
import { defaultHomepage } from "discourse/lib/utilities";
|
||||
import Site from "discourse/models/site";
|
||||
import { MAIN_PANEL } from "discourse/services/sidebar-state";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { getUserChatSeparateSidebarMode } from "discourse/plugins/chat/discourse/lib/get-user-chat-separate-sidebar-mode";
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user