mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 13:03:44 +08:00
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:
parent
5dba5c4208
commit
368bd2697a
|
@ -1,19 +1,34 @@
|
||||||
import Component from "@glimmer/component";
|
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 { inject as service } from "@ember/service";
|
||||||
import { Promise } from "rsvp";
|
import { Promise } from "rsvp";
|
||||||
|
import ChangeTags from "discourse/components/bulk-actions/change-tags";
|
||||||
import DButton from "discourse/components/d-button";
|
import DButton from "discourse/components/d-button";
|
||||||
import DModal from "discourse/components/d-modal";
|
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 Topic from "discourse/models/topic";
|
||||||
import htmlSafe from "discourse-common/helpers/html-safe";
|
import htmlSafe from "discourse-common/helpers/html-safe";
|
||||||
import i18n from "discourse-common/helpers/i18n";
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
//import AppendTags from "../bulk-actions/append-tags";
|
import CategoryChooser from "select-kit/components/category-chooser";
|
||||||
//import ChangeCategory from "../bulk-actions/change-category";
|
import TagChooser from "select-kit/components/tag-chooser";
|
||||||
//import ChangeTags from "../bulk-actions/change-tags";
|
|
||||||
//import NotificationLevel from "../bulk-actions/notification-level";
|
|
||||||
|
|
||||||
export default class BulkTopicActions extends Component {
|
export default class BulkTopicActions extends Component {
|
||||||
@service router;
|
@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) {
|
async perform(operation) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
|
@ -25,7 +40,7 @@ export default class BulkTopicActions extends Component {
|
||||||
try {
|
try {
|
||||||
return this._processChunks(operation);
|
return this._processChunks(operation);
|
||||||
} catch {
|
} catch {
|
||||||
this.dialog.alert(i18n.t("generic_error"));
|
this.dialog.alert(i18n("generic_error"));
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.processedTopicCount = 0;
|
this.processedTopicCount = 0;
|
||||||
|
@ -97,6 +112,54 @@ export default class BulkTopicActions extends Component {
|
||||||
case "close":
|
case "close":
|
||||||
this.forEachPerformed({ type: "close" }, (t) => t.set("closed", true));
|
this.forEachPerformed({ type: "close" }, (t) => t.set("closed", true));
|
||||||
break;
|
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.model.refreshClosure?.();
|
||||||
this.args.closeModal();
|
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>
|
<template>
|
||||||
|
@ -128,8 +223,44 @@ export default class BulkTopicActions extends Component {
|
||||||
>
|
>
|
||||||
<:body>
|
<:body>
|
||||||
<div>
|
<div>
|
||||||
{{htmlSafe (i18n "topics.bulk.selected" count=@model.topics.length)}}
|
{{htmlSafe
|
||||||
|
(i18n
|
||||||
|
"topics.bulk.selected"
|
||||||
|
count=@model.bulkSelectHelper.selected.length
|
||||||
|
)
|
||||||
|
}}
|
||||||
</div>
|
</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>
|
</:body>
|
||||||
|
|
||||||
<:footer>
|
<:footer>
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
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 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 i18n from "discourse-common/helpers/i18n";
|
||||||
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
import DropdownSelectBoxComponent from "select-kit/components/dropdown-select-box";
|
||||||
|
|
||||||
|
@ -18,6 +16,8 @@ export default DropdownSelectBoxComponent.extend({
|
||||||
|
|
||||||
modal: service(),
|
modal: service(),
|
||||||
router: service(),
|
router: service(),
|
||||||
|
currentUser: service(),
|
||||||
|
siteSettings: service(),
|
||||||
|
|
||||||
computeContent() {
|
computeContent() {
|
||||||
let options = [];
|
let options = [];
|
||||||
|
@ -28,41 +28,152 @@ export default DropdownSelectBoxComponent.extend({
|
||||||
name: i18n("topic_bulk_actions.update_category.name"),
|
name: i18n("topic_bulk_actions.update_category.name"),
|
||||||
description: i18n("topic_bulk_actions.update_category.description"),
|
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",
|
id: "close-topics",
|
||||||
icon: "lock",
|
icon: "lock",
|
||||||
name: i18n("topic_bulk_actions.close_topics.name"),
|
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
|
@action
|
||||||
onSelect(id) {
|
onSelect(id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case "update-category":
|
case "update-category":
|
||||||
// Temporary: just use the existing modal & action
|
this.showBulkTopicActionsModal(id, "change_category");
|
||||||
this.modal.show(TopicBulkActions, {
|
break;
|
||||||
model: {
|
case "update-notifications":
|
||||||
topics: this.bulkSelectHelper.selected,
|
this.showBulkTopicActionsModal(id, "notification_level");
|
||||||
category: this.category,
|
|
||||||
refreshClosure: () => this.router.refresh(),
|
|
||||||
initialAction: "set-component",
|
|
||||||
initialComponent: ChangeCategory,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case "close-topics":
|
case "close-topics":
|
||||||
this.modal.show(BulkTopicActions, {
|
this.showBulkTopicActionsModal("close", "close_topics", {
|
||||||
model: {
|
allowSilent: true,
|
||||||
action: "close",
|
|
||||||
title: i18n("topics.bulk.close_topics"),
|
|
||||||
bulkSelectHelper: this.bulkSelectHelper,
|
|
||||||
refreshClosure: () => this.router.refresh(),
|
|
||||||
allowSilent: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -2997,9 +2997,32 @@ en:
|
||||||
topic_bulk_actions:
|
topic_bulk_actions:
|
||||||
close_topics:
|
close_topics:
|
||||||
name: "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:
|
update_category:
|
||||||
name: "Update Category"
|
name: "Update Category"
|
||||||
description: "Choose the new category for the selected topics"
|
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:
|
topic:
|
||||||
filter_to:
|
filter_to:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user