Commit b9dd33c3 authored by Rubén Dávila's avatar Rubén Dávila

Merge branch '4920-count-of-users-by-role-in-admin' into 'master'

Resolve "Count of users by role in admin"

Closes #4920

See merge request gitlab-org/gitlab-ee!4539
parents 6c51dbf4 106e42b1
class Admin::DashboardController < Admin::ApplicationController
prepend ::EE::Admin::DashboardController
def index
@projects = Project.order_id_desc.without_deleted.with_route.limit(10)
@users = User.order_id_desc.limit(10)
......
class ProjectAuthorization < ActiveRecord::Base
prepend ::EE::ProjectAuthorization
belongs_to :user
belongs_to :project
......
......@@ -23,6 +23,9 @@
%h3.text-center
Users:
= number_with_delimiter(User.count)
-# EE specific
.text-center
= link_to 'Users statistics', admin_dashboard_stats_path
%hr
= link_to 'New user', new_admin_user_path, class: "btn btn-new"
.col-sm-4
......
---
title: Add users stats page for admin area with per role amount
merge_request: 4539
author:
type: changed
......@@ -138,6 +138,8 @@ namespace :admin do
get :status
end
end
get '/dashboard/stats', to: 'dashboard#stats'
## EE-specific
resources :labels
......
# rubocop:disable Gitlab/ModuleWithInstanceVariables
module EE
module Admin
module DashboardController
extend ActiveSupport::Concern
def stats
@admin_count = ::User.admins.count
@roles_count = ::ProjectAuthorization.roles_stats
end
end
end
end
module EE
module ProjectAuthorization
extend ActiveSupport::Concern
module ClassMethods
# Get amout of users with highest role they have.
# If John is developer in one project but master in another he will be
# counted once as master. This is needed to count users who don't use
# functionality available to higher roles only.
#
# Example of result:
# [{"kind"=>"guest", "amount"=>"4"},
# {"kind"=>"reporter", "amount"=>"6"},
# {"kind"=>"developer", "amount"=>"10"},
# {"kind"=>"master", "amount"=>"9"},
# {"kind"=>"owner", "amount"=>"1"}]
#
def roles_stats
connection.exec_query <<-EOF.strip_heredoc
SELECT CASE access_level
WHEN 10 THEN 'guest'
WHEN 20 THEN 'reporter'
WHEN 30 THEN 'developer'
WHEN 40 THEN 'master'
WHEN 50 THEN 'owner'
ELSE 'unknown' END
AS kind,
count(*) AS amount
FROM (
SELECT user_id, max(access_level) AS access_level
FROM #{table_name}
GROUP BY user_id
) access_per_user
GROUP BY access_level
ORDER BY access_level ASC;
EOF
end
end
end
end
- page_title 'Users statistics'
%h3 Users statistics
%table.table
%tr
%td Users total
%td
= User.count
- if @admin_count
%tr
%td Admin users
%td
= @admin_count
- if @roles_count
- @roles_count.each do |row|
%tr
%td
Users with highest role
%strong
= row['kind']
%td
= row['amount']
require 'spec_helper'
describe 'Admin Dashboard' do
describe 'Users statistic' do
before do
project1 = create(:project_empty_repo)
project1.add_reporter(create(:user))
project2 = create(:project_empty_repo)
project2.add_developer(create(:user))
# Add same user as Reporter and Developer to different projects
# and expect it to be counted once for the stats
user = create(:user)
project1.add_reporter(user)
project2.add_developer(user)
sign_in(create(:admin))
end
describe 'Roles stats' do
it 'show correct amount of users per role' do
visit admin_dashboard_stats_path
expect(page).to have_content('Admin users 1')
expect(page).to have_content('Users with highest role developer 2')
expect(page).to have_content('Users with highest role reporter 1')
end
end
end
end
require 'spec_helper'
describe ProjectAuthorization do
describe '.roles_stats' do
before do
project1 = create(:project_empty_repo)
project1.add_reporter(create(:user))
project2 = create(:project_empty_repo)
project2.add_developer(create(:user))
# Add same user as Reporter and Developer to different projects
# and expect it to be counted once for the stats
user = create(:user)
project1.add_reporter(user)
project2.add_developer(user)
end
subject { described_class.roles_stats.to_a }
it do
expect(amount_for_kind('reporter')).to eq(1)
expect(amount_for_kind('developer')).to eq(2)
expect(amount_for_kind('master')).to eq(2)
end
def amount_for_kind(access_level)
subject.find do |row|
row['kind'] == access_level
end['amount'].to_i
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment