DEV: Supports href attribute for hamburger links API bridge to sidebar (#17750)
In the old `decorateWidget("hamburger-menu:generalLinks", callbackFn)`
API, the return value of the callback function can either return a
`route` or `href`. The API bridge added in
de54bdd73d
supported `route` but not `href` and
hence the need for this commit.
This commit is contained in:
parent
b9c1e63bd1
commit
df264e49a9
|
@ -9,6 +9,7 @@ import MyPostsSectionLink from "discourse/lib/sidebar/community-section/my-posts
|
|||
import GroupsSectionLink from "discourse/lib/sidebar/community-section/groups-section-link";
|
||||
import UsersSectionLink from "discourse/lib/sidebar/community-section/users-section-link";
|
||||
|
||||
import { inject as service } from "@ember/service";
|
||||
import { action } from "@ember/object";
|
||||
import { next } from "@ember/runloop";
|
||||
|
||||
|
@ -21,12 +22,15 @@ const MAIN_SECTION_LINKS = [
|
|||
const MORE_SECTION_LINKS = [GroupsSectionLink, UsersSectionLink];
|
||||
|
||||
export default class SidebarCommunitySection extends GlimmerComponent {
|
||||
@service router;
|
||||
|
||||
moreSectionLinks = [...MORE_SECTION_LINKS, ...customSectionLinks].map(
|
||||
(sectionLinkClass) => {
|
||||
return new sectionLinkClass({
|
||||
topicTrackingState: this.topicTrackingState,
|
||||
currentUser: this.currentUser,
|
||||
appEvents: this.appEvents,
|
||||
router: this.router,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -10,9 +10,11 @@ export default class SectionLink extends GlimmerComponent {
|
|||
|
||||
get prefixCSS() {
|
||||
const color = this.args.prefixColor;
|
||||
|
||||
if (!color || !color.match(/^\w{6}$/)) {
|
||||
return htmlSafe("");
|
||||
}
|
||||
|
||||
return htmlSafe("color: #" + color);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ 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 { addSidebarSection } from "discourse/lib/sidebar/custom-sections";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
|
||||
// If you add any methods to the API ensure you bump up the version number
|
||||
// based on Semantic Versioning 2.0.0. Please update the changelog at
|
||||
|
@ -484,15 +485,27 @@ class PluginApi {
|
|||
|
||||
if (siteSettings.enable_experimental_sidebar_hamburger) {
|
||||
try {
|
||||
const { route, label, rawLabel, className } = fn();
|
||||
const { href, route, label, rawLabel, className } = fn();
|
||||
const textContent = rawLabel || I18n.t(label);
|
||||
|
||||
this.addCommunitySectionLink({
|
||||
const args = {
|
||||
name: className || textContent.replace(/\s+/g, "-").toLowerCase(),
|
||||
route,
|
||||
title: textContent,
|
||||
text: textContent,
|
||||
});
|
||||
};
|
||||
|
||||
if (href) {
|
||||
if (DiscourseURL.isInternal(href)) {
|
||||
args.href = href;
|
||||
} else {
|
||||
// Skip external links support for now
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
args.route = route;
|
||||
}
|
||||
|
||||
this.addCommunitySectionLink(args);
|
||||
} catch {
|
||||
deprecated(
|
||||
`Usage of \`api.decorateWidget('hamburger-menu:generalLinks')\` is incompatible with the \`enable_experimental_sidebar_hamburger\` site setting. Please use \`api.addCommunitySectionLink\` instead.`
|
||||
|
@ -1699,7 +1712,8 @@ class PluginApi {
|
|||
*
|
||||
* @param {(addCommunitySectionLinkCallback|Object)} arg - 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 of the link.
|
||||
* @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.
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* Base class representing a sidebar topics section link interface.
|
||||
*/
|
||||
export default class BaseSectionLink {
|
||||
constructor({ topicTrackingState, currentUser, appEvents } = {}) {
|
||||
constructor({ topicTrackingState, currentUser, appEvents, router } = {}) {
|
||||
this.router = router;
|
||||
this.topicTrackingState = topicTrackingState;
|
||||
this.currentUser = currentUser;
|
||||
this.appEvents = appEvents;
|
||||
|
@ -32,6 +33,11 @@ export default class BaseSectionLink {
|
|||
*/
|
||||
get model() {}
|
||||
|
||||
/**
|
||||
* @returns {Object} Models for <LinkTo> component. See https://api.emberjs.com/ember/release/classes/Ember.Templates.components/methods/LinkTo?anchor=LinkTo
|
||||
*/
|
||||
get models() {}
|
||||
|
||||
/**
|
||||
* @returns {Object} Query parameters for <LinkTo> component. See https://api.emberjs.com/ember/release/classes/Ember.Templates.components/methods/LinkTo?anchor=LinkTo
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,42 @@
|
|||
import BaseSectionLink from "discourse/lib/sidebar/community-section/base-section-link";
|
||||
|
||||
export let customSectionLinks = [];
|
||||
class RouteInfoHelper {
|
||||
constructor(router, url) {
|
||||
this.routeInfo = router.recognize(url);
|
||||
}
|
||||
|
||||
get route() {
|
||||
return this.routeInfo.name;
|
||||
}
|
||||
|
||||
get models() {
|
||||
return this.#getParameters;
|
||||
}
|
||||
|
||||
get query() {
|
||||
return this.routeInfo.queryParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracted from https://github.com/emberjs/rfcs/issues/658
|
||||
* Retrieves all parameters for a `RouteInfo` object and its parents in
|
||||
* correct oder, so that you can pass them to e.g.
|
||||
* `transitionTo(routeName, ...params)`.
|
||||
*/
|
||||
get #getParameters() {
|
||||
let allParameters = [];
|
||||
let current = this.routeInfo;
|
||||
|
||||
do {
|
||||
const { params, paramNames } = current;
|
||||
const currentParameters = paramNames.map((n) => params[n]);
|
||||
allParameters = [...currentParameters, ...allParameters];
|
||||
} while ((current = current.parent));
|
||||
|
||||
return allParameters;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an additional section link under the topics section
|
||||
|
@ -8,31 +44,56 @@ export let customSectionLinks = [];
|
|||
* @param {BaseSectionLink} baseSectionLink Factory class to inherit from.
|
||||
* @returns {BaseSectionLink} A class that extends BaseSectionLink.
|
||||
*
|
||||
* @param {(addSectionLinkCallback|Object)} arg - A callback function or an Object.
|
||||
* @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 of the link.
|
||||
* @param {string} arg.title - The title attribute for the link.
|
||||
* @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.
|
||||
*/
|
||||
export function addSectionLink(arg) {
|
||||
if (typeof arg === "function") {
|
||||
customSectionLinks.push(arg.call(this, BaseSectionLink));
|
||||
export function addSectionLink(args) {
|
||||
if (typeof args === "function") {
|
||||
customSectionLinks.push(args.call(this, BaseSectionLink));
|
||||
} else {
|
||||
const klass = class extends BaseSectionLink {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
if (args.href) {
|
||||
this.routeInfoHelper = new RouteInfoHelper(this.router, args.href);
|
||||
}
|
||||
}
|
||||
|
||||
get name() {
|
||||
return arg.name;
|
||||
return args.name;
|
||||
}
|
||||
|
||||
get route() {
|
||||
return arg.route;
|
||||
if (args.href) {
|
||||
return this.routeInfoHelper.route;
|
||||
} else {
|
||||
return args.route;
|
||||
}
|
||||
}
|
||||
|
||||
get models() {
|
||||
if (args.href) {
|
||||
return this.routeInfoHelper.models;
|
||||
}
|
||||
}
|
||||
|
||||
get query() {
|
||||
if (args.href) {
|
||||
return this.routeInfoHelper.query;
|
||||
}
|
||||
}
|
||||
|
||||
get text() {
|
||||
return arg.text;
|
||||
return args.text;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return arg.title;
|
||||
return args.title;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
@content={{sectionLink.text}}
|
||||
@currentWhen={{sectionLink.currentWhen}}
|
||||
@badgeText={{sectionLink.badgeText}}
|
||||
@model={{sectionLink.model}} />
|
||||
@model={{sectionLink.model}}
|
||||
@models={{sectionLink.models}} />
|
||||
{{/each}}
|
||||
|
||||
<Sidebar::MoreSectionLinks @sectionLinks={{this.moreSectionLinks}} />
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
@content={{this.activeSectionLink.text}}
|
||||
@currentWhen={{this.activeSectionLink.currentWhen}}
|
||||
@badgeText={{this.activeSectionLink.badgeText}}
|
||||
@model={{this.activeSectionLink.model}} />
|
||||
@model={{this.activeSectionLink.model}}
|
||||
@models={{this.activeSectionLink.models}} />
|
||||
{{/if}}
|
||||
|
||||
<details class="sidebar-more-section-links-details" {{on "toggle" this.toggleSectionLinks}}>
|
||||
|
@ -29,7 +30,8 @@
|
|||
@content={{sectionLink.text}}
|
||||
@currentWhen={{sectionLink.currentWhen}}
|
||||
@badgeText={{sectionLink.badgeText}}
|
||||
@model={{sectionLink.model}} />
|
||||
@model={{sectionLink.model}}
|
||||
@models={{sectionLink.models}} />
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -444,6 +444,13 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||
className: "my-custom-top",
|
||||
};
|
||||
});
|
||||
|
||||
api.decorateWidget("hamburger-menu:generalLinks", () => {
|
||||
return {
|
||||
href: "/c/bug?status=open",
|
||||
rawLabel: "open bugs",
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
await visit("/");
|
||||
|
@ -457,6 +464,11 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||
"adds custom latest section link to community section"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
customlatestSectionLink.href.endsWith("/latest"),
|
||||
"sets the right href attribute for the custom latest section link"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
customlatestSectionLink.textContent.trim(),
|
||||
I18n.t("filters.latest.title"),
|
||||
|
@ -476,6 +488,11 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||
"adds custom unread section link to community section"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
customUnreadSectionLink.href.endsWith("/unread"),
|
||||
"sets the right href attribute for the custom unread section link"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
customUnreadSectionLink.textContent.trim(),
|
||||
"my unreads",
|
||||
|
@ -490,5 +507,19 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||
customTopSectionLInk,
|
||||
"adds custom top section link to community section with right link class"
|
||||
);
|
||||
|
||||
const openBugsSectionLink = query(
|
||||
".sidebar-section-community .sidebar-section-link-open-bugs"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
openBugsSectionLink,
|
||||
"adds custom open bugs section link to community section with right link class"
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
openBugsSectionLink.href.endsWith("/c/bug?status=open"),
|
||||
"sets the right href attribute for the custom open bugs section link"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue