FEATURE: Assign bulk actions for topics lists (#110)
- Allows unassigning and reassigning topics using bulk actions - Adds bulk actions UI to the group assigned page
This commit is contained in:
parent
e6a3bc80d7
commit
3e3dc3815b
|
@ -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"))) {
|
||||
|
|
|
@ -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();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
--}}
|
||||
<td class="main-link clearfix" colspan="1">
|
||||
<span class="link-top-line">
|
||||
{{#if bulkSelectEnabled}}
|
||||
<td class="bulk-select">
|
||||
<input type="checkbox" class="bulk-select">
|
||||
</td>
|
||||
{{/if}}
|
||||
<td class='main-link clearfix' colspan="1">
|
||||
<span class='link-top-line'>
|
||||
{{~raw "topic-status" topic=topic}}
|
||||
{{~#if isPrivateMessage}}
|
||||
{{~d-icon "envelope" class="private-message-icon"}}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{{#unless skipHeader}}
|
||||
<thead>
|
||||
{{raw "topic-list-header"
|
||||
canBulkSelect=canBulkSelect
|
||||
toggleInTitle=toggleInTitle
|
||||
hideCategory=hideCategory
|
||||
showPosters=showPosters
|
||||
|
@ -17,6 +18,7 @@
|
|||
<tbody>
|
||||
{{#each filteredTopics as |topic|}}
|
||||
{{assigned-topic-list-item topic=topic
|
||||
bulkSelectEnabled=bulkSelectEnabled
|
||||
showTopicPostBadges=showTopicPostBadges
|
||||
hideCategory=hideCategory
|
||||
showPosters=showPosters
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,17 +8,23 @@
|
|||
</div>
|
||||
</div>
|
||||
{{#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
|
||||
|
|
|
@ -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"
|
||||
|
|
23
plugin.rb
23
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]
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue