diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 1b38381ce..1738481cf 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -29,6 +29,17 @@ module Admin Audit::Logger.log(:moderator, current_user, params.dup) end + # Having this method here (which also exists in admin/application_controller) + # allows us to authorize the moderator role specifically for the user_status + # action, while preserving the implementation for all other admin actions + def authorize_admin + if action_name == "user_status" + authorize(User, :toggle_suspension_status?) + else + super + end + end + def index @users = Admin::UsersQuery.call( relation: User.registered, @@ -104,18 +115,33 @@ module Admin begin Moderator::ManageActivityAndRoles.handle_user_roles(admin: current_user, user: @user, user_params: user_params) flash[:success] = I18n.t("admin.users_controller.updated") + respond_to do |format| + format.html do + redirect_back_or_to admin_users_path + end + format.json do + render json: { + success: true, + message: I18n.t("admin.users_controller.updated_json", username: @user.username) + }, status: :ok + end + end rescue StandardError => e flash[:danger] = e.message + respond_to do |format| + format.html do + redirect_back_or_to admin_users_path + end + format.json do + render json: { + success: false, + message: @user.errors_as_sentence + }, status: :unprocessable_entity + end + end end - Credits::Manage.call(@user, credit_params) add_note if user_params[:new_note] - - if request.referer&.include?(admin_user_path(params[:id])) - redirect_to admin_user_path(params[:id]) - else - redirect_to admin_users_path - end end def export_data diff --git a/app/javascript/actionsPanel/actionsPanel.js b/app/javascript/actionsPanel/actionsPanel.js index 1f37610a5..b40cda99d 100644 --- a/app/javascript/actionsPanel/actionsPanel.js +++ b/app/javascript/actionsPanel/actionsPanel.js @@ -1,4 +1,5 @@ import { toggleFlagUserModal } from '../packs/flagUserModal'; +import { toggleModal } from '../packs/toggleUserSuspensionModal'; import { toggleUnpublishPostModal } from '../packs/unpublishPostModal'; import { request } from '@utilities/http'; @@ -395,6 +396,14 @@ export function addBottomActionsListeners() { document .getElementById('open-flag-user-modal') .addEventListener('click', toggleFlagUserModal); + + document + .getElementById('suspend-user-btn') + ?.addEventListener('click', toggleModal); + + document + .getElementById('unsuspend-user-btn') + ?.addEventListener('click', toggleModal); } export function initializeActionsPanel() { diff --git a/app/javascript/article-form/components/Help/BasicEditor.jsx b/app/javascript/article-form/components/Help/BasicEditor.jsx index a25ece38e..da47dd8be 100644 --- a/app/javascript/article-form/components/Help/BasicEditor.jsx +++ b/app/javascript/article-form/components/Help/BasicEditor.jsx @@ -31,5 +31,5 @@ export const BasicEditor = ({ openModal }) => ( ); BasicEditor.propTypes = { - toggleModal: PropTypes.func.isRequired, + openModal: PropTypes.func.isRequired, }; diff --git a/app/javascript/crayons/Modal/Modal.jsx b/app/javascript/crayons/Modal/Modal.jsx index b26d710a4..9da5e2145 100644 --- a/app/javascript/crayons/Modal/Modal.jsx +++ b/app/javascript/crayons/Modal/Modal.jsx @@ -20,6 +20,7 @@ export const Modal = ({ backdropDismissible = false, onClose = () => {}, focusTrapSelector = '.crayons-modal__box', + document = window.document, }) => { const classes = classNames('crayons-modal', { [`crayons-modal--${size}`]: size && size !== 'medium', @@ -36,6 +37,7 @@ export const Modal = ({ onDeactivate={onClose} clickOutsideDeactivates={backdropDismissible} selector={focusTrapSelector} + document={document} >
+ <%= t("views.moderations.actions.suspend.suspend_modal_text", username: author_username) %> +
+ ++
++ <%= t("views.moderations.actions.suspend.unsuspend_modal_text", username: author_username) %> +
+ ++
+