mirror of
https://github.com/discourse/discourse.git
synced 2025-03-06 11:19:51 +00:00
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 de54bdd73d2c501cb22902d638a14cddd2c15520 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 GroupsSectionLink from "discourse/lib/sidebar/community-section/groups-section-link";
|
||||||
import UsersSectionLink from "discourse/lib/sidebar/community-section/users-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 { action } from "@ember/object";
|
||||||
import { next } from "@ember/runloop";
|
import { next } from "@ember/runloop";
|
||||||
|
|
||||||
@ -21,12 +22,15 @@ const MAIN_SECTION_LINKS = [
|
|||||||
const MORE_SECTION_LINKS = [GroupsSectionLink, UsersSectionLink];
|
const MORE_SECTION_LINKS = [GroupsSectionLink, UsersSectionLink];
|
||||||
|
|
||||||
export default class SidebarCommunitySection extends GlimmerComponent {
|
export default class SidebarCommunitySection extends GlimmerComponent {
|
||||||
|
@service router;
|
||||||
|
|
||||||
moreSectionLinks = [...MORE_SECTION_LINKS, ...customSectionLinks].map(
|
moreSectionLinks = [...MORE_SECTION_LINKS, ...customSectionLinks].map(
|
||||||
(sectionLinkClass) => {
|
(sectionLinkClass) => {
|
||||||
return new sectionLinkClass({
|
return new sectionLinkClass({
|
||||||
topicTrackingState: this.topicTrackingState,
|
topicTrackingState: this.topicTrackingState,
|
||||||
currentUser: this.currentUser,
|
currentUser: this.currentUser,
|
||||||
appEvents: this.appEvents,
|
appEvents: this.appEvents,
|
||||||
|
router: this.router,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -10,9 +10,11 @@ export default class SectionLink extends GlimmerComponent {
|
|||||||
|
|
||||||
get prefixCSS() {
|
get prefixCSS() {
|
||||||
const color = this.args.prefixColor;
|
const color = this.args.prefixColor;
|
||||||
|
|
||||||
if (!color || !color.match(/^\w{6}$/)) {
|
if (!color || !color.match(/^\w{6}$/)) {
|
||||||
return htmlSafe("");
|
return htmlSafe("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return htmlSafe("color: #" + color);
|
return htmlSafe("color: #" + color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,7 @@ import { downloadCalendar } from "discourse/lib/download-calendar";
|
|||||||
import { consolePrefix } from "discourse/lib/source-identifier";
|
import { consolePrefix } from "discourse/lib/source-identifier";
|
||||||
import { addSectionLink } from "discourse/lib/sidebar/custom-community-section-links";
|
import { addSectionLink } from "discourse/lib/sidebar/custom-community-section-links";
|
||||||
import { addSidebarSection } from "discourse/lib/sidebar/custom-sections";
|
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
|
// 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
|
// based on Semantic Versioning 2.0.0. Please update the changelog at
|
||||||
@ -484,15 +485,27 @@ class PluginApi {
|
|||||||
|
|
||||||
if (siteSettings.enable_experimental_sidebar_hamburger) {
|
if (siteSettings.enable_experimental_sidebar_hamburger) {
|
||||||
try {
|
try {
|
||||||
const { route, label, rawLabel, className } = fn();
|
const { href, route, label, rawLabel, className } = fn();
|
||||||
const textContent = rawLabel || I18n.t(label);
|
const textContent = rawLabel || I18n.t(label);
|
||||||
|
|
||||||
this.addCommunitySectionLink({
|
const args = {
|
||||||
name: className || textContent.replace(/\s+/g, "-").toLowerCase(),
|
name: className || textContent.replace(/\s+/g, "-").toLowerCase(),
|
||||||
route,
|
|
||||||
title: textContent,
|
title: textContent,
|
||||||
text: 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 {
|
} catch {
|
||||||
deprecated(
|
deprecated(
|
||||||
`Usage of \`api.decorateWidget('hamburger-menu:generalLinks')\` is incompatible with the \`enable_experimental_sidebar_hamburger\` site setting. Please use \`api.addCommunitySectionLink\` instead.`
|
`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 {(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.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.title - The title attribute for the link.
|
||||||
* @param {string} arg.text - The text to display 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.
|
* Base class representing a sidebar topics section link interface.
|
||||||
*/
|
*/
|
||||||
export default class BaseSectionLink {
|
export default class BaseSectionLink {
|
||||||
constructor({ topicTrackingState, currentUser, appEvents } = {}) {
|
constructor({ topicTrackingState, currentUser, appEvents, router } = {}) {
|
||||||
|
this.router = router;
|
||||||
this.topicTrackingState = topicTrackingState;
|
this.topicTrackingState = topicTrackingState;
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.appEvents = appEvents;
|
this.appEvents = appEvents;
|
||||||
@ -32,6 +33,11 @@ export default class BaseSectionLink {
|
|||||||
*/
|
*/
|
||||||
get model() {}
|
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
|
* @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";
|
import BaseSectionLink from "discourse/lib/sidebar/community-section/base-section-link";
|
||||||
|
|
||||||
export let customSectionLinks = [];
|
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
|
* Appends an additional section link under the topics section
|
||||||
@ -8,31 +44,56 @@ export let customSectionLinks = [];
|
|||||||
* @param {BaseSectionLink} baseSectionLink Factory class to inherit from.
|
* @param {BaseSectionLink} baseSectionLink Factory class to inherit from.
|
||||||
* @returns {BaseSectionLink} A class that extends BaseSectionLink.
|
* @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.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.title - The title 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} arg.text - The text to display for the link.
|
||||||
*/
|
*/
|
||||||
export function addSectionLink(arg) {
|
export function addSectionLink(args) {
|
||||||
if (typeof arg === "function") {
|
if (typeof args === "function") {
|
||||||
customSectionLinks.push(arg.call(this, BaseSectionLink));
|
customSectionLinks.push(args.call(this, BaseSectionLink));
|
||||||
} else {
|
} else {
|
||||||
const klass = class extends BaseSectionLink {
|
const klass = class extends BaseSectionLink {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
|
||||||
|
if (args.href) {
|
||||||
|
this.routeInfoHelper = new RouteInfoHelper(this.router, args.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return arg.name;
|
return args.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
get route() {
|
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() {
|
get text() {
|
||||||
return arg.text;
|
return args.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return arg.title;
|
return args.title;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@
|
|||||||
@content={{sectionLink.text}}
|
@content={{sectionLink.text}}
|
||||||
@currentWhen={{sectionLink.currentWhen}}
|
@currentWhen={{sectionLink.currentWhen}}
|
||||||
@badgeText={{sectionLink.badgeText}}
|
@badgeText={{sectionLink.badgeText}}
|
||||||
@model={{sectionLink.model}} />
|
@model={{sectionLink.model}}
|
||||||
|
@models={{sectionLink.models}} />
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
<Sidebar::MoreSectionLinks @sectionLinks={{this.moreSectionLinks}} />
|
<Sidebar::MoreSectionLinks @sectionLinks={{this.moreSectionLinks}} />
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
@content={{this.activeSectionLink.text}}
|
@content={{this.activeSectionLink.text}}
|
||||||
@currentWhen={{this.activeSectionLink.currentWhen}}
|
@currentWhen={{this.activeSectionLink.currentWhen}}
|
||||||
@badgeText={{this.activeSectionLink.badgeText}}
|
@badgeText={{this.activeSectionLink.badgeText}}
|
||||||
@model={{this.activeSectionLink.model}} />
|
@model={{this.activeSectionLink.model}}
|
||||||
|
@models={{this.activeSectionLink.models}} />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<details class="sidebar-more-section-links-details" {{on "toggle" this.toggleSectionLinks}}>
|
<details class="sidebar-more-section-links-details" {{on "toggle" this.toggleSectionLinks}}>
|
||||||
@ -29,7 +30,8 @@
|
|||||||
@content={{sectionLink.text}}
|
@content={{sectionLink.text}}
|
||||||
@currentWhen={{sectionLink.currentWhen}}
|
@currentWhen={{sectionLink.currentWhen}}
|
||||||
@badgeText={{sectionLink.badgeText}}
|
@badgeText={{sectionLink.badgeText}}
|
||||||
@model={{sectionLink.model}} />
|
@model={{sectionLink.model}}
|
||||||
|
@models={{sectionLink.models}} />
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
@ -444,6 +444,13 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||||||
className: "my-custom-top",
|
className: "my-custom-top",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
api.decorateWidget("hamburger-menu:generalLinks", () => {
|
||||||
|
return {
|
||||||
|
href: "/c/bug?status=open",
|
||||||
|
rawLabel: "open bugs",
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await visit("/");
|
await visit("/");
|
||||||
@ -457,6 +464,11 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||||||
"adds custom latest section link to community section"
|
"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(
|
assert.strictEqual(
|
||||||
customlatestSectionLink.textContent.trim(),
|
customlatestSectionLink.textContent.trim(),
|
||||||
I18n.t("filters.latest.title"),
|
I18n.t("filters.latest.title"),
|
||||||
@ -476,6 +488,11 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||||||
"adds custom unread section link to community section"
|
"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(
|
assert.strictEqual(
|
||||||
customUnreadSectionLink.textContent.trim(),
|
customUnreadSectionLink.textContent.trim(),
|
||||||
"my unreads",
|
"my unreads",
|
||||||
@ -490,5 +507,19 @@ acceptance("Sidebar - Plugin API", function (needs) {
|
|||||||
customTopSectionLInk,
|
customTopSectionLInk,
|
||||||
"adds custom top section link to community section with right link class"
|
"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…
x
Reference in New Issue
Block a user