-
- {{html-safe (i18n "topics.bulk.selected" count=@model.topics.length)}}
-
-
- {{#if this.showProgress}}
-
- {{html-safe (i18n "topics.bulk.progress" count=this.processedTopicCount)}}
-
- {{else if this.activeComponent}}
-
- {{else}}
-
- {{#each this.buttons as |button|}}
-
- {{/each}}
-
- {{/if}}
-
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/app/components/modal/topic-bulk-actions.js b/app/assets/javascripts/discourse/app/components/modal/topic-bulk-actions.js
deleted file mode 100644
index 457bc07107c..00000000000
--- a/app/assets/javascripts/discourse/app/components/modal/topic-bulk-actions.js
+++ /dev/null
@@ -1,312 +0,0 @@
-import Component from "@glimmer/component";
-import { tracked } from "@glimmer/tracking";
-import { getOwner } from "@ember/application";
-import { action } from "@ember/object";
-import { service } from "@ember/service";
-import { Promise } from "rsvp";
-import Topic from "discourse/models/topic";
-import I18n from "discourse-i18n";
-import AppendTags from "../bulk-actions/append-tags";
-import ChangeCategory from "../bulk-actions/change-category";
-import ChangeTags from "../bulk-actions/change-tags";
-import NotificationLevel from "../bulk-actions/notification-level";
-
-const _customButtons = [];
-
-export function _addBulkButton(opts) {
- _customButtons.push({
- label: opts.label,
- icon: opts.icon,
- class: opts.class,
- visible: opts.visible,
- action: opts.action,
- });
-}
-
-export function clearBulkButtons() {
- _customButtons.length = 0;
-}
-
-// Modal for performing bulk actions on topics
-export default class TopicBulkActions extends Component {
- @service currentUser;
- @service siteSettings;
- @service dialog;
-
- @tracked loading = false;
- @tracked showProgress = false;
- @tracked processedTopicCount = 0;
- @tracked activeComponent = null;
-
- defaultButtons = [
- {
- label: "topics.bulk.change_category",
- icon: "pencil-alt",
- class: "btn-default bulk-actions__change-category",
- visible: ({ topics }) => !topics.some((t) => t.isPrivateMessage),
- action({ setComponent }) {
- setComponent(ChangeCategory);
- },
- },
- {
- label: "topics.bulk.close_topics",
- icon: "lock",
- class: "btn-default bulk-actions__close-topics",
- visible: ({ topics }) => !topics.some((t) => t.isPrivateMessage),
- action({ forEachPerformed }) {
- forEachPerformed({ type: "close" }, (t) => t.set("closed", true));
- },
- },
- {
- label: "topics.bulk.archive_topics",
- icon: "folder",
- class: "btn-default bulk-actions__archive-topics",
- visible: ({ topics }) => !topics.some((t) => t.isPrivateMessage),
- action({ forEachPerformed }) {
- forEachPerformed({ type: "archive" }, (t) => t.set("archived", true));
- },
- },
- {
- label: "topics.bulk.archive_topics",
- icon: "folder",
- class: "btn-default bulk-actions__archive-topics",
- visible: ({ topics }) => topics.some((t) => t.isPrivateMessage),
- action: ({ performAndRefresh }) => {
- const userPrivateMessages = getOwner(this).lookup(
- "controller:user-private-messages"
- );
- let params = { type: "archive_messages" };
-
- if (userPrivateMessages.isGroup) {
- params.group = userPrivateMessages.groupFilter;
- }
-
- performAndRefresh(params);
- },
- },
- {
- label: "topics.bulk.move_messages_to_inbox",
- icon: "folder",
- class: "btn-default bulk-actions__move-messages-to-inbox",
- visible: ({ topics }) => topics.some((t) => t.isPrivateMessage),
- action: ({ performAndRefresh }) => {
- const userPrivateMessages = getOwner(this).lookup(
- "controller:user-private-messages"
- );
- let params = { type: "move_messages_to_inbox" };
-
- if (userPrivateMessages.isGroup) {
- params.group = userPrivateMessages.groupFilter;
- }
-
- performAndRefresh(params);
- },
- },
- {
- label: "topics.bulk.notification_level",
- icon: "d-regular",
- class: "btn-default bulk-actions__notification-level",
- action({ setComponent }) {
- setComponent(NotificationLevel);
- },
- },
- {
- label: "topics.bulk.defer",
- icon: "circle",
- class: "btn-default bulk-actions__defer",
- visible: ({ currentUser }) => currentUser.user_option.enable_defer,
- action({ performAndRefresh }) {
- performAndRefresh({ type: "destroy_post_timing" });
- },
- },
- {
- label: "topics.bulk.unlist_topics",
- icon: "far-eye-slash",
- class: "btn-default bulk-actions__unlist",
- visible: ({ topics }) =>
- topics.some((t) => t.visible) &&
- !topics.some((t) => t.isPrivateMessage),
- action({ forEachPerformed }) {
- forEachPerformed({ type: "unlist" }, (t) => t.set("visible", false));
- },
- },
- {
- label: "topics.bulk.relist_topics",
- icon: "far-eye",
- class: "btn-default bulk-actions__relist",
- visible: ({ topics }) =>
- topics.some((t) => !t.visible) &&
- !topics.some((t) => t.isPrivateMessage),
- action({ forEachPerformed }) {
- forEachPerformed({ type: "relist" }, (t) => t.set("visible", true));
- },
- },
- {
- label: "topics.bulk.reset_bump_dates",
- icon: "anchor",
- class: "btn-default bulk-actions__reset-bump-dates",
- visible: ({ currentUser }) => currentUser.canManageTopic,
- action({ performAndRefresh }) {
- performAndRefresh({ type: "reset_bump_dates" });
- },
- },
- {
- label: "topics.bulk.change_tags",
- icon: "tag",
- class: "btn-default bulk-actions__change-tags",
- visible: ({ currentUser, siteSettings }) =>
- siteSettings.tagging_enabled && currentUser.canManageTopic,
- action({ setComponent }) {
- setComponent(ChangeTags);
- },
- },
- {
- label: "topics.bulk.append_tags",
- icon: "tag",
- class: "btn-default bulk-actions__append-tags",
- visible: ({ currentUser, siteSettings }) =>
- siteSettings.tagging_enabled && currentUser.canManageTopic,
- action({ setComponent }) {
- setComponent(AppendTags);
- },
- },
- {
- label: "topics.bulk.remove_tags",
- icon: "tag",
- class: "btn-default bulk-actions__remove-tags",
- visible: ({ currentUser, siteSettings }) =>
- siteSettings.tagging_enabled && currentUser.canManageTopic,
- action: ({ performAndRefresh, topics }) => {
- this.dialog.deleteConfirm({
- message: I18n.t("topics.bulk.confirm_remove_tags", {
- count: topics.length,
- }),
- didConfirm: () => performAndRefresh({ type: "remove_tags" }),
- });
- },
- },
- {
- label: "topics.bulk.delete",
- icon: "trash-alt",
- class: "btn-danger delete-topics bulk-actions__delete",
- visible: ({ currentUser }) => currentUser.staff,
- action({ performAndRefresh }) {
- performAndRefresh({ type: "delete" });
- },
- },
- ];
-
- constructor() {
- super(...arguments);
-
- if (this.args.model.initialAction === "set-component") {
- this.setComponent(this.args.model.initialComponent);
- }
- }
-
- get buttons() {
- return [...this.defaultButtons, ..._customButtons].filter(({ visible }) => {
- if (visible) {
- return visible({
- topics: this.args.model.topics,
- category: this.args.model.category,
- currentUser: this.currentUser,
- siteSettings: this.siteSettings,
- });
- } else {
- return true;
- }
- });
- }
-
- async perform(operation) {
- this.loading = true;
-
- if (this.args.model.topics.length > 20) {
- this.showProgress = true;
- }
-
- try {
- return this._processChunks(operation);
- } catch {
- this.dialog.alert(I18n.t("generic_error"));
- } finally {
- this.loading = false;
- this.processedTopicCount = 0;
- this.showProgress = false;
- }
- }
-
- _generateTopicChunks(allTopics) {
- let startIndex = 0;
- const chunkSize = 30;
- const chunks = [];
-
- while (startIndex < allTopics.length) {
- const topics = allTopics.slice(startIndex, startIndex + chunkSize);
- chunks.push(topics);
- startIndex += chunkSize;
- }
-
- return chunks;
- }
-
- _processChunks(operation) {
- const allTopics = this.args.model.topics;
- const topicChunks = this._generateTopicChunks(allTopics);
- const topicIds = [];
-
- const tasks = topicChunks.map((topics) => async () => {
- const result = await Topic.bulkOperation(topics, operation);
- this.processedTopicCount = this.processedTopicCount + topics.length;
- return result;
- });
-
- return new Promise((resolve, reject) => {
- const resolveNextTask = async () => {
- if (tasks.length === 0) {
- const topics = topicIds.map((id) => allTopics.findBy("id", id));
- return resolve(topics);
- }
-
- const task = tasks.shift();
-
- try {
- const result = await task();
- if (result?.topic_ids) {
- topicIds.push(...result.topic_ids);
- }
- resolveNextTask();
- } catch {
- reject();
- }
- };
-
- resolveNextTask();
- });
- }
-
- @action
- setComponent(component) {
- this.activeComponent = component;
- }
-
- @action
- async forEachPerformed(operation, cb) {
- const topics = await this.perform(operation);
-
- if (topics) {
- topics.forEach(cb);
- this.args.model.refreshClosure?.();
- this.args.closeModal();
- }
- }
-
- @action
- async performAndRefresh(operation) {
- await this.perform(operation);
-
- this.args.model.refreshClosure?.();
- this.args.closeModal();
- }
-}
diff --git a/app/assets/javascripts/discourse/app/components/topic-list.hbs b/app/assets/javascripts/discourse/app/components/topic-list.hbs
index 9f5f54cdbc1..ae89d49c9d2 100644
--- a/app/assets/javascripts/discourse/app/components/topic-list.hbs
+++ b/app/assets/javascripts/discourse/app/components/topic-list.hbs
@@ -15,7 +15,6 @@
listTitle=this.listTitle
bulkSelectEnabled=this.bulkSelectEnabled
bulkSelectHelper=this.bulkSelectHelper
- experimentalTopicBulkActionsEnabled=this.experimentalTopicBulkActionsEnabled
canDoBulkActions=this.canDoBulkActions
showTopicsAndRepliesToggle=this.showTopicsAndRepliesToggle
newListSubset=this.newListSubset
diff --git a/app/assets/javascripts/discourse/app/components/topic-list.js b/app/assets/javascripts/discourse/app/components/topic-list.js
index 1f5432c1f27..09ddc2db3f2 100644
--- a/app/assets/javascripts/discourse/app/components/topic-list.js
+++ b/app/assets/javascripts/discourse/app/components/topic-list.js
@@ -5,7 +5,6 @@ import { on } from "@ember/object/evented";
import { service } from "@ember/service";
import LoadMore from "discourse/mixins/load-more";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
-import TopicBulkActions from "./modal/topic-bulk-actions";
export default Component.extend(LoadMore, {
modal: service(),
@@ -50,11 +49,6 @@ export default Component.extend(LoadMore, {
);
},
- @discourseComputed
- experimentalTopicBulkActionsEnabled() {
- return this.currentUser?.use_experimental_topic_bulk_actions;
- },
-
@discourseComputed
sortable() {
return !!this.changeSort;
@@ -196,16 +190,6 @@ export default Component.extend(LoadMore, {
this.rerender();
});
- onClick("button.bulk-select-actions", () => {
- this.modal.show(TopicBulkActions, {
- model: {
- topics: this.bulkSelectHelper.selected,
- category: this.category,
- refreshClosure: () => this.router.refresh(),
- },
- });
- });
-
onClick("button.topics-replies-toggle", (element) => {
if (element.classList.contains("--all")) {
this.changeNewListSubset(null);
diff --git a/app/assets/javascripts/discourse/app/components/topic-list/list.gjs b/app/assets/javascripts/discourse/app/components/topic-list/list.gjs
index fe71c3d97c6..fa0ac5e52c9 100644
--- a/app/assets/javascripts/discourse/app/components/topic-list/list.gjs
+++ b/app/assets/javascripts/discourse/app/components/topic-list/list.gjs
@@ -32,10 +32,6 @@ export default class TopicList extends Component {
return !this.bulkSelectEnabled && this.args.canBulkSelect;
}
- get experimentalTopicBulkActionsEnabled() {
- return this.currentUser?.use_experimental_topic_bulk_actions;
- }
-
get sortable() {
return !!this.args.changeSort;
}
@@ -118,7 +114,6 @@ export default class TopicList extends Component {
@listTitle={{or @listTitle "topic.title"}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@bulkSelectHelper={{@bulkSelectHelper}}
- @experimentalTopicBulkActionsEnabled={{this.experimentalTopicBulkActionsEnabled}}
@canDoBulkActions={{this.canDoBulkActions}}
@showTopicsAndRepliesToggle={{@showTopicsAndRepliesToggle}}
@newListSubset={{@newListSubset}}
diff --git a/app/assets/javascripts/discourse/app/components/topic-list/topic-list-header-column.gjs b/app/assets/javascripts/discourse/app/components/topic-list/topic-list-header-column.gjs
index 66838dcee3f..bd9bacfd4c6 100644
--- a/app/assets/javascripts/discourse/app/components/topic-list/topic-list-header-column.gjs
+++ b/app/assets/javascripts/discourse/app/components/topic-list/topic-list-header-column.gjs
@@ -2,7 +2,6 @@ import Component from "@glimmer/component";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { service } from "@ember/service";
-import TopicBulkActions from "discourse/components/modal/topic-bulk-actions";
import NewListHeaderControls from "discourse/components/topic-list/new-list-header-controls";
import TopicBulkSelectDropdown from "discourse/components/topic-list/topic-bulk-select-dropdown";
import concatClass from "discourse/helpers/concat-class";
@@ -48,17 +47,6 @@ export default class TopicListHeaderColumn extends Component {
.forEach((el) => el.click());
}
- @action
- bulkSelectActions() {
- this.modal.show(TopicBulkActions, {
- model: {
- topics: this.args.bulkSelectHelper.selected,
- category: this.category,
- refreshClosure: () => this.router.refresh(),
- },
- });
- }
-
@action
onClick() {
this.args.changeSort(this.args.order);
@@ -100,24 +88,17 @@ export default class TopicListHeaderColumn extends Component {
title={{i18n "topics.bulk.toggle"}}
class="btn-flat bulk-select"
>
- {{icon (if @experimentalTopicBulkActionsEnabled "tasks" "list")}}
+ {{icon "tasks"}}
{{/if}}
{{#if @bulkSelectEnabled}}