FEATURE: new category setting to add "Unassigned" navigation menu

When a category is used exclusively for managing topic assignments it can
be very useful to list all the unassigned topics. This introduces a new
category setting that allows admins to opt for this new navigation item.

It works both on mobile and desktop.

Unfortunately Discourse is lacking internal APIs for cleanly adding NavItems

We will look at improving this soon.
This commit is contained in:
Sam Saffron 2019-10-30 16:37:13 +11:00
parent 9c2ebbaaf5
commit 600e1b6544
6 changed files with 109 additions and 0 deletions

View File

@ -0,0 +1,13 @@
<h3>{{i18n 'discourse_assign.assign.title'}}</h3>
<section class='field'>
<div class="enable-accepted-answer">
<label class="checkbox-label">
{{input
type="checkbox"
checked=(readonly category.enable_unassigned_filter)
change=(action "onChangeSetting" value="target.checked")
}}
{{i18n 'discourse_assign.add_unassigned_filter'}}
</label>
</div>
</section>

View File

@ -0,0 +1,10 @@
export default {
actions: {
onChangeSetting(value) {
this.set(
"category.custom_fields.enable_unassigned_filter",
value ? "true" : "false"
);
}
}
};

View File

@ -5,6 +5,7 @@ import { h } from "virtual-dom";
import { iconHTML } from "discourse-common/lib/icon-library";
import { queryRegistry } from "discourse/widgets/widget";
import { getOwner } from "discourse-common/lib/get-owner";
import NavItem from "discourse/models/nav-item";
function registerTopicFooterButtons(api) {
api.registerTopicFooterButton({
@ -55,6 +56,65 @@ function registerTopicFooterButtons(api) {
}
function initialize(api) {
// START TEMPORARY HACK
//
// NavItem does not allow for proper customisation currently.
// The router sets "filterMode" which only includes partial data about the route
// This is the only information a nav item has when deciding if to highlight a route
// or not.
// Additionally short of monkey patching there is no way to insert a nav item prior to
// Top.
//
// This hack will be nuked when we add a new api like registerTopicFooterButtons for nav
api.modifyClass("route:discovery.latestParentCategory", {
_retrieveTopicList(category, transition) {
const params = transition.to.queryParams;
if (params && params["assigned"] === "nobody") {
this.controllerFor("navigation/category").setProperties({
filterMode: "Unassigned"
});
}
return this._super(category, transition);
}
});
const UnassignedNavItem = NavItem.extend({
@computed()
filterMode() {
return "Unassigned";
},
@computed("filterMode", "category")
href(filterMode, category) {
return Discourse.getURL(
"/c/" +
Discourse.Category.slugFor(category) +
"/l/latest?status=open&assigned=nobody"
);
}
});
api.modifyClass("component:d-navigation", {
@computed("filterMode", "category", "noSubcategories")
navItems(filterMode, category, noSubcategories) {
filterMode = "Unassigned";
let items = this._super(filterMode, category, noSubcategories);
if (category && category.enable_unassigned_filter) {
const args = {
name: "unassigned",
hasIcon: false,
category: category
};
const newItem = UnassignedNavItem.create(args);
items.splice(items.length - 1, 0, newItem);
}
return items;
}
});
// END TEMPORARY HACK
// You can't act on flags claimed by another user
api.modifyClass(
"component:flagged-post",

View File

@ -0,0 +1,20 @@
import Category from "discourse/models/category";
export default {
name: "extend-category-for-assign",
before: "inject-discourse-objects",
initialize() {
Category.reopen({
enable_unassigned_filter: Ember.computed(
"custom_fields.enable_unassigned_filter",
{
get(fieldName) {
return Ember.get(this.custom_fields, fieldName) === "true";
}
}
)
});
}
};

View File

@ -1,9 +1,14 @@
en:
js:
filters:
unassigned:
title: "Unassigned"
help: "Unassigned topics"
action_codes:
assigned: "assigned %{who} %{when}"
unassigned: "unassigned %{who} %{when}"
discourse_assign:
add_unassigned_filter: "Add 'unassigned' filter to category"
cant_act: "You cannot act on flags that have been assigned to other users"
cant_act_unclaimed: "You must claim this topic before acting on flags."
assigned: "Assigned"

View File

@ -100,6 +100,7 @@ after_initialize do
end
TopicList.preloaded_custom_fields << TopicAssigner::ASSIGNED_TO_ID
Site.preloaded_category_custom_fields << "enable_unassigned_filter" if Site.respond_to? :preloaded_category_custom_fields
TopicList.on_preload do |topics, topic_list|
if SiteSetting.assign_enabled?