mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: More bulk select modal enhancements (#25979)
* Add cancel button * Add loading spinner * Add toast message
This commit is contained in:
parent
38ff1a38bd
commit
6702babd5e
@ -4,6 +4,7 @@ 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 ChangeTags from "discourse/components/bulk-actions/change-tags";
|
||||||
|
import ConditionalLoadingSection from "discourse/components/conditional-loading-section";
|
||||||
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 RadioButton from "discourse/components/radio-button";
|
||||||
@ -16,9 +17,12 @@ import TagChooser from "select-kit/components/tag-chooser";
|
|||||||
|
|
||||||
export default class BulkTopicActions extends Component {
|
export default class BulkTopicActions extends Component {
|
||||||
@service router;
|
@service router;
|
||||||
|
@service toasts;
|
||||||
@tracked activeComponent = null;
|
@tracked activeComponent = null;
|
||||||
@tracked tags = [];
|
@tracked tags = [];
|
||||||
@tracked categoryId;
|
@tracked categoryId;
|
||||||
|
@tracked loading;
|
||||||
|
@tracked errors;
|
||||||
|
|
||||||
notificationLevelId = null;
|
notificationLevelId = null;
|
||||||
|
|
||||||
@ -31,18 +35,16 @@ export default class BulkTopicActions extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async perform(operation) {
|
async perform(operation) {
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
if (this.args.model.bulkSelectHelper.selected.length > 20) {
|
if (this.args.model.bulkSelectHelper.selected.length > 20) {
|
||||||
this.showProgress = true;
|
this.showProgress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this._processChunks(operation);
|
return await this._processChunks(operation);
|
||||||
} catch {
|
} catch {
|
||||||
this.dialog.alert(i18n("generic_error"));
|
this.errors = true;
|
||||||
|
this.showToast();
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
|
||||||
this.processedTopicCount = 0;
|
this.processedTopicCount = 0;
|
||||||
this.showProgress = false;
|
this.showProgress = false;
|
||||||
}
|
}
|
||||||
@ -108,6 +110,7 @@ export default class BulkTopicActions extends Component {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
performAction() {
|
performAction() {
|
||||||
|
this.loading = true;
|
||||||
switch (this.args.model.action) {
|
switch (this.args.model.action) {
|
||||||
case "close":
|
case "close":
|
||||||
this.forEachPerformed({ type: "close" }, (t) => t.set("closed", true));
|
this.forEachPerformed({ type: "close" }, (t) => t.set("closed", true));
|
||||||
@ -163,6 +166,21 @@ export default class BulkTopicActions extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showToast() {
|
||||||
|
this.loading = false;
|
||||||
|
if (this.errors) {
|
||||||
|
this.toasts.error({
|
||||||
|
duration: 3000,
|
||||||
|
data: { message: i18n("generic_error") },
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.toasts.success({
|
||||||
|
duration: 3000,
|
||||||
|
data: { message: i18n("topics.bulk.completed") },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async forEachPerformed(operation, cb) {
|
async forEachPerformed(operation, cb) {
|
||||||
const topics = await this.perform(operation);
|
const topics = await this.perform(operation);
|
||||||
@ -172,6 +190,7 @@ 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();
|
this.args.model.bulkSelectHelper.toggleBulkSelect();
|
||||||
|
this.showToast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +201,7 @@ 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();
|
this.args.model.bulkSelectHelper.toggleBulkSelect();
|
||||||
|
this.showToast();
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed("action")
|
@computed("action")
|
||||||
@ -222,45 +242,55 @@ export default class BulkTopicActions extends Component {
|
|||||||
class="topic-bulk-actions-modal -large"
|
class="topic-bulk-actions-modal -large"
|
||||||
>
|
>
|
||||||
<:body>
|
<:body>
|
||||||
<div>
|
<ConditionalLoadingSection
|
||||||
{{htmlSafe
|
@isLoading={{this.loading}}
|
||||||
(i18n
|
@title={{i18n "topics.bulk.performing"}}
|
||||||
"topics.bulk.selected"
|
>
|
||||||
count=@model.bulkSelectHelper.selected.length
|
<div>
|
||||||
)
|
{{htmlSafe
|
||||||
}}
|
(i18n
|
||||||
</div>
|
"topics.bulk.selected"
|
||||||
|
count=@model.bulkSelectHelper.selected.length
|
||||||
{{#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>
|
</div>
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if this.isTagAction}}
|
{{#if this.isCategoryAction}}
|
||||||
<p><TagChooser @tags={{this.tags}} @categoryId={{@categoryId}} /></p>
|
<p>
|
||||||
{{/if}}
|
<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}}
|
||||||
|
</ConditionalLoadingSection>
|
||||||
</:body>
|
</:body>
|
||||||
|
|
||||||
<:footer>
|
<:footer>
|
||||||
@ -277,8 +307,16 @@ export default class BulkTopicActions extends Component {
|
|||||||
/>{{i18n "topics.bulk.silent"}}</label>
|
/>{{i18n "topics.bulk.silent"}}</label>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
<DButton
|
||||||
|
@action={{@closeModal}}
|
||||||
|
@label="cancel"
|
||||||
|
class="btn-transparent d-modal-cancel"
|
||||||
|
id="bulk-topics-cancel"
|
||||||
|
/>
|
||||||
<DButton
|
<DButton
|
||||||
@action={{this.performAction}}
|
@action={{this.performAction}}
|
||||||
|
@disabled={{this.loading}}
|
||||||
@icon="check"
|
@icon="check"
|
||||||
@label="topics.bulk.confirm"
|
@label="topics.bulk.confirm"
|
||||||
id="bulk-topics-confirm"
|
id="bulk-topics-confirm"
|
||||||
|
@ -227,7 +227,7 @@
|
|||||||
p {
|
p {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
#bulk-topics-confirm {
|
#bulk-topics-cancel {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2965,6 +2965,8 @@ en:
|
|||||||
one: "Progress: <strong>%{count}</strong> topic"
|
one: "Progress: <strong>%{count}</strong> topic"
|
||||||
other: "Progress: <strong>%{count}</strong> topics"
|
other: "Progress: <strong>%{count}</strong> topics"
|
||||||
silent: "Perform this action silently."
|
silent: "Perform this action silently."
|
||||||
|
performing: "Performing bulk operations, please wait…"
|
||||||
|
completed: "Bulk operations completed successfully!"
|
||||||
|
|
||||||
none:
|
none:
|
||||||
unread: "You have no unread topics."
|
unread: "You have no unread topics."
|
||||||
|
Loading…
Reference in New Issue
Block a user