DEV: Add more bulk-select-dropdown options (#25574)

This change updates the experimental bulk-select-dropdown (that is
currently feature-flagged) with more options.
This commit is contained in:
Blake Erickson 2024-02-21 20:56:27 -07:00 committed by GitHub
parent 5dba5c4208
commit 368bd2697a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 293 additions and 28 deletions

View File

@ -1,19 +1,34 @@
import Component from "@glimmer/component";
import { action } from "@ember/object";
import { tracked } from "@glimmer/tracking";
import { action, computed } from "@ember/object";
import { inject as service } from "@ember/service";
import { Promise } from "rsvp";
import ChangeTags from "discourse/components/bulk-actions/change-tags";
import DButton from "discourse/components/d-button";
import DModal from "discourse/components/d-modal";
import RadioButton from "discourse/components/radio-button";
import { topicLevels } from "discourse/lib/notification-levels";
import Topic from "discourse/models/topic";
import htmlSafe from "discourse-common/helpers/html-safe";
import i18n from "discourse-common/helpers/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";
import CategoryChooser from "select-kit/components/category-chooser";
import TagChooser from "select-kit/components/tag-chooser";
export default class BulkTopicActions extends Component {
@service router;
@tracked activeComponent = null;
@tracked tags = [];
@tracked categoryId;
notificationLevelId = null;
constructor() {
super(...arguments);
if (this.args.model.initialAction === "set-component") {
this.setComponent(ChangeTags);
}
}
async perform(operation) {
this.loading = true;
@ -25,7 +40,7 @@ export default class BulkTopicActions extends Component {
try {
return this._processChunks(operation);
} catch {
this.dialog.alert(i18n.t("generic_error"));
this.dialog.alert(i18n("generic_error"));
} finally {
this.loading = false;
this.processedTopicCount = 0;
@ -97,6 +112,54 @@ export default class BulkTopicActions extends Component {
case "close":
this.forEachPerformed({ type: "close" }, (t) => t.set("closed", true));
break;
case "archive":
this.forEachPerformed({ type: "archive" }, (t) =>
t.set("archived", true)
);
break;
case "unlist":
this.forEachPerformed({ type: "unlist" }, (t) =>
t.set("unlisted", true)
);
break;
case "relist":
this.forEachPerformed({ type: "relist" }, (t) =>
t.set("unlisted", false)
);
break;
case "append-tags":
this.performAndRefresh({ type: "append_tags", tags: this.tags });
break;
case "replace-tags":
this.performAndRefresh({ type: "change_tags", tags: this.tags });
break;
case "remove-tags":
this.performAndRefresh({ type: "remove_tags" });
break;
case "delete":
this.performAndRefresh({ type: "delete" });
break;
case "reset-bump-dates":
this.performAndRefresh({ type: "reset_bump_dates" });
break;
case "defer":
this.performAndRefresh({ type: "destroy_post_timing" });
break;
case "update-notifications":
this.performAndRefresh({
type: "change_notification_level",
notification_level_id: this.notificationLevelId,
});
break;
case "update-category":
this.forEachPerformed(
{
type: "change_category",
category_id: this.categoryId,
},
(t) => t.set("category_id", this.categoryId)
);
break;
}
}
@ -118,6 +181,38 @@ export default class BulkTopicActions extends Component {
this.args.model.refreshClosure?.();
this.args.closeModal();
this.args.model.bulkSelectHelper.toggleBulkSelect();
}
@computed("action")
get isTagAction() {
return (
this.args.model.action === "append-tags" ||
this.args.model.action === "replace-tags"
);
}
@computed("action")
get isNotificationAction() {
return this.args.model.action === "update-notifications";
}
@computed("action")
get isCategoryAction() {
return this.args.model.action === "update-category";
}
get notificationLevels() {
return topicLevels.map((level) => ({
id: level.id.toString(),
name: i18n(`topic.notifications.${level.key}.title`),
description: i18n(`topic.notifications.${level.key}.description`),
}));
}
@action
onCategoryChange(categoryId) {
this.categoryId = categoryId;
}
<template>
@ -128,8 +223,44 @@ export default class BulkTopicActions extends Component {
>
<:body>
<div>
{{htmlSafe (i18n "topics.bulk.selected" count=@model.topics.length)}}
{{htmlSafe
(i18n
"topics.bulk.selected"
count=@model.bulkSelectHelper.selected.length
)
}}
</div>
{{#if this.isCategoryAction}}
<p>
<CategoryChooser
@value={{this.categoryId}}
@onChange={{this.onCategoryChange}}
/>
</p>
{{/if}}
{{#if this.isNotificationAction}}
<div class="bulk-notification-list">
{{#each this.notificationLevels as |level|}}
<div class="controls">
<label class="radio notification-level-radio checkbox-label">
<RadioButton
@value={{level.id}}
@name="notification_level"
@selection={{this.notificationLevelId}}
/>
<strong>{{level.name}}</strong>
<div class="description">{{htmlSafe level.description}}</div>
</label>
</div>
{{/each}}
</div>
{{/if}}
{{#if this.isTagAction}}
<p><TagChooser @tags={{this.tags}} @categoryId={{@categoryId}} /></p>
{{/if}}
</:body>
<:footer>

View File

@ -1,8 +1,6 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import ChangeCategory from "discourse/components/bulk-actions/change-category";
import BulkTopicActions from "discourse/components/modal/bulk-topic-actions";
import TopicBulkActions from "discourse/components/modal/topic-bulk-actions";
import i18n from "discourse-common/helpers/i18n";
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
@ -18,6 +16,8 @@ export default DropdownSelectBoxComponent.extend({
modal: service(),
router: service(),
currentUser: service(),
siteSettings: service(),
computeContent() {
let options = [];
@ -28,41 +28,152 @@ export default DropdownSelectBoxComponent.extend({
name: i18n("topic_bulk_actions.update_category.name"),
description: i18n("topic_bulk_actions.update_category.description"),
},
{
id: "update-notifications",
icon: "d-regular",
name: i18n("topic_bulk_actions.update_notifications.name"),
description: i18n(
"topic_bulk_actions.update_notifications.description"
),
},
{
id: "reset-bump-dates",
icon: "anchor",
name: i18n("topic_bulk_actions.reset_bump_dates.name"),
description: i18n("topic_bulk_actions.reset_bump_dates.description"),
},
{
id: "defer",
icon: "circle",
name: i18n("topic_bulk_actions.defer.name"),
description: i18n("topic_bulk_actions.defer.description"),
visible: ({ currentUser }) => currentUser.user_option.enable_defer,
},
{
id: "close-topics",
icon: "lock",
name: i18n("topic_bulk_actions.close_topics.name"),
},
{
id: "archive-topics",
icon: "folder",
name: i18n("topic_bulk_actions.archive_topics.name"),
},
{
id: "unlist-topics",
icon: "far-eye-slash",
name: i18n("topic_bulk_actions.unlist_topics.name"),
visible: ({ topics }) =>
topics.some((t) => t.visible) &&
!topics.some((t) => t.isPrivateMessage),
},
{
id: "relist-topics",
icon: "far-eye",
name: i18n("topic_bulk_actions.relist_topics.name"),
visible: ({ topics }) =>
topics.some((t) => !t.visible) &&
!topics.some((t) => t.isPrivateMessage),
},
{
id: "append-tags",
icon: "tag",
name: i18n("topic_bulk_actions.append_tags.name"),
visible: ({ currentUser, siteSettings }) =>
siteSettings.tagging_enabled && currentUser.canManageTopic,
},
{
id: "replace-tags",
icon: "tag",
name: i18n("topic_bulk_actions.replace_tags.name"),
visible: ({ currentUser, siteSettings }) =>
siteSettings.tagging_enabled && currentUser.canManageTopic,
},
{
id: "remove-tags",
icon: "tag",
name: i18n("topic_bulk_actions.remove_tags.name"),
visible: ({ currentUser, siteSettings }) =>
siteSettings.tagging_enabled && currentUser.canManageTopic,
},
{
id: "delete-topics",
icon: "trash-alt",
name: i18n("topic_bulk_actions.delete_topics.name"),
visible: ({ currentUser }) => currentUser.staff,
},
]);
return options;
return [...options].filter(({ visible }) => {
if (visible) {
return visible({
topics: this.bulkSelectHelper.selected,
currentUser: this.currentUser,
siteSettings: this.siteSettings,
});
} else {
return true;
}
});
},
showBulkTopicActionsModal(actionName, title, opts = {}) {
let allowSilent = false;
if (opts.allowSilent === true) {
allowSilent = true;
}
this.modal.show(BulkTopicActions, {
model: {
action: actionName,
title: i18n(`topics.bulk.${title}`),
bulkSelectHelper: this.bulkSelectHelper,
refreshClosure: () => this.router.refresh(),
allowSilent,
},
});
},
@action
onSelect(id) {
switch (id) {
case "update-category":
// Temporary: just use the existing modal & action
this.modal.show(TopicBulkActions, {
model: {
topics: this.bulkSelectHelper.selected,
category: this.category,
refreshClosure: () => this.router.refresh(),
initialAction: "set-component",
initialComponent: ChangeCategory,
},
});
this.showBulkTopicActionsModal(id, "change_category");
break;
case "update-notifications":
this.showBulkTopicActionsModal(id, "notification_level");
break;
case "close-topics":
this.modal.show(BulkTopicActions, {
model: {
action: "close",
title: i18n("topics.bulk.close_topics"),
bulkSelectHelper: this.bulkSelectHelper,
refreshClosure: () => this.router.refresh(),
allowSilent: true,
},
this.showBulkTopicActionsModal("close", "close_topics", {
allowSilent: true,
});
break;
case "archive-topics":
this.showBulkTopicActionsModal("archive", "archive_topics");
break;
case "unlist-topics":
this.showBulkTopicActionsModal("unlist", "unlist_topics");
break;
case "relist-topics":
this.showBulkTopicActionsModal("relist", "relist_topics");
break;
case "append-tags":
this.showBulkTopicActionsModal(id, "choose_append_tags");
break;
case "replace-tags":
this.showBulkTopicActionsModal(id, "change_tags");
break;
case "remove-tags":
this.showBulkTopicActionsModal(id, "remove_tags");
break;
case "delete-topics":
this.showBulkTopicActionsModal("delete", "delete");
break;
case "reset-bump-dates":
this.showBulkTopicActionsModal(id, "reset_bump_dates");
break;
case "defer":
this.showBulkTopicActionsModal(id, "defer");
break;
}
},
});

View File

@ -2997,9 +2997,32 @@ en:
topic_bulk_actions:
close_topics:
name: "Close Topics"
archive_topics:
name: "Archive Topics"
unlist_topics:
name: "Unlist Topics"
relist_topics:
name: "Relist Topics"
remove_tags:
name: "Remove Tags"
append_tags:
name: "Append Tags"
replace_tags:
name: "Replace Tags"
delete_topics:
name: "Delete Topics"
update_category:
name: "Update Category"
description: "Choose the new category for the selected topics"
reset_bump_dates:
name: "Reset Bump Dates"
description: "Reset the topic bump date to the last created post date, which affects ordering in the topic list"
defer:
name: "Defer Topics"
description: "Mark topics as unread"
update_notifications:
name: "Update Notifications…"
description: "Change notification level to Watching, Tracking, Normal, or Muted"
topic:
filter_to: