diff --git a/app/assets/javascripts/discourse/app/controllers/group-manage-categories.js b/app/assets/javascripts/discourse/app/controllers/group-manage-categories.js
index 629679cc34d..01059518f2c 100644
--- a/app/assets/javascripts/discourse/app/controllers/group-manage-categories.js
+++ b/app/assets/javascripts/discourse/app/controllers/group-manage-categories.js
@@ -6,9 +6,12 @@ export default Controller.extend({
"model.watchingCategories.[]",
"model.watchingFirstPostCategories.[]",
"model.trackingCategories.[]",
+ "model.regularCategories.[]",
"model.mutedCategories.[]"
)
- selectedCategories(watching, watchingFirst, tracking, muted) {
- return [].concat(watching, watchingFirst, tracking, muted).filter(t => t);
+ selectedCategories(watching, watchingFirst, tracking, regular, muted) {
+ return []
+ .concat(watching, watchingFirst, tracking, regular, muted)
+ .filter(t => t);
}
});
diff --git a/app/assets/javascripts/discourse/app/controllers/group-manage-tags.js b/app/assets/javascripts/discourse/app/controllers/group-manage-tags.js
index 151365c1da9..0066b58e472 100644
--- a/app/assets/javascripts/discourse/app/controllers/group-manage-tags.js
+++ b/app/assets/javascripts/discourse/app/controllers/group-manage-tags.js
@@ -6,9 +6,12 @@ export default Controller.extend({
"model.watching_tags.[]",
"model.watching_first_post_tags.[]",
"model.tracking_tags.[]",
+ "model.regular_tags.[]",
"model.muted_tags.[]"
)
- selectedTags(watching, watchingFirst, tracking, muted) {
- return [].concat(watching, watchingFirst, tracking, muted).filter(t => t);
+ selectedTags(watching, watchingFirst, tracking, regular, muted) {
+ return []
+ .concat(watching, watchingFirst, tracking, regular, muted)
+ .filter(t => t);
}
});
diff --git a/app/assets/javascripts/discourse/app/models/group.js b/app/assets/javascripts/discourse/app/models/group.js
index 883aedc0bef..1f3681b28e0 100644
--- a/app/assets/javascripts/discourse/app/models/group.js
+++ b/app/assets/javascripts/discourse/app/models/group.js
@@ -200,6 +200,14 @@ const Group = RestModel.extend({
);
},
+ @observes("regular_category_ids")
+ _updateRegularCategories() {
+ this.set(
+ "regularCategories",
+ Category.findByIds(this.regular_category_ids)
+ );
+ },
+
@observes("muted_category_ids")
_updateMutedCategories() {
this.set("mutedCategories", Category.findByIds(this.muted_category_ids));
@@ -240,25 +248,27 @@ const Group = RestModel.extend({
publish_read_state: this.publish_read_state
};
- ["muted", "watching", "tracking", "watching_first_post"].forEach(s => {
- let prop =
- s === "watching_first_post"
- ? "watchingFirstPostCategories"
- : s + "Categories";
+ ["muted", "regular", "watching", "tracking", "watching_first_post"].forEach(
+ s => {
+ let prop =
+ s === "watching_first_post"
+ ? "watchingFirstPostCategories"
+ : s + "Categories";
- let categories = this.get(prop);
+ let categories = this.get(prop);
- if (categories) {
- attrs[s + "_category_ids"] =
- categories.length > 0 ? categories.map(c => c.get("id")) : [-1];
+ if (categories) {
+ attrs[s + "_category_ids"] =
+ categories.length > 0 ? categories.map(c => c.get("id")) : [-1];
+ }
+
+ let tags = this.get(s + "_tags");
+
+ if (tags) {
+ attrs[s + "_tags"] = tags.length > 0 ? tags : [""];
+ }
}
-
- let tags = this.get(s + "_tags");
-
- if (tags) {
- attrs[s + "_tags"] = tags.length > 0 ? tags : [""];
- }
- });
+ );
if (this.flair_type === "icon") {
attrs["flair_icon"] = this.flair_icon;
diff --git a/app/assets/javascripts/discourse/app/templates/group/manage/categories.hbs b/app/assets/javascripts/discourse/app/templates/group/manage/categories.hbs
index c130ce5a8a5..61af9de7c5b 100644
--- a/app/assets/javascripts/discourse/app/templates/group/manage/categories.hbs
+++ b/app/assets/javascripts/discourse/app/templates/group/manage/categories.hbs
@@ -5,11 +5,11 @@
-
+
{{category-selector
categories=model.watchingCategories
- blacklist=selectedCategories
+ blocklist=selectedCategories
onChange=(action (mut model.watchingCategories))
}}
@@ -19,11 +19,11 @@
-
+
{{category-selector
categories=model.trackingCategories
- blacklist=selectedCategories
+ blocklist=selectedCategories
onChange=(action (mut model.trackingCategories))
}}
@@ -33,11 +33,11 @@
-
+
{{category-selector
categories=model.watchingFirstPostCategories
- blacklist=selectedCategories
+ blocklist=selectedCategories
onChange=(action (mut model.watchingFirstPostCategories))
}}
@@ -47,11 +47,25 @@
-
+
+
+ {{category-selector
+ categories=model.regularCategories
+ blocklist=selectedCategories
+ onChange=(action (mut model.regularCategories))
+ }}
+
+
+ {{i18n "groups.manage.categories.regular_categories_instructions"}}
+
+
+
+
+
{{category-selector
categories=model.mutedCategories
- blacklist=selectedCategories
+ blocklist=selectedCategories
onChange=(action (mut model.mutedCategories))
}}
diff --git a/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs b/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs
index 6a5a91019a4..604ac185247 100644
--- a/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs
+++ b/app/assets/javascripts/discourse/app/templates/group/manage/tags.hbs
@@ -5,7 +5,7 @@
-
+
{{tag-chooser
tags=model.watching_tags
@@ -21,7 +21,7 @@
-
+
{{tag-chooser
tags=model.tracking_tags
@@ -37,7 +37,7 @@
-
+
{{tag-chooser
tags=model.watching_first_post_tags
@@ -53,7 +53,23 @@
-
+
+
+ {{tag-chooser
+ tags=model.regular_tags
+ blacklist=selectedTags
+ allowCreate=false
+ everyTag=true
+ unlimitedTagCount=true
+ }}
+
+
+ {{i18n "groups.manage.tags.regular_tags_instructions"}}
+
+
+
+
+
{{tag-chooser
tags=model.muted_tags
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 53ca79530b2..c473ce6d282 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -611,7 +611,7 @@ class GroupsController < ApplicationController
end
if !automatic || current_user.admin
- [:muted, :tracking, :watching, :watching_first_post].each do |level|
+ [:muted, :regular, :tracking, :watching, :watching_first_post].each do |level|
permitted_params << { "#{level}_category_ids" => [] }
permitted_params << { "#{level}_tags" => [] }
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 9b99d4667dc..61a986443f9 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -765,7 +765,7 @@ class Group < ActiveRecord::Base
flair_icon.presence || flair_upload&.short_path
end
- [:muted, :tracking, :watching, :watching_first_post].each do |level|
+ [:muted, :regular, :tracking, :watching, :watching_first_post].each do |level|
define_method("#{level}_category_ids=") do |category_ids|
@category_notifications ||= {}
@category_notifications[level] = category_ids
diff --git a/app/models/group_user.rb b/app/models/group_user.rb
index f2806219e10..921641d4c64 100644
--- a/app/models/group_user.rb
+++ b/app/models/group_user.rb
@@ -86,7 +86,7 @@ class GroupUser < ActiveRecord::Base
higher_level_category_ids = user_levels.values.flatten
- [:muted, :tracking, :watching_first_post, :watching].each do |level|
+ [:muted, :regular, :tracking, :watching_first_post, :watching].each do |level|
level_num = NotificationLevels.all[level]
higher_level_category_ids -= (user_levels[level_num] || [])
if group_category_ids = group_levels[level_num]
@@ -118,7 +118,7 @@ class GroupUser < ActiveRecord::Base
higher_level_tag_ids = user_levels.values.flatten
- [:muted, :tracking, :watching_first_post, :watching].each do |level|
+ [:muted, :regular, :tracking, :watching_first_post, :watching].each do |level|
level_num = NotificationLevels.all[level]
higher_level_tag_ids -= (user_levels[level_num] || [])
if group_tag_ids = group_levels[level_num]
diff --git a/app/serializers/basic_group_serializer.rb b/app/serializers/basic_group_serializer.rb
index 1b2f9d0ece9..c75189022f3 100644
--- a/app/serializers/basic_group_serializer.rb
+++ b/app/serializers/basic_group_serializer.rb
@@ -69,10 +69,12 @@ class BasicGroupSerializer < ApplicationSerializer
admin_or_owner_attributes :watching_category_ids,
:tracking_category_ids,
:watching_first_post_category_ids,
+ :regular_category_ids,
:muted_category_ids,
:watching_tags,
:watching_first_post_tags,
:tracking_tags,
+ :regular_tags,
:muted_tags
def include_display_name?
@@ -121,7 +123,7 @@ class BasicGroupSerializer < ApplicationSerializer
scope.can_see_group_members?(object)
end
- [:watching, :tracking, :watching_first_post, :muted].each do |level|
+ [:watching, :regular, :tracking, :watching_first_post, :muted].each do |level|
define_method("#{level}_category_ids") do
GroupCategoryNotificationDefault.lookup(object, level).pluck(:category_id)
end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 9a0a16a1332..46b2680b795 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -663,6 +663,7 @@ en:
watched_categories_instructions: "Automatically watch all topics in these categories. Group members will be notified of all new posts and topics, and a count of new posts will also appear next to the topic."
tracked_categories_instructions: "Automatically track all topics in these categories. A count of new posts will appear next to the topic."
watching_first_post_categories_instructions: "Users will be notified of the first post in each new topic in these categories."
+ regular_categories_instructions: "If these categories are muted, they will be unmuted for group members. Users will be notified if they are mentioned or someone replies to them."
muted_categories_instructions: "Users will not be notified of anything about new topics in these categories, and they will not appear on the categories or latest topics pages."
tags:
title: Tags
@@ -671,6 +672,7 @@ en:
watched_tags_instructions: "Automatically watch all topics with these tags. Group members will be notified of all new posts and topics, and a count of new posts will also appear next to the topic."
tracked_tags_instructions: "Automatically track all topics with these tags. A count of new posts will appear next to the topic."
watching_first_post_tags_instructions: "Users will be notified of the first post in each new topic with these tags."
+ regular_tags_instructions: "If these tags are muted, they will be unmuted for group members. Users will be notified if they are mentioned or someone replies to them."
muted_tags_instructions: "Users will not be notified of anything about new topics with these tags, and they will not appear in latest."
logs:
title: "Logs"
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index d57b8b996d4..dad0ef6dad1 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -1059,18 +1059,22 @@ describe Group do
let(:category1) { Fabricate(:category) }
let(:category2) { Fabricate(:category) }
let(:category3) { Fabricate(:category) }
+ let(:category4) { Fabricate(:category) }
let(:tag1) { Fabricate(:tag) }
let(:tag2) { Fabricate(:tag) }
let(:tag3) { Fabricate(:tag) }
+ let(:tag4) { Fabricate(:tag) }
let(:synonym1) { Fabricate(:tag, target_tag: tag1) }
let(:synonym2) { Fabricate(:tag, target_tag: tag2) }
it "can set category notifications" do
group.watching_category_ids = [category1.id, category2.id]
group.tracking_category_ids = [category3.id]
+ group.regular_category_ids = [category4.id]
group.save!
expect(GroupCategoryNotificationDefault.lookup(group, :watching).pluck(:category_id)).to contain_exactly(category1.id, category2.id)
expect(GroupCategoryNotificationDefault.lookup(group, :tracking).pluck(:category_id)).to eq([category3.id])
+ expect(GroupCategoryNotificationDefault.lookup(group, :regular).pluck(:category_id)).to eq([category4.id])
new_group = Fabricate.build(:group)
new_group.watching_category_ids = [category1.id, category2.id]
@@ -1097,9 +1101,11 @@ describe Group do
end
it "can set tag notifications" do
+ group.regular_tags = [tag4.name]
group.watching_tags = [tag1.name, tag2.name]
group.tracking_tags = [tag3.name]
group.save!
+ expect(GroupTagNotificationDefault.lookup(group, :regular).pluck(:tag_id)).to eq([tag4.id])
expect(GroupTagNotificationDefault.lookup(group, :watching).pluck(:tag_id)).to contain_exactly(tag1.id, tag2.id)
expect(GroupTagNotificationDefault.lookup(group, :tracking).pluck(:tag_id)).to eq([tag3.id])
diff --git a/spec/models/group_user_spec.rb b/spec/models/group_user_spec.rb
index cd35144c9b3..6b3029bab54 100644
--- a/spec/models/group_user_spec.rb
+++ b/spec/models/group_user_spec.rb
@@ -39,6 +39,7 @@ describe GroupUser do
let(:category2) { Fabricate(:category) }
let(:category3) { Fabricate(:category) }
let(:category4) { Fabricate(:category) }
+ let(:category5) { Fabricate(:category) }
def levels
CategoryUser.notification_levels
@@ -50,16 +51,18 @@ describe GroupUser do
it "adds new category notifications" do
group.muted_category_ids = [category1.id]
- group.tracking_category_ids = [category2.id]
- group.watching_category_ids = [category3.id]
- group.watching_first_post_category_ids = [category4.id]
+ group.regular_category_ids = [category2.id]
+ group.tracking_category_ids = [category3.id]
+ group.watching_category_ids = [category4.id]
+ group.watching_first_post_category_ids = [category5.id]
group.save!
- expect { group.add(user) }.to change { CategoryUser.count }.by(4)
+ expect { group.add(user) }.to change { CategoryUser.count }.by(5)
h = CategoryUser.notification_levels_for(Guardian.new(user))
expect(h[category1.id]).to eq(levels[:muted])
- expect(h[category2.id]).to eq(levels[:tracking])
- expect(h[category3.id]).to eq(levels[:watching])
- expect(h[category4.id]).to eq(levels[:watching_first_post])
+ expect(h[category2.id]).to eq(levels[:regular])
+ expect(h[category3.id]).to eq(levels[:tracking])
+ expect(h[category4.id]).to eq(levels[:watching])
+ expect(h[category5.id]).to eq(levels[:watching_first_post])
end
it "only upgrades notifications" do
@@ -67,11 +70,12 @@ describe GroupUser do
CategoryUser.create!(user: user, category_id: category2.id, notification_level: levels[:tracking])
CategoryUser.create!(user: user, category_id: category3.id, notification_level: levels[:watching_first_post])
CategoryUser.create!(user: user, category_id: category4.id, notification_level: levels[:watching])
- group.watching_first_post_category_ids = [category1.id, category2.id, category3.id, category4.id]
+ group.regular_category_ids = [category1.id]
+ group.watching_first_post_category_ids = [category2.id, category3.id, category4.id]
group.save!
group.add(user)
h = CategoryUser.notification_levels_for(Guardian.new(user))
- expect(h[category1.id]).to eq(levels[:watching_first_post])
+ expect(h[category1.id]).to eq(levels[:regular])
expect(h[category2.id]).to eq(levels[:watching_first_post])
expect(h[category3.id]).to eq(levels[:watching_first_post])
expect(h[category4.id]).to eq(levels[:watching])
@@ -100,6 +104,7 @@ describe GroupUser do
let(:tag2) { Fabricate(:tag) }
let(:tag3) { Fabricate(:tag) }
let(:tag4) { Fabricate(:tag) }
+ let(:tag5) { Fabricate(:tag) }
let(:synonym1) { Fabricate(:tag, target_tag: tag1) }
def levels
@@ -112,15 +117,17 @@ describe GroupUser do
it "adds new tag notifications" do
group.muted_tags = [synonym1.name]
- group.tracking_tags = [tag2.name]
- group.watching_tags = [tag3.name]
- group.watching_first_post_tags = [tag4.name]
+ group.regular_tags = [tag2.name]
+ group.tracking_tags = [tag3.name]
+ group.watching_tags = [tag4.name]
+ group.watching_first_post_tags = [tag5.name]
group.save!
- expect { group.add(user) }.to change { TagUser.count }.by(4)
+ expect { group.add(user) }.to change { TagUser.count }.by(5)
expect(TagUser.lookup(user, :muted).pluck(:tag_id)).to eq([tag1.id])
- expect(TagUser.lookup(user, :tracking).pluck(:tag_id)).to eq([tag2.id])
- expect(TagUser.lookup(user, :watching).pluck(:tag_id)).to eq([tag3.id])
- expect(TagUser.lookup(user, :watching_first_post).pluck(:tag_id)).to eq([tag4.id])
+ expect(TagUser.lookup(user, :regular).pluck(:tag_id)).to eq([tag2.id])
+ expect(TagUser.lookup(user, :tracking).pluck(:tag_id)).to eq([tag3.id])
+ expect(TagUser.lookup(user, :watching).pluck(:tag_id)).to eq([tag4.id])
+ expect(TagUser.lookup(user, :watching_first_post).pluck(:tag_id)).to eq([tag5.id])
end
it "only upgrades notifications" do
@@ -128,13 +135,15 @@ describe GroupUser do
TagUser.create!(user: user, tag_id: tag2.id, notification_level: levels[:tracking])
TagUser.create!(user: user, tag_id: tag3.id, notification_level: levels[:watching_first_post])
TagUser.create!(user: user, tag_id: tag4.id, notification_level: levels[:watching])
- group.watching_first_post_tags = [tag1.name, tag2.name, tag3.name, tag4.name]
+ group.regular_tags = [tag1.name]
+ group.watching_first_post_tags = [tag2.name, tag3.name, tag4.name]
group.save!
group.add(user)
expect(TagUser.lookup(user, :muted).pluck(:tag_id)).to be_empty
+ expect(TagUser.lookup(user, :regular).pluck(:tag_id)).to eq([tag1.id])
expect(TagUser.lookup(user, :tracking).pluck(:tag_id)).to be_empty
expect(TagUser.lookup(user, :watching).pluck(:tag_id)).to eq([tag4.id])
- expect(TagUser.lookup(user, :watching_first_post).pluck(:tag_id)).to contain_exactly(tag1.id, tag2.id, tag3.id)
+ expect(TagUser.lookup(user, :watching_first_post).pluck(:tag_id)).to contain_exactly(tag2.id, tag3.id)
end
it "merges notifications" do
diff --git a/test/javascripts/acceptance/group-manage-categories-test.js b/test/javascripts/acceptance/group-manage-categories-test.js
index 5bf7c88ea32..00aaf77ef40 100644
--- a/test/javascripts/acceptance/group-manage-categories-test.js
+++ b/test/javascripts/acceptance/group-manage-categories-test.js
@@ -16,7 +16,7 @@ QUnit.test("As an admin", async assert => {
await visit("/g/discourse/manage/categories");
assert.ok(
- find(".groups-notifications-form .category-selector").length === 4,
+ find(".groups-notifications-form .category-selector").length === 5,
"it should display category inputs"
);
});
@@ -27,7 +27,7 @@ QUnit.test("As a group owner", async assert => {
await visit("/g/discourse/manage/categories");
assert.ok(
- find(".groups-notifications-form .category-selector").length === 4,
+ find(".groups-notifications-form .category-selector").length === 5,
"it should display category inputs"
);
});
diff --git a/test/javascripts/acceptance/group-manage-tags-test.js b/test/javascripts/acceptance/group-manage-tags-test.js
index d5140e199b5..86b3cb82833 100644
--- a/test/javascripts/acceptance/group-manage-tags-test.js
+++ b/test/javascripts/acceptance/group-manage-tags-test.js
@@ -16,7 +16,7 @@ QUnit.test("As an admin", async assert => {
await visit("/g/discourse/manage/tags");
assert.ok(
- find(".groups-notifications-form .tag-chooser").length === 4,
+ find(".groups-notifications-form .tag-chooser").length === 5,
"it should display tag inputs"
);
});
@@ -27,7 +27,7 @@ QUnit.test("As a group owner", async assert => {
await visit("/g/discourse/manage/tags");
assert.ok(
- find(".groups-notifications-form .tag-chooser").length === 4,
+ find(".groups-notifications-form .tag-chooser").length === 5,
"it should display tag inputs"
);
});