diff --git a/assets/javascripts/discourse-assign/connectors/category-custom-settings/assign-settings.hbs b/assets/javascripts/discourse-assign/connectors/category-custom-settings/assign-settings.hbs
new file mode 100644
index 0000000..0ee2383
--- /dev/null
+++ b/assets/javascripts/discourse-assign/connectors/category-custom-settings/assign-settings.hbs
@@ -0,0 +1,13 @@
+
{{i18n 'discourse_assign.assign.title'}}
+
+
+
+
+
diff --git a/assets/javascripts/discourse-assign/connectors/category-custom-settings/assign-settings.js.es6 b/assets/javascripts/discourse-assign/connectors/category-custom-settings/assign-settings.js.es6
new file mode 100644
index 0000000..dcd2b94
--- /dev/null
+++ b/assets/javascripts/discourse-assign/connectors/category-custom-settings/assign-settings.js.es6
@@ -0,0 +1,10 @@
+export default {
+ actions: {
+ onChangeSetting(value) {
+ this.set(
+ "category.custom_fields.enable_unassigned_filter",
+ value ? "true" : "false"
+ );
+ }
+ }
+};
diff --git a/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6 b/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
index ea262d9..6a57abb 100644
--- a/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
+++ b/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
@@ -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",
diff --git a/assets/javascripts/discourse-assign/pre-initializers/extend-category-for-assign.js.es6 b/assets/javascripts/discourse-assign/pre-initializers/extend-category-for-assign.js.es6
new file mode 100644
index 0000000..3bb263e
--- /dev/null
+++ b/assets/javascripts/discourse-assign/pre-initializers/extend-category-for-assign.js.es6
@@ -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";
+ }
+ }
+ )
+ });
+ }
+};
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index c09e9be..76fd663 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -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"
diff --git a/plugin.rb b/plugin.rb
index cc59d97..425d733 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -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?