DEV: allow positioning of nav items and allow selection

Previously we could not place extra nav items in a particular order.

This change introduces a new `before` attribute to addNavigationBarItem
with this attribute we can place a nav item before "top" or any other place.


Additionally this allows navigation items to force active state. In some
cases we may want an items that is simply a "filter" on latest using `?query_params`
when we do that we can "force" the filter active.

A concrete example is the assign plugin that adds a nav item for

Unassigned => `/c/cat-slug/l/latest?assigned=nobody&status=open`

If we did not force then latest would be selected even though the filter
is clicked.
This commit is contained in:
Sam Saffron 2019-11-01 13:52:25 +11:00
parent 70c6831125
commit 9fb09d147d
3 changed files with 48 additions and 5 deletions

View File

@ -15,8 +15,11 @@ export default Component.extend(
hidden: false,
rerenderTriggers: ["content.count"],
@computed("content.filterMode", "filterMode")
active(contentFilterMode, filterMode) {
@computed("content.filterMode", "filterMode", "content.active")
active(contentFilterMode, filterMode, active) {
if (active !== undefined) {
return active;
}
return (
contentFilterMode === filterMode ||
filterMode.indexOf(contentFilterMode) === 0

View File

@ -46,7 +46,7 @@ import { queryRegistry } from "discourse/widgets/widget";
import Composer from "discourse/models/composer";
// If you add any methods to the API ensure you bump up this number
const PLUGIN_API_VERSION = "0.8.34";
const PLUGIN_API_VERSION = "0.8.35";
class PluginApi {
constructor(version, container) {
@ -736,7 +736,9 @@ class PluginApi {
* displayName: "bugs"
* href: "/c/bugs",
* customFilter: (category, args, router) => { category && category.name !== 'bug' }
* customHref: (category, args, router) => { if (category && category.name) === 'not-a-bug') "/a-feature"; }
* customHref: (category, args, router) => { if (category && category.name) === 'not-a-bug') "/a-feature"; },
* before: "top",
* forceActive(category, args, router) => router.currentURL === "/a/b/c/d";
* })
*/
addNavigationBarItem(item) {
@ -763,6 +765,14 @@ class PluginApi {
};
}
const forceActive = item.forceActive;
if (forceActive) {
const router = this.container.lookup("service:router");
item.forceActive = function(category, args) {
return forceActive(category, args, router);
};
}
addNavItem(item);
}
}

View File

@ -193,12 +193,42 @@ NavItem.reopenClass({
return item.customFilter.call(this, category, args);
});
let forceActive = false;
extraItems.forEach(item => {
const before = item.before;
if (before) {
let i = 0;
for (i = 0; i < items.length; i++) {
if (items[i].name === before) {
break;
}
}
items.splice(i, 0, item);
} else {
items.push(item);
}
if (!item.customHref) return;
item.set("href", item.customHref.call(this, category, args));
if (item.forceActive && item.forceActive.call(this, category, args)) {
item.active = true;
forceActive = true;
} else {
item.active = undefined;
}
});
return items.concat(extraItems);
if (forceActive) {
items.forEach(i => {
if (i.active === undefined) {
i.active = false;
}
});
}
return items;
}
});