diff --git a/assets/javascripts/discourse-assign/controllers/assign-user.js.es6 b/assets/javascripts/discourse-assign/controllers/assign-user.js.es6
index 5d5800a..d41c0ef 100644
--- a/assets/javascripts/discourse-assign/controllers/assign-user.js.es6
+++ b/assets/javascripts/discourse-assign/controllers/assign-user.js.es6
@@ -1,7 +1,9 @@
import { ajax } from "discourse/lib/ajax";
import { popupAjaxError } from "discourse/lib/ajax-error";
+import { inject as controller } from "@ember/controller";
export default Ember.Controller.extend({
+ topicBulkActions: controller(),
assignSuggestions: null,
allowedGroups: null,
taskActions: Ember.inject.service(),
@@ -22,8 +24,19 @@ export default Ember.Controller.extend({
}
},
+ bulkAction(username) {
+ this.topicBulkActions.performAndRefresh({
+ type: "assign",
+ username,
+ });
+ },
+
actions: {
assignUser(user) {
+ if (this.isBulkAction) {
+ this.bulkAction(user.username);
+ return;
+ }
this.setProperties({
"model.username": user.username,
"model.allowedGroups": this.taskActions.allowedGroups,
@@ -32,6 +45,10 @@ export default Ember.Controller.extend({
},
assign() {
+ if (this.isBulkAction) {
+ this.bulkAction(this.model.username);
+ return;
+ }
let path = "/assign/assign";
if (Ember.isEmpty(this.get("model.username"))) {
diff --git a/assets/javascripts/discourse-assign/controllers/group-assigned-show.js.es6 b/assets/javascripts/discourse-assign/controllers/group-assigned-show.js.es6
index 5ea1aaf..27a841a 100644
--- a/assets/javascripts/discourse-assign/controllers/group-assigned-show.js.es6
+++ b/assets/javascripts/discourse-assign/controllers/group-assigned-show.js.es6
@@ -1,4 +1,5 @@
import UserTopicsList from "discourse/controllers/user-topics-list";
+import { alias } from "@ember/object/computed";
import { debounce } from "@ember/runloop";
import discourseComputed from "discourse-common/utils/decorators";
import { INPUT_DELAY } from "discourse-common/config/environment";
@@ -9,6 +10,9 @@ export default UserTopicsList.extend({
order: null,
ascending: false,
q: "",
+ bulkSelectEnabled: false,
+ selected: [],
+ canBulkSelect: alias("currentUser.staff"),
queryParams: ["order", "ascending", "q"],
@@ -61,5 +65,11 @@ export default UserTopicsList.extend({
onChangeFilter(value) {
debounce(this, this._setSearchTerm, value, INPUT_DELAY * 2);
},
+ toggleBulkSelect() {
+ this.toggleProperty("bulkSelectEnabled");
+ },
+ refresh() {
+ this.refreshModel();
+ },
},
});
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 f67eb8e..5ce0e70 100644
--- a/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
+++ b/assets/javascripts/discourse-assign/initializers/extend-for-assigns.js.es6
@@ -7,6 +7,9 @@ import { queryRegistry } from "discourse/widgets/widget";
import { getOwner } from "discourse-common/lib/get-owner";
import { htmlSafe } from "@ember/template";
import getURL from "discourse-common/lib/get-url";
+import { addBulkButton } from "discourse/controllers/topic-bulk-actions";
+import TopicButtonAction from "discourse/controllers/topic-bulk-actions";
+import { inject } from "@ember/controller";
import I18n from "I18n";
function titleForState(user) {
@@ -320,6 +323,30 @@ export default {
return;
}
+ const currentUser = container.lookup("current-user:main");
+ if (currentUser.can_assign) {
+ TopicButtonAction.reopen({
+ assignUser: inject("assign-user"),
+ actions: {
+ showReAssign() {
+ this.set("assignUser.isBulkAction", true);
+ this.set("assignUser.model", { username: "" });
+ this.send("changeBulkTemplate", "modal/assign-user");
+ },
+ unassignTopics() {
+ this.performAndRefresh({ type: "unassign" });
+ },
+ },
+ });
+ addBulkButton("showReAssign", "assign", {
+ icon: "user-plus",
+ class: "btn-default",
+ });
+ addBulkButton("unassignTopics", "unassign", {
+ icon: "user-times",
+ class: "btn-default",
+ });
+ }
withPluginApi("0.8.11", (api) => initialize(api, container));
withPluginApi("0.8.28", (api) =>
registerTopicFooterButtons(api, container)
diff --git a/assets/javascripts/discourse/templates/components/assigned-topic-list-item.hbs b/assets/javascripts/discourse/templates/components/assigned-topic-list-item.hbs
index 44c956f..798e711 100644
--- a/assets/javascripts/discourse/templates/components/assigned-topic-list-item.hbs
+++ b/assets/javascripts/discourse/templates/components/assigned-topic-list-item.hbs
@@ -5,8 +5,13 @@
This causes the topic-post-badge to be considered the same word as "text"
at the end of the link, preventing it from line wrapping onto its own line.
--}}
-
-
+{{#if bulkSelectEnabled}}
+ |
+
+ |
+{{/if}}
+
+
{{~raw "topic-status" topic=topic}}
{{~#if isPrivateMessage}}
{{~d-icon "envelope" class="private-message-icon"}}
diff --git a/assets/javascripts/discourse/templates/components/assigned-topic-list.hbs b/assets/javascripts/discourse/templates/components/assigned-topic-list.hbs
index c09697b..26dcd79 100644
--- a/assets/javascripts/discourse/templates/components/assigned-topic-list.hbs
+++ b/assets/javascripts/discourse/templates/components/assigned-topic-list.hbs
@@ -1,6 +1,7 @@
{{#unless skipHeader}}
{{raw "topic-list-header"
+ canBulkSelect=canBulkSelect
toggleInTitle=toggleInTitle
hideCategory=hideCategory
showPosters=showPosters
@@ -17,6 +18,7 @@
{{#each filteredTopics as |topic|}}
{{assigned-topic-list-item topic=topic
+ bulkSelectEnabled=bulkSelectEnabled
showTopicPostBadges=showTopicPostBadges
hideCategory=hideCategory
showPosters=showPosters
diff --git a/assets/javascripts/discourse/templates/components/basic-assigned-topic-list.hbs b/assets/javascripts/discourse/templates/components/basic-assigned-topic-list.hbs
index 4b8b01d..8013463 100644
--- a/assets/javascripts/discourse/templates/components/basic-assigned-topic-list.hbs
+++ b/assets/javascripts/discourse/templates/components/basic-assigned-topic-list.hbs
@@ -14,10 +14,13 @@
hideCategory=hideCategory
topics=topics
expandExcerpts=expandExcerpts
+ bulkSelectEnabled=bulkSelectEnabled
+ canBulkSelect=canBulkSelect
selected=selected
skipHeader=skipHeader
tagsForUser=tagsForUser
changeSort=changeSort
+ toggleBulkSelect=toggleBulkSelect
unassign=unassign
reassign=reassign
onScroll=onScroll
diff --git a/assets/javascripts/discourse/templates/group-topics-list.hbs b/assets/javascripts/discourse/templates/group-topics-list.hbs
index 9c7d662..9f668d5 100644
--- a/assets/javascripts/discourse/templates/group-topics-list.hbs
+++ b/assets/javascripts/discourse/templates/group-topics-list.hbs
@@ -8,17 +8,23 @@
{{#load-more class="paginated-topics-list" selector=".paginated-topics-list .topic-list tr" action=(action "loadMore")}}
+ {{bulk-select-button
+ selected=selected
+ action=(action "refresh")
+ }}
{{basic-assigned-topic-list
topicList=model
hideCategory=hideCategory
showPosters=showPosters
bulkSelectEnabled=bulkSelectEnabled
+ canBulkSelect=canBulkSelect
selected=selected
hasIncoming=hasIncoming
incomingCount=incomingCount
showInserted=(action "showInserted")
tagsForUser=tagsForUser
changeSort=(action "changeSort")
+ toggleBulkSelect=(action "toggleBulkSelect")
unassign=(action "unassign")
reassign=(action "reassign")
onScroll=saveScrollPosition
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index e31e653..db73b26 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -53,3 +53,7 @@ en:
assign_event:
name: "Assign Event"
details: "When a user assigns or unassigns a topic."
+ topics:
+ bulk:
+ unassign: "Unassign Topics"
+ assign: "Assign Topics"
diff --git a/plugin.rb b/plugin.rb
index 69dba46..8c7acdf 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -398,6 +398,29 @@ after_initialize do
end
end
+ TopicsBulkAction.register_operation("assign") do
+ if @user.can_assign?
+ assign_user = User.find_by_username(@operation[:username])
+ topics.each do |t|
+ TopicAssigner.new(t, @user).assign(assign_user)
+ end
+ end
+ end
+
+ TopicsBulkAction.register_operation("unassign") do
+ if @user.can_assign?
+ topics.each do |t|
+ if guardian.can_assign?
+ TopicAssigner.new(t, @user).unassign
+ end
+ end
+ end
+ end
+
+ if defined? register_permitted_bulk_action_parameter
+ register_permitted_bulk_action_parameter :username
+ end
+
if defined? UserBookmarkSerializer
add_to_class(:user_bookmark_serializer, :assigned_to_user_id) do
id = topic.custom_fields[TopicAssigner::ASSIGNED_TO_ID]
diff --git a/spec/components/topics_bulk_action_spec.rb b/spec/components/topics_bulk_action_spec.rb
new file mode 100644
index 0000000..a0f485f
--- /dev/null
+++ b/spec/components/topics_bulk_action_spec.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require_relative '../support/assign_allowed_group'
+
+describe TopicsBulkAction do
+ fab!(:post) { Fabricate(:post) }
+ fab!(:post1) { Fabricate(:post) }
+ fab!(:post2) { Fabricate(:post) }
+
+ before do
+ SiteSetting.assign_enabled = true
+ end
+
+ let(:user) { Fabricate(:user) }
+ let(:user2) { Fabricate(:user) }
+
+ include_context 'A group that is allowed to assign'
+
+ before do
+ add_to_assign_allowed_group(user)
+ end
+
+ describe "assign_topics" do
+ it "assigns multiple topics to user" do
+ TopicsBulkAction.new(user, [post.topic.id, post1.topic.id], { type: 'assign', username: user.username }).perform!
+
+ assigned_topics = TopicQuery.new(user, { page: 0 }).list_messages_assigned(user).topics
+
+ expect(assigned_topics.length).to eq(2)
+
+ expect(assigned_topics).to contain_exactly(post.topic, post1.topic)
+ end
+
+ it "doesn't allows to assign to user not in assign_allowed_group" do
+ TopicsBulkAction.new(user, [post.topic.id, post1.topic.id], { type: 'assign', username: user2.username }).perform!
+
+ assigned_topics = TopicQuery.new(user, { page: 0 }).list_messages_assigned(user2).topics
+
+ expect(assigned_topics.length).to eq(0)
+ end
+
+ it "user who is not in assign_allowed_group can't assign topics" do
+ TopicsBulkAction.new(user2, [post.topic.id, post1.topic.id, post2.topic.id], { type: 'assign', username: user.username }).perform!
+
+ assigned_topics = TopicQuery.new(user, { page: 0 }).list_messages_assigned(user).topics
+
+ expect(assigned_topics.length).to eq(0)
+ end
+ end
+
+ describe "unassign_topics" do
+ it "unassigns multiple topics assigned to user" do
+ TopicsBulkAction.new(user, [post.topic.id, post1.topic.id, post2.topic.id], { type: 'assign', username: user.username }).perform!
+
+ TopicsBulkAction.new(user, [post.topic.id, post1.topic.id], type: 'unassign').perform!
+
+ assigned_topics = TopicQuery.new(user, { page: 0 }).list_messages_assigned(user).topics
+
+ expect(assigned_topics.length).to eq(1)
+
+ expect(assigned_topics).to contain_exactly(post2.topic)
+ end
+
+ it "user who is not in assign_allowed_group can't unassign topics" do
+ TopicsBulkAction.new(user, [post.topic.id, post1.topic.id, post2.topic.id], { type: 'assign', username: user.username }).perform!
+
+ TopicsBulkAction.new(user2, [post.topic.id, post1.topic.id], type: 'unassign').perform!
+
+ assigned_topics = TopicQuery.new(user, { page: 0 }).list_messages_assigned(user).topics
+
+ expect(assigned_topics.length).to eq(3)
+
+ expect(assigned_topics).to contain_exactly(post.topic, post1.topic, post2.topic)
+ end
+
+ end
+end
|