diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index ebccb1ea8ddbde4d2f327fc865c3c7e6fe616308..8a0134af94d71a4a828a28cc5779de8362fd9b71 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -139,28 +139,4 @@ $(document).on('ready', function() { $('.js-first-visit-notice').on('close.bs.alert', async () => { document.cookie = 'dismiss_fvn=true; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT'; }); - - - $('.js-role-grant-btn').on("click", (e) => { - const $this = $(e.target); - - $.ajax({ - 'type': 'POST', - 'url': '/users/' + $this.attr("data-user") + "/mod/toggle-role", - 'data': { role: $this.attr("data-toggle") }, - 'target': $this - }) - .done((response) => { - if (response.status !== 'success') { - QPixel.createNotification('danger', '<strong>Failed:</strong> ' + response.message); - } - else { - window.location.reload(); - } - }) - .fail((jqXHR, textStatus, errorThrown) => { - QPixel.createNotification('danger', '<strong>Failed:</strong> ' + jqXHR.status); - console.log(jqXHR.responseText); - }); - }); }); diff --git a/app/assets/javascripts/users.js b/app/assets/javascripts/users.js index 38f6bdade42f4b878213c6d2880170e122a6420f..a818d04667118b8cde59ad2a7e4aa948ffca40da 100644 --- a/app/assets/javascripts/users.js +++ b/app/assets/javascripts/users.js @@ -3,4 +3,21 @@ $(() => { $('input[type="submit"]').attr('disabled', true).addClass('is-muted is-outlined'); $('.js-errors').text('Cookies must be enabled in your browser for you to be able to sign up or sign in.'); } + + $('.js-role-grant-btn').on('click', async ev => { + const $tgt = $(ev.target); + const resp = await fetch(`/users/${$tgt.attr('data-user')}/mod/toggle-role`, { + method: 'POST', + body: JSON.stringify({ role: $tgt.attr('data-role') }), + headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': QPixel.csrfToken() }, + credentials: 'include' + }); + const data = await resp.json(); + if (resp.status !== 200 || data.status !== 'success') { + QPixel.createNotification('danger', `<strong>Failed:</strong> ${data.message}`); + } + else { + location.reload(); + } + }); }); \ No newline at end of file diff --git a/app/assets/stylesheets/users.scss b/app/assets/stylesheets/users.scss index 977e467460764ee869b5f40acb327d7eb71935cc..af3d4ee296740d92abd5dec9b161924060133d6d 100644 --- a/app/assets/stylesheets/users.scss +++ b/app/assets/stylesheets/users.scss @@ -55,10 +55,17 @@ flex-grow: 1; padding: 1em; border-right: 1px solid #ddd; + h1 { word-wrap: break-word; overflow: auto; margin: 0; + display: flex; + align-items: center; + + > * { + margin: 0 0.2em; + } } } .user-profile--sidebar { @@ -101,8 +108,7 @@ .user-profile--name { flex-grow: 0; border-right: 0; - padding: 0.5em; - padding-right: 0; + padding: 0.5em 0 0.5em 0.5em; } .user-profile--sidebar { @@ -117,4 +123,11 @@ .profile-text { max-height: none; } +} + +.staff-badge { + display: inline-block !important; + padding: 3px 6px !important; + border-radius: 2px !important; + font-weight: 700 !important; } \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index cd2a0c32398d3ad5b245189e06049a7e3a48a2a9..908e23793bc3b2535fa6f84618753a7e0cdcb781 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,6 +1,4 @@ require 'net/http' - -# rubocop:disable Metrics/ClassLength class UsersController < ApplicationController before_action :authenticate_user!, only: [:edit_profile, :update_profile, :stack_redirect, :transfer_se_content, :qr_login_code, :me] @@ -228,50 +226,27 @@ class UsersController < ApplicationController end end - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/CyclomaticComplexity def role_toggle - if params[:role] == 'mod' - @user.community_user.update(is_moderator: !@user.is_moderator) - AuditLog.admin_audit(event_type: 'role_toggle', related: @user, user: current_user, - comment: "moderator to #{@user.is_moderator}") - render json: { status: 'success' } && return + role_map = { mod: :is_moderator, admin: :is_admin, mod_global: :is_global_moderator, admin_global: :is_global_admin, + staff: :staff } + unless role_map.keys.include?(params[:role].underscore.to_sym) + render json: { status: 'error', message: "Role not found: #{params[:role]}" }, status: 400 end - if current_user.is_global_admin - if params[:role] == 'admin' - @user.community_user.update(is_admin: !@user.is_admin) - AuditLog.admin_audit(event_type: 'role_toggle', related: @user, user: current_user, - comment: "admin to #{@user.is_admin}") - render json: { status: 'success' } && return - end - - if params[:role] == 'mod-global' - @user.update(is_global_moderator: !@user.is_global_moderator) - AuditLog.admin_audit(event_type: 'role_toggle', related: @user, user: current_user, - comment: "global mod to #{@user.is_global_moderator}") - render json: { status: 'success' } && return - end - - if params[:role] == 'admin-global' - @user.update(is_global_admin: true) - AuditLog.admin_audit(event_type: 'role_toggle', related: @user, user: current_user, - comment: "global admin to #{@user.is_global_admin}") - render json: { status: 'success' } && return - end - - if params[:role] == 'staff' - @user.update(staff: !@user.staff) - AuditLog.admin_audit(event_type: 'role_toggle', related: @user, user: current_user, - comment: "staff to #{@user.staff}") - render json: { status: 'success' } && return - end + key = params[:role].underscore.to_sym + attrib = role_map[key] + if [:mod, :admin].include? key + new_value = !@user.community_user.send(attrib) + @user.community_user.update(attrib => new_value) + else + new_value = !@user.send(attrib) + @user.update(attrib => new_value) end + AuditLog.admin_audit(event_type: 'role_toggle', related: @user, user: current_user, + comment: "#{attrib} to #{new_value}") - render json: { status: 'error', message: "Role not found: #{params[:role]}" } + render json: { status: 'success' } end - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity def stack_redirect response = Net::HTTP.post_form(URI('https://stackoverflow.com/oauth/access_token/json'), @@ -365,4 +340,3 @@ class UsersController < ApplicationController User.joins(:community_user).includes(:community_user, :avatar_attachment) end end -# rubocop:enable Metrics/ClassLength diff --git a/app/views/users/mod.html.erb b/app/views/users/mod.html.erb index 94b5d8ab37b5a1772f51d1ac690e0e22042dc1f2..a9fd72324fcf01a2a2769363ed4c88d639f5a629 100644 --- a/app/views/users/mod.html.erb +++ b/app/views/users/mod.html.erb @@ -20,22 +20,22 @@ <div class="widget--header">Granting / revoking special permissions</div> <div class="widget--body"> <p>You can grant or revoke special user permissions to this user.</p> - <% if @user.is_moderator %> - <button class="button is-filled js-role-grant-btn" data-toggle="mod" data-user="<%= @user.id %>">Revoke Moderator</button> + <% if @user.community_user.is_moderator %> + <button class="button is-filled js-role-grant-btn" data-role="mod" data-user="<%= @user.id %>">Revoke Moderator</button> <% else %> - <button class="button is-outlined js-role-grant-btn" data-toggle="mod" data-user="<%= @user.id %>">Grant Moderator</button> + <button class="button is-outlined js-role-grant-btn" data-role="mod" data-user="<%= @user.id %>">Grant Moderator</button> <% end %> <% if @current_user.is_global_admin %> - <% if @user.is_admin %> - <button class="button is-filled js-role-grant-btn" data-toggle="admin" data-user="<%= @user.id %>">Revoke Admin</button> + <% if @user.community_user.is_admin %> + <button class="button is-filled js-role-grant-btn" data-role="admin" data-user="<%= @user.id %>">Revoke Admin</button> <% else %> - <button class="button is-outlined js-role-grant-btn" data-toggle="admin" data-user="<%= @user.id %>">Grant Admin</button> + <button class="button is-outlined js-role-grant-btn" data-role="admin" data-user="<%= @user.id %>">Grant Admin</button> <% end %> <% if @user.is_global_moderator %> - <button class="button is-filled js-role-grant-btn" data-toggle="mod-global" data-user="<%= @user.id %>">Revoke Global Moderator</button> + <button class="button is-filled js-role-grant-btn" data-role="mod-global" data-user="<%= @user.id %>">Revoke Global Moderator</button> <% else %> - <button class="button is-outlined js-role-grant-btn" data-toggle="mod-global" data-user="<%= @user.id %>">Grant Gobal Moderator</button> + <button class="button is-outlined js-role-grant-btn" data-role="mod-global" data-user="<%= @user.id %>">Grant Global Moderator</button> <% end %> <p> @@ -44,9 +44,9 @@ </p> <% if @user.is_global_admin %> - <button class="button is-muted is-filled" disabled>This user is a Global Admin</button> + <button class="button is-filled js-role-grant-btn" data-role="admin-global" data-user="<%= @user.id %>">Revoke Global Admin</button> <% else %> - <button class="button is-outlined js-role-grant-btn" data-toggle="admin-global" data-user="<%= @user.id %>">Grant Gobal Admin</button> + <button class="button is-outlined js-role-grant-btn" data-role="admin-global" data-user="<%= @user.id %>">Grant Global Admin</button> <% end %> <p> @@ -54,10 +54,10 @@ to help others identify who's who. </p> - <% if @user.is_global_moderator %> - <button class="button is-filled js-role-grant-btn" data-toggle="staff" data-user="<%= @user.id %>">Revoke Staff</button> + <% if @user.staff? %> + <button class="button is-filled js-role-grant-btn" data-role="staff" data-user="<%= @user.id %>">Revoke Staff</button> <% else %> - <button class="button is-outlined js-role-grant-btn" data-toggle="staff" data-user="<%= @user.id %>">Grant Staff</button> + <button class="button is-outlined js-role-grant-btn" data-role="staff" data-user="<%= @user.id %>">Grant Staff</button> <% end %> <% end %> </div> diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 5e85b232612a28167584fab0e4eb8eaf92e03d0b..c08c01bbb4b6ced9c719e6cf4fd143f94b870efd 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -26,12 +26,12 @@ <h1> <%= @user.username %> <% if @user.is_admin && SiteSetting['AdminBadgeCharacter'] %> - <span class="badge is-user-role"><%= SiteSetting['AdminBadgeCharacter'] %></span> + <span class="badge is-user-role" title="Administrator"><%= SiteSetting['AdminBadgeCharacter'] %></span> <% elsif @user.is_moderator && SiteSetting['ModBadgeCharacter'] %> - <span class="badge is-user-role"><%= SiteSetting['ModBadgeCharacter'] %></span> + <span class="badge is-user-role" title="Moderator"><%= SiteSetting['ModBadgeCharacter'] %></span> <% end %> <% if @user.staff? %> - <span class="badge is-tag is-green">staff</span> + <span class="badge is-tag is-filled is-green staff-badge">staff</span> <% end %> </h1> <div class="profile-text">