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:
parent
9c2ebbaaf5
commit
600e1b6544
|
|
@ -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>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
export default {
|
||||
actions: {
|
||||
onChangeSetting(value) {
|
||||
this.set(
|
||||
"category.custom_fields.enable_unassigned_filter",
|
||||
value ? "true" : "false"
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
Loading…
Reference in New Issue