discourse/app/assets/javascripts/admin/addon/services/admin-sidebar-state-manager.js
Martin Brennan d8c855e559
DEV: Introduce AdminNavManager service for admin sidebar and search links (#33357)
Followup d92de3e4d0

We have an ADMIN_NAV_MAP const that was being used in the admin sidebar
and the admin search to generate a list of links that the admin can
see and navigate to.

However, we were modifying this const, which led to inconsistent
behaviour between the admin sidebar and admin search, leading to
flaky tests.

This commit moves the access control of ADMIN_NAV_MAP into a new
service, and introduces a more structured way of adding/changing
links in the nav map that the sidebar and search can use directly.

This commit also removes old unused code from the admin sidebar
state manager used to store a custom admin nav map in localstorage.
2025-06-30 11:02:21 +10:00

71 lines
1.8 KiB
JavaScript
Vendored

import Service, { service } from "@ember/service";
import scrollLock from "discourse/lib/scroll-lock";
import { ADMIN_PANEL, MAIN_PANEL } from "discourse/lib/sidebar/panels";
import AdminSearchModal from "admin/components/modal/admin-search";
export default class AdminSidebarStateManager extends Service {
@service sidebarState;
@service header;
keywords = {};
setLinkKeywords(link_name, keywords) {
if (!this.keywords[link_name]) {
this.keywords[link_name] = {
navigation: keywords.map((keyword) => keyword.toLowerCase()),
};
return;
}
this.keywords[link_name].navigation = [
...new Set(
this.keywords[link_name].navigation.concat(
keywords.map((keyword) => keyword.toLowerCase())
)
),
];
}
maybeForceAdminSidebar(opts = {}) {
opts.onlyIfAlreadyActive ??= true;
const isAdminSidebarActive =
this.sidebarState.currentPanel?.key === ADMIN_PANEL;
if (!opts.onlyIfAlreadyActive) {
return this.#forceAdminSidebar();
}
if (isAdminSidebarActive) {
return this.#forceAdminSidebar();
} else {
this.sidebarState.isForcingSidebar = false;
return false;
}
}
stopForcingAdminSidebar() {
this.sidebarState.setPanel(MAIN_PANEL);
this.sidebarState.isForcingSidebar = false;
}
get modals() {
return { adminSearch: AdminSearchModal };
}
#forceAdminSidebar() {
this.sidebarState.setPanel(ADMIN_PANEL);
this.sidebarState.setSeparatedMode();
this.sidebarState.hideSwitchPanelButtons();
this.sidebarState.isForcingSidebar = true;
// we may navigate to admin from the header dropdown
// and when we do, we have to close it
if (this.sidebarState.sidebarHidden) {
this.header.hamburgerVisible = false;
scrollLock(false);
}
return true;
}
}