diff --git a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js index b9492e30af4..93ed9c306f1 100644 --- a/app/assets/javascripts/admin/addon/controllers/admin-user-index.js +++ b/app/assets/javascripts/admin/addon/controllers/admin-user-index.js @@ -11,7 +11,7 @@ import discourseComputed from "discourse-common/utils/decorators"; import getURL from "discourse-common/lib/get-url"; import { htmlSafe } from "@ember/template"; import { iconHTML } from "discourse-common/lib/icon-library"; -import { popupAjaxError } from "discourse/lib/ajax-error"; +import { extractError, popupAjaxError } from "discourse/lib/ajax-error"; import { inject as service } from "@ember/service"; import showModal from "discourse/lib/show-modal"; @@ -272,73 +272,6 @@ export default Controller.extend(CanCheckEmails, { silence() { return this.model.silence(); }, - deleteAllPosts() { - let deletedPosts = 0; - let deletedPercentage = 0; - const user = this.model; - const message = I18n.messageFormat( - "admin.user.delete_all_posts_confirm_MF", - { - POSTS: user.get("post_count"), - TOPICS: user.get("topic_count"), - } - ); - - const performDelete = (progressModal) => { - this.model - .deleteAllPosts() - .then(({ posts_deleted }) => { - if (posts_deleted === 0) { - user.set("post_count", 0); - progressModal.send("closeModal"); - } else { - deletedPosts += posts_deleted; - deletedPercentage = Math.floor( - (deletedPosts * 100) / user.get("post_count") - ); - progressModal.setProperties({ - deletedPercentage: deletedPercentage, - }); - performDelete(progressModal); - } - }) - .catch((e) => { - progressModal.send("closeModal"); - let error; - AdminUser.find(user.get("id")).then((u) => user.setProperties(u)); - if (e.jqXHR.responseJSON && e.jqXHR.responseJSON.errors) { - error = e.jqXHR.responseJSON.errors[0]; - } - error = error || I18n.t("admin.user.delete_posts_failed"); - bootbox.alert(error); - }); - }; - - const buttons = [ - { - label: I18n.t("composer.cancel"), - class: "d-modal-cancel", - link: true, - }, - { - icon: iconHTML("exclamation-triangle"), - label: I18n.t("admin.user.delete_all_posts"), - class: "btn btn-danger", - callback: () => { - const progressModal = openProgressModal(); - performDelete(progressModal); - }, - }, - ]; - - const openProgressModal = () => { - return showModal("admin-delete-user-posts-progress", { - admin: true, - }); - }; - - bootbox.dialog(message, buttons, { classes: "delete-all-posts" }); - }, anonymize() { const user = this.model; @@ -626,5 +559,50 @@ export default Controller.extend(CanCheckEmails, { } }); }, + + showDeletePostsConfirmation() { + showModal("admin-delete-posts-confirmation", { + admin: true, + model: this.model, + }); + }, + + deleteAllPosts() { + let deletedPosts = 0; + let deletedPercentage = 0; + const user = this.model; + + const performDelete = (progressModal) => { + this.model + .deleteAllPosts() + .then(({ posts_deleted }) => { + if (posts_deleted === 0) { + user.set("post_count", 0); + progressModal.send("closeModal"); + } else { + deletedPosts += posts_deleted; + deletedPercentage = Math.floor( + (deletedPosts * 100) / user.get("post_count") + ); + progressModal.setProperties({ + deletedPercentage: deletedPercentage, + }); + performDelete(progressModal); + } + }) + .catch((e) => { + progressModal.send("closeModal"); + let error; + AdminUser.find(user.get("id")).then((u) => user.setProperties(u)); + error = extractError(e) || I18n.t("admin.user.delete_posts_failed"); + bootbox.alert(error); + }); + }; + + const progressModal = showModal("admin-delete-user-posts-progress", { + admin: true, + }); + performDelete(progressModal); + }, }, }); diff --git a/app/assets/javascripts/admin/addon/controllers/modals/admin-delete-posts-confirmation.js b/app/assets/javascripts/admin/addon/controllers/modals/admin-delete-posts-confirmation.js new file mode 100644 index 00000000000..106b459f0ce --- /dev/null +++ b/app/assets/javascripts/admin/addon/controllers/modals/admin-delete-posts-confirmation.js @@ -0,0 +1,46 @@ +import Controller, { inject as controller } from "@ember/controller"; +import I18n from "I18n"; +import ModalFunctionality from "discourse/mixins/modal-functionality"; +import { action } from "@ember/object"; +import { alias } from "@ember/object/computed"; +import discourseComputed from "discourse-common/utils/decorators"; + +export default Controller.extend(ModalFunctionality, { + adminUserIndex: controller(), + username: alias("model.username"), + postCount: alias("model.post_count"), + + onShow() { + this.set("value", null); + }, + + @discourseComputed("username", "postCount") + text(username, postCount) { + return I18n.t(`admin.user.delete_posts.confirmation.text`, { + username, + postCount, + }); + }, + + @discourseComputed("username") + deleteButtonText(username) { + return I18n.t(`admin.user.delete_posts.confirmation.delete`, { + username, + }); + }, + + @discourseComputed("value", "text") + deleteDisabled(value, text) { + return !value || text !== value; + }, + + @action + confirm() { + this.adminUserIndex.send("deleteAllPosts"); + }, + + @action + close() { + this.send("closeModal"); + }, +}); diff --git a/app/assets/javascripts/admin/addon/templates/modal/admin-delete-posts-confirmation.hbs b/app/assets/javascripts/admin/addon/templates/modal/admin-delete-posts-confirmation.hbs new file mode 100644 index 00000000000..9c5cb275c3b --- /dev/null +++ b/app/assets/javascripts/admin/addon/templates/modal/admin-delete-posts-confirmation.hbs @@ -0,0 +1,20 @@ +
{{html-safe (i18n "admin.user.delete_posts.confirmation.description" username=username post_count=postCount text=text)}}
+ {{input type="text" value=value}} + {{/d-modal-body}} + + +{{I18n "admin.user.delete_posts_progress"}}
+{{I18n "admin.user.delete_posts.progress.description"}}
{{/d-modal-body}} diff --git a/app/assets/javascripts/admin/addon/templates/user-index.hbs b/app/assets/javascripts/admin/addon/templates/user-index.hbs index 17350dc1f0f..d81aeb21f46 100644 --- a/app/assets/javascripts/admin/addon/templates/user-index.hbs +++ b/app/assets/javascripts/admin/addon/templates/user-index.hbs @@ -599,9 +599,9 @@ {{#if model.post_count}} {{d-button class="btn-danger" - action=(action "deleteAllPosts") + action=(action "showDeletePostsConfirmation") icon="far-trash-alt" - label="admin.user.delete_all_posts"}} + label="admin.user.delete_posts.button"}} {{/if}} {{else}} {{deleteAllPostsExplanation}} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index fcbb059ecc5..96aba1a02ce 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -4878,8 +4878,7 @@ en: silence_message_placeholder: "(leave blank to send default message)" suspended_until: "(until %{until})" cant_suspend: "This user cannot be suspended." - delete_all_posts: "Delete all posts" - delete_posts_progress: "Deleting posts..." + delete_posts_failed: "There was a problem deleting the posts." post_edits: "Post Edits" view_edits: "View Edits" @@ -4948,8 +4947,22 @@ en: anonymize_failed: "There was a problem anonymizing the account." delete: "Delete User" delete_posts: + button: "Delete all posts" progress: title: "Progress of deleting posts" + description: "Deleting posts..." + confirmation: + title: "Delete all posts by @%{username}" + description: | +Are you sure you would like to delete %{post_count} posts by @%{username}? + +
This can not be undone!
+ +To continue type: %{text}