Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
15b863d0
Commit
15b863d0
authored
Nov 11, 2021
by
Ammar Alakkad
Committed by
Enrique Alcántara
Nov 11, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add with_highest_role_minimal_access to statistics
Changelog: other
parent
1daa906e
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
154 additions
and
70 deletions
+154
-70
app/models/users_statistics.rb
app/models/users_statistics.rb
+13
-23
app/views/admin/dashboard/stats.html.haml
app/views/admin/dashboard/stats.html.haml
+32
-31
db/migrate/20211103062728_add_with_highest_role_minimal_access_to_users_statistics.rb
...d_with_highest_role_minimal_access_to_users_statistics.rb
+7
-0
db/schema_migrations/20211103062728
db/schema_migrations/20211103062728
+1
-0
db/structure.sql
db/structure.sql
+2
-1
ee/app/models/ee/users_statistics.rb
ee/app/models/ee/users_statistics.rb
+20
-1
ee/app/views/admin/dashboard/_minimal_access_stats_row.html.haml
...views/admin/dashboard/_minimal_access_stats_row.html.haml
+11
-0
ee/spec/factories/user_highest_roles.rb
ee/spec/factories/user_highest_roles.rb
+7
-0
ee/spec/models/ee/users_statistics_spec.rb
ee/spec/models/ee/users_statistics_spec.rb
+44
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/factories/user_highest_roles.rb
spec/factories/user_highest_roles.rb
+5
-5
spec/frontend/members/mock_data.js
spec/frontend/members/mock_data.js
+1
-1
spec/models/users_statistics_spec.rb
spec/models/users_statistics_spec.rb
+8
-8
No files found.
app/models/users_statistics.rb
View file @
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
...
...
app/views/admin/dashboard/stats.html.haml
View file @
15b863d0
-
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
db/migrate/20211103062728_add_with_highest_role_minimal_access_to_users_statistics.rb
0 → 100644
View file @
15b863d0
# 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
db/schema_migrations/20211103062728
0 → 100644
View file @
15b863d0
a22322122144f28306b3b38dbe50b3465ad623c389f8bfe6fa97a0f71b1c7c21
\ No newline at end of file
db/structure.sql
View file @
15b863d0
...
@@ -20277,7 +20277,8 @@ CREATE TABLE users_statistics (
...
@@ -20277,7 +20277,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
ee/app/models/ee/users_statistics.rb
View file @
15b863d0
...
@@ -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
...
...
ee/app/views/admin/dashboard/_minimal_access_stats_row.html.haml
0 → 100644
View file @
15b863d0
-
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
ee/spec/factories/user_highest_roles.rb
0 → 100644
View file @
15b863d0
# frozen_string_literal: true
FactoryBot
.
modify
do
factory
:user_highest_role
do
trait
(
:minimal_access
)
{
highest_access_level
{
GroupMember
::
MINIMAL_ACCESS
}
}
end
end
ee/spec/models/users_statistics_spec.rb
→
ee/spec/models/
ee/
users_statistics_spec.rb
View file @
15b863d0
...
@@ -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
locale/gitlab.pot
View file @
15b863d0
...
@@ -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 ""
...
...
spec/factories/user_highest_roles.rb
View file @
15b863d0
...
@@ -5,10 +5,10 @@ FactoryBot.define do
...
@@ -5,10 +5,10 @@ FactoryBot.define do
highest_access_level
{
nil
}
highest_access_level
{
nil
}
user
user
trait
(
:guest
)
{
highest_access_level
{
GroupMember
::
GUEST
}
}
trait
(
:guest
)
{
highest_access_level
{
GroupMember
::
GUEST
}
}
trait
(
:reporter
)
{
highest_access_level
{
GroupMember
::
REPORTER
}
}
trait
(
:reporter
)
{
highest_access_level
{
GroupMember
::
REPORTER
}
}
trait
(
:developer
)
{
highest_access_level
{
GroupMember
::
DEVELOPER
}
}
trait
(
:developer
)
{
highest_access_level
{
GroupMember
::
DEVELOPER
}
}
trait
(
:maintainer
)
{
highest_access_level
{
GroupMember
::
MAINTAINER
}
}
trait
(
:maintainer
)
{
highest_access_level
{
GroupMember
::
MAINTAINER
}
}
trait
(
:owner
)
{
highest_access_level
{
GroupMember
::
OWNER
}
}
trait
(
:owner
)
{
highest_access_level
{
GroupMember
::
OWNER
}
}
end
end
end
end
spec/frontend/members/mock_data.js
View file @
15b863d0
...
@@ -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
A
ccess
'
:
5
,
'
Minimal
a
ccess
'
:
5
,
},
},
};
};
...
...
spec/models/users_statistics_spec.rb
View file @
15b863d0
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment