From 02987e05d5eaf3fb5e33734d7517c87f35c48793 Mon Sep 17 00:00:00 2001 From: Alan Guo Xiang Tan Date: Thu, 4 Aug 2022 15:05:14 +0800 Subject: [PATCH] DEV: Support old hamburger menu custom footer links in Sidebar (#17796) This commit extends the existing API bridge for supporting custom general links in the old hamburger menu in Sidebar to support custom footer links. Custom footer links can be added to the old hamburger menu via the `api.decorateWidget("hamburger-menu:footerLinks")` API. Footer links are added into the secondary section of the "More..." links drawer in the Community section of the sidebar. --- .../components/sidebar/community-section.js | 16 +++++--- .../discourse/app/lib/plugin-api.js | 27 ++++++++----- .../sidebar/custom-community-section-links.js | 25 +++++++----- .../acceptance/sidebar-plugin-api-test.js | 40 ++++++++++++++++++- 4 files changed, 82 insertions(+), 26 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/sidebar/community-section.js b/app/assets/javascripts/discourse/app/components/sidebar/community-section.js index ff6b9626b8e..e704cfe18da 100644 --- a/app/assets/javascripts/discourse/app/components/sidebar/community-section.js +++ b/app/assets/javascripts/discourse/app/components/sidebar/community-section.js @@ -2,7 +2,10 @@ import GlimmerComponent from "discourse/components/glimmer"; import Composer from "discourse/models/composer"; import { getOwner } from "discourse-common/lib/get-owner"; import PermissionType from "discourse/models/permission-type"; -import { customSectionLinks } from "discourse/lib/sidebar/custom-community-section-links"; +import { + customSectionLinks, + secondaryCustomSectionLinks, +} from "discourse/lib/sidebar/custom-community-section-links"; import EverythingSectionLink from "discourse/lib/sidebar/community-section/everything-section-link"; import TrackedSectionLink from "discourse/lib/sidebar/community-section/tracked-section-link"; import MyPostsSectionLink from "discourse/lib/sidebar/community-section/my-posts-section-link"; @@ -36,11 +39,12 @@ export default class SidebarCommunitySection extends GlimmerComponent { } ); - moreSecondarySectionLinks = MORE_SECONDARY_SECTION_LINKS.map( - (sectionLinkClass) => { - return this.#initializeSectionLink(sectionLinkClass); - } - ); + moreSecondarySectionLinks = [ + ...MORE_SECONDARY_SECTION_LINKS, + ...secondaryCustomSectionLinks, + ].map((sectionLinkClass) => { + return this.#initializeSectionLink(sectionLinkClass); + }); #mainSectionLinks = this.currentUser.staff ? [...MAIN_SECTION_LINKS, ...ADMIN_MAIN_SECTION_LINKS] diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index 9c4bd3ccf38..84eb5dbe7fd 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js @@ -95,7 +95,7 @@ import { import { CUSTOM_USER_SEARCH_OPTIONS } from "select-kit/components/user-chooser"; import { downloadCalendar } from "discourse/lib/download-calendar"; import { consolePrefix } from "discourse/lib/source-identifier"; -import { addSectionLink } from "discourse/lib/sidebar/custom-community-section-links"; +import { addSectionLink as addCustomCommunitySectionLink } from "discourse/lib/sidebar/custom-community-section-links"; import { addSidebarSection } from "discourse/lib/sidebar/custom-sections"; import DiscourseURL from "discourse/lib/url"; @@ -480,7 +480,15 @@ class PluginApi { * **/ decorateWidget(name, fn) { - if (name === "hamburger-menu:generalLinks") { + this._deprecateDecoratingHamburgerWidgetLinks(name, fn); + decorateWidget(name, fn); + } + + _deprecateDecoratingHamburgerWidgetLinks(name, fn) { + if ( + name === "hamburger-menu:generalLinks" || + name === "hamburger-menu:footerLinks" + ) { const siteSettings = this.container.lookup("site-settings:main"); if (siteSettings.enable_experimental_sidebar_hamburger) { @@ -505,7 +513,7 @@ class PluginApi { args.route = route; } - this.addCommunitySectionLink(args); + this.addCommunitySectionLink(args, name.match(/footerLinks/)); } catch { deprecated( `Usage of \`api.decorateWidget('hamburger-menu:generalLinks')\` is incompatible with the \`enable_experimental_sidebar_hamburger\` site setting. Please use \`api.addCommunitySectionLink\` instead.` @@ -515,8 +523,6 @@ class PluginApi { return; } } - - decorateWidget(name, fn); } /** @@ -1665,9 +1671,9 @@ class PluginApi { /** * EXPERIMENTAL. Do not use. - * Support for adding a navigation link to Sidebar Community section by returning a class which extends from the BaseSectionLink - * class interface. See `lib/sidebar/community-section/base-section-link.js` for documentation on the BaseSectionLink class - * interface. + * Support for adding a navigation link to Sidebar Community section under the "More..." links drawer by returning a + * class which extends from the BaseSectionLink class interface. See `lib/sidebar/community-section/base-section-link.js` + * for documentation on the BaseSectionLink class interface. * * ``` * api.addCommunitySectionLink((baseSectionLink) => { @@ -1716,9 +1722,10 @@ class PluginApi { * @param {string=} arg.href - The href attribute for the link. * @param {string} arg.title - The title attribute for the link. * @param {string} arg.text - The text to display for the link. + * @param {Boolean} [secondary] - Determines whether the section link should be added to the main or secondary section in the "More..." links drawer. */ - addCommunitySectionLink(arg) { - addSectionLink(arg); + addCommunitySectionLink(arg, secondary) { + addCustomCommunitySectionLink(arg, secondary); } /** diff --git a/app/assets/javascripts/discourse/app/lib/sidebar/custom-community-section-links.js b/app/assets/javascripts/discourse/app/lib/sidebar/custom-community-section-links.js index fe09ec2fa6a..301945fb0f5 100644 --- a/app/assets/javascripts/discourse/app/lib/sidebar/custom-community-section-links.js +++ b/app/assets/javascripts/discourse/app/lib/sidebar/custom-community-section-links.js @@ -1,6 +1,8 @@ import BaseSectionLink from "discourse/lib/sidebar/community-section/base-section-link"; export let customSectionLinks = []; +export let secondaryCustomSectionLinks = []; + class RouteInfoHelper { constructor(router, url) { this.routeInfo = router.recognize(url); @@ -39,21 +41,25 @@ class RouteInfoHelper { } /** - * Appends an additional section link under the topics section + * Appends an additional section link to the Community section under the "More..." links drawer. + * * @callback addSectionLinkCallback * @param {BaseSectionLink} baseSectionLink Factory class to inherit from. * @returns {BaseSectionLink} A class that extends BaseSectionLink. * * @param {(addSectionLinkCallback|Object)} args - A callback function or an Object. - * @param {string} arg.name - The name of the link. Needs to be dasherized and lowercase. - * @param {string=} arg.route - The Ember route name to generate the href attribute for the link. - * @param {string=} arg.href - The href attribute for the link. - * @param {string=} arg.title - The title attribute for the link. - * @param {string} arg.text - The text to display for the link. + * @param {string} args.name - The name of the link. Needs to be dasherized and lowercase. + * @param {string=} args.route - The Ember route name to generate the href attribute for the link. + * @param {string=} args.href - The href attribute for the link. + * @param {string=} args.title - The title attribute for the link. + * @param {string} args.text - The text to display for the link. + * @param {Boolean} [secondary] - Determines whether the section link should be added to the main or secondary section in the "More..." links drawer. */ -export function addSectionLink(args) { +export function addSectionLink(args, secondary) { + const links = secondary ? secondaryCustomSectionLinks : customSectionLinks; + if (typeof args === "function") { - customSectionLinks.push(args.call(this, BaseSectionLink)); + links.push(args.call(this, BaseSectionLink)); } else { const klass = class extends BaseSectionLink { constructor() { @@ -97,10 +103,11 @@ export function addSectionLink(args) { } }; - customSectionLinks.push(klass); + links.push(klass); } } export function resetDefaultSectionLinks() { customSectionLinks = []; + secondaryCustomSectionLinks = []; } diff --git a/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js b/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js index 67fd132e2a6..6b094042a73 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/sidebar-plugin-api-test.js @@ -421,7 +421,45 @@ acceptance("Sidebar - Plugin API", function (needs) { ); }); - test("API bridge for decorating hamburger-menu widget with generalLinks", async function (assert) { + test("API bridge for decorating hamburger-menu widget with footer links", async function (assert) { + withPluginApi("1.3.0", (api) => { + api.decorateWidget("hamburger-menu:footerLinks", () => { + return { + route: "discovery.top", + rawLabel: "my top", + className: "my-custom-top", + }; + }); + }); + + await visit("/"); + + await click( + ".sidebar-section-community .sidebar-more-section-links-details-summary" + ); + + const myCustomTopSectionLink = query( + ".sidebar-section-community .sidebar-more-section-links-details-content-secondary .sidebar-section-link-my-custom-top" + ); + + assert.ok( + myCustomTopSectionLink, + "adds my custom top section link to community section under the secondary section in the More... links drawer" + ); + + assert.ok( + myCustomTopSectionLink.href.endsWith("/top"), + "sets the right href attribute for the my custom top section link" + ); + + assert.strictEqual( + myCustomTopSectionLink.textContent.trim(), + "my top", + "displays the right text for my custom top section link" + ); + }); + + test("API bridge for decorating hamburger-menu widget with general links", async function (assert) { withPluginApi("1.3.0", (api) => { api.decorateWidget("hamburger-menu:generalLinks", () => { return {