Commit 08c5fbee authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '342516-add-minimal-access-user-statistics' into 'master'

Add with_highest_role_minimal_access to statistics

See merge request gitlab-org/gitlab!73651
parents 3e554c95 15b863d0
...@@ -3,12 +3,6 @@ ...@@ -3,12 +3,6 @@
class UsersStatistics < ApplicationRecord class UsersStatistics < ApplicationRecord
scope :order_created_at_desc, -> { order(created_at: :desc) } scope :order_created_at_desc, -> { order(created_at: :desc) }
class << self
def latest
order_created_at_desc.first
end
end
def active def active
[ [
without_groups_and_projects, without_groups_and_projects,
...@@ -26,30 +20,26 @@ class UsersStatistics < ApplicationRecord ...@@ -26,30 +20,26 @@ class UsersStatistics < ApplicationRecord
end end
class << self class << self
def create_current_stats! def latest
stats_by_role = highest_role_stats order_created_at_desc.first
end
create!( def create_current_stats!
without_groups_and_projects: without_groups_and_projects_stats, create!(highest_role_stats)
with_highest_role_guest: stats_by_role[:guest],
with_highest_role_reporter: stats_by_role[:reporter],
with_highest_role_developer: stats_by_role[:developer],
with_highest_role_maintainer: stats_by_role[:maintainer],
with_highest_role_owner: stats_by_role[:owner],
bots: bot_stats,
blocked: blocked_stats
)
end end
private private
def highest_role_stats def highest_role_stats
{ {
owner: batch_count_for_access_level(Gitlab::Access::OWNER), without_groups_and_projects: without_groups_and_projects_stats,
maintainer: batch_count_for_access_level(Gitlab::Access::MAINTAINER), with_highest_role_guest: batch_count_for_access_level(Gitlab::Access::GUEST),
developer: batch_count_for_access_level(Gitlab::Access::DEVELOPER), with_highest_role_reporter: batch_count_for_access_level(Gitlab::Access::REPORTER),
reporter: batch_count_for_access_level(Gitlab::Access::REPORTER), with_highest_role_developer: batch_count_for_access_level(Gitlab::Access::DEVELOPER),
guest: batch_count_for_access_level(Gitlab::Access::GUEST) with_highest_role_maintainer: batch_count_for_access_level(Gitlab::Access::MAINTAINER),
with_highest_role_owner: batch_count_for_access_level(Gitlab::Access::OWNER),
bots: bot_stats,
blocked: blocked_stats
} }
end end
......
- page_title s_('AdminArea|Users statistics') - page_title s_('AdminArea|Users statistics')
%h3.my-4 %h3.gl-my-6
= s_('AdminArea|Users statistics') = s_('AdminArea|Users statistics')
%table.table.gl-text-gray-500 %table.table.gl-text-gray-500
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Users without a Group and Project') = s_('AdminArea|Users without a Group and Project')
= render_if_exists 'admin/dashboard/included_free_in_license_tooltip' = render_if_exists 'admin/dashboard/included_free_in_license_tooltip'
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.without_groups_and_projects.to_i = @users_statistics&.without_groups_and_projects
= render_if_exists 'admin/dashboard/minimal_access_stats_row', users_statistics: @users_statistics
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Users with highest role') = s_('AdminArea|Users with highest role')
%strong %strong
= s_('AdminArea|Guest') = s_('AdminArea|Guest')
= render_if_exists 'admin/dashboard/included_free_in_license_tooltip' = render_if_exists 'admin/dashboard/included_free_in_license_tooltip'
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.with_highest_role_guest.to_i = @users_statistics&.with_highest_role_guest
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Users with highest role') = s_('AdminArea|Users with highest role')
%strong %strong
= s_('AdminArea|Reporter') = s_('AdminArea|Reporter')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.with_highest_role_reporter.to_i = @users_statistics&.with_highest_role_reporter
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Users with highest role') = s_('AdminArea|Users with highest role')
%strong %strong
= s_('AdminArea|Developer') = s_('AdminArea|Developer')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.with_highest_role_developer.to_i = @users_statistics&.with_highest_role_developer
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Users with highest role') = s_('AdminArea|Users with highest role')
%strong %strong
= s_('AdminArea|Maintainer') = s_('AdminArea|Maintainer')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.with_highest_role_maintainer.to_i = @users_statistics&.with_highest_role_maintainer
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Users with highest role') = s_('AdminArea|Users with highest role')
%strong %strong
= s_('AdminArea|Owner') = s_('AdminArea|Owner')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.with_highest_role_owner.to_i = @users_statistics&.with_highest_role_owner
%tr %tr
%td.p-3 %td.gl-p-5!
= s_('AdminArea|Bots') = s_('AdminArea|Bots')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
= @users_statistics&.bots.to_i = @users_statistics&.bots
= render_if_exists 'admin/dashboard/billable_users_row' = render_if_exists 'admin/dashboard/billable_users_row'
%tr.bg-gray-light.gl-text-gray-900 %tr.bg-gray-light.gl-text-gray-900
%td.p-3 %td.gl-p-5!
%strong %strong
= s_('AdminArea|Active users') = s_('AdminArea|Active users')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
%strong %strong
= @users_statistics&.active.to_i = @users_statistics&.active
%tr.bg-gray-light.gl-text-gray-900 %tr.bg-gray-light.gl-text-gray-900
%td.p-3 %td.gl-p-5!
%strong %strong
= s_('AdminArea|Blocked users') = s_('AdminArea|Blocked users')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
%strong %strong
= @users_statistics&.blocked.to_i = @users_statistics&.blocked
%tr.bg-gray-light.gl-text-gray-900 %tr.bg-gray-light.gl-text-gray-900
%td.p-3 %td.gl-p-5!
%strong %strong
= s_('AdminArea|Total users') = s_('AdminArea|Total users')
%td.p-3.text-right %td.gl-text-right{ class: 'gl-p-5!' }
%strong %strong
= @users_statistics&.total.to_i = @users_statistics&.total
# frozen_string_literal: true
class AddWithHighestRoleMinimalAccessToUsersStatistics < Gitlab::Database::Migration[1.0]
def change
add_column :users_statistics, :with_highest_role_minimal_access, :integer, null: false, default: 0
end
end
a22322122144f28306b3b38dbe50b3465ad623c389f8bfe6fa97a0f71b1c7c21
\ No newline at end of file
...@@ -20289,7 +20289,8 @@ CREATE TABLE users_statistics ( ...@@ -20289,7 +20289,8 @@ CREATE TABLE users_statistics (
with_highest_role_maintainer integer DEFAULT 0 NOT NULL, with_highest_role_maintainer integer DEFAULT 0 NOT NULL,
with_highest_role_owner integer DEFAULT 0 NOT NULL, with_highest_role_owner integer DEFAULT 0 NOT NULL,
bots integer DEFAULT 0 NOT NULL, bots integer DEFAULT 0 NOT NULL,
blocked integer DEFAULT 0 NOT NULL blocked integer DEFAULT 0 NOT NULL,
with_highest_role_minimal_access integer DEFAULT 0 NOT NULL
); );
CREATE SEQUENCE users_statistics_id_seq CREATE SEQUENCE users_statistics_id_seq
...@@ -2,10 +2,18 @@ ...@@ -2,10 +2,18 @@
module EE module EE
module UsersStatistics module UsersStatistics
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
def billable def billable
(base_billable_users + guest_billable_users).sum (base_billable_users + guest_billable_users).sum
end end
override :active
def active
super + with_highest_role_minimal_access
end
private private
def base_billable_users def base_billable_users
...@@ -21,7 +29,18 @@ module EE ...@@ -21,7 +29,18 @@ module EE
if License.current&.exclude_guests_from_active_count? if License.current&.exclude_guests_from_active_count?
[] []
else else
[without_groups_and_projects, with_highest_role_guest] [without_groups_and_projects, with_highest_role_guest, with_highest_role_minimal_access]
end
end
class_methods do
extend ::Gitlab::Utils::Override
private
override :highest_role_stats
def highest_role_stats
super.merge(with_highest_role_minimal_access: batch_count_for_access_level(::Gitlab::Access::MINIMAL_ACCESS))
end end
end end
end end
......
- return unless License.feature_available?(:minimal_access_role)
- users_statistics = local_assigns.fetch(:users_statistics)
%tr
%td.gl-p-5!
= s_('AdminArea|Users with highest role')
%strong
= s_('AdminArea|Minimal access')
%td.gl-text-right{ class: 'gl-p-5!' }
= users_statistics&.with_highest_role_minimal_access
# frozen_string_literal: true
FactoryBot.modify do
factory :user_highest_role do
trait(:minimal_access) { highest_access_level { GroupMember::MINIMAL_ACCESS } }
end
end
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe UsersStatistics do RSpec.describe UsersStatistics do
let(:users_statistics) { build(:users_statistics) } let(:users_statistics) { build(:users_statistics, with_highest_role_minimal_access: 5) }
describe '#billable' do describe '#billable' do
it 'sums users statistics values excluding blocked users and bots' do it 'sums users statistics values excluding blocked users and bots' do
expect(users_statistics.billable).to eq(69) expect(users_statistics.billable).to eq(74)
end end
context 'when there is an ultimate license' do context 'when there is an ultimate license' do
...@@ -16,9 +16,29 @@ RSpec.describe UsersStatistics do ...@@ -16,9 +16,29 @@ RSpec.describe UsersStatistics do
allow(License).to receive(:current).and_return(license) allow(License).to receive(:current).and_return(license)
end end
it 'excludes blocked users, bots, guest users, and users without a group or project' do it 'excludes blocked users, bots, guest users, users without a group or project and minimal access users' do
expect(users_statistics.billable).to eq(41) expect(users_statistics.billable).to eq(41)
end end
end end
end end
describe '#active' do
it 'includes minimal access roles' do
expect(users_statistics.active).to eq(76)
end
end
describe '.create_current_stats!' do
before do
create(:user_highest_role, :minimal_access)
allow(ApplicationRecord.connection).to receive(:transaction_open?).and_return(false)
end
it 'includes minimal access in current statistics values' do
expect(described_class.create_current_stats!).to have_attributes(
with_highest_role_minimal_access: 1
)
end
end
end end
...@@ -2316,6 +2316,9 @@ msgstr "" ...@@ -2316,6 +2316,9 @@ msgstr ""
msgid "AdminArea|Maintainer" msgid "AdminArea|Maintainer"
msgstr "" msgstr ""
msgid "AdminArea|Minimal access"
msgstr ""
msgid "AdminArea|New group" msgid "AdminArea|New group"
msgstr "" msgstr ""
......
...@@ -39,7 +39,7 @@ export const member = { ...@@ -39,7 +39,7 @@ export const member = {
Developer: 30, Developer: 30,
Maintainer: 40, Maintainer: 40,
Owner: 50, Owner: 50,
'Minimal Access': 5, 'Minimal access': 5,
}, },
}; };
......
...@@ -34,11 +34,11 @@ RSpec.describe UsersStatistics do ...@@ -34,11 +34,11 @@ RSpec.describe UsersStatistics do
describe '.create_current_stats!' do describe '.create_current_stats!' do
before do before do
create_list(:user_highest_role, 4) create_list(:user_highest_role, 1)
create_list(:user_highest_role, 2, :guest) create_list(:user_highest_role, 2, :guest)
create_list(:user_highest_role, 3, :reporter) create_list(:user_highest_role, 2, :reporter)
create_list(:user_highest_role, 4, :developer) create_list(:user_highest_role, 2, :developer)
create_list(:user_highest_role, 3, :maintainer) create_list(:user_highest_role, 2, :maintainer)
create_list(:user_highest_role, 2, :owner) create_list(:user_highest_role, 2, :owner)
create_list(:user, 2, :bot) create_list(:user, 2, :bot)
create_list(:user, 1, :blocked) create_list(:user, 1, :blocked)
...@@ -49,11 +49,11 @@ RSpec.describe UsersStatistics do ...@@ -49,11 +49,11 @@ RSpec.describe UsersStatistics do
context 'when successful' do context 'when successful' do
it 'creates an entry with the current statistics values' do it 'creates an entry with the current statistics values' do
expect(described_class.create_current_stats!).to have_attributes( expect(described_class.create_current_stats!).to have_attributes(
without_groups_and_projects: 4, without_groups_and_projects: 1,
with_highest_role_guest: 2, with_highest_role_guest: 2,
with_highest_role_reporter: 3, with_highest_role_reporter: 2,
with_highest_role_developer: 4, with_highest_role_developer: 2,
with_highest_role_maintainer: 3, with_highest_role_maintainer: 2,
with_highest_role_owner: 2, with_highest_role_owner: 2,
bots: 2, bots: 2,
blocked: 1 blocked: 1
......
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