Commit 26f4ba3b authored by yo's avatar yo

Redesign admin dashboard

Finish project card

Update user stat card

Update group stat card

Add Changelog

Transparent card footer

Remove div tags

Remove href in span tag

Update Translations

Turn into white bg

Move to card for licence overview

Update licence summary and breakdown

Update Translations

Fix margins

Add separate heading

Update translations

Fix test

Fix test

Update index.html.haml_spec.rb

Update index.html.haml_spec.rb

Move to span

Fix test

Switch to col-md-4

Fix mobile view

Fix Test
parent 09c2a929
...@@ -26,8 +26,8 @@ export default { ...@@ -26,8 +26,8 @@ export default {
</script> </script>
<template> <template>
<div class="info-well"> <div class="gl-card">
<div class="well-segment admin-well admin-well-statistics"> <div class="gl-card-body">
<h4>{{ __('Statistics') }}</h4> <h4>{{ __('Statistics') }}</h4>
<gl-loading-icon v-if="isLoading" size="md" class="my-3" /> <gl-loading-icon v-if="isLoading" size="md" class="my-3" />
<template v-else> <template v-else>
......
.info-well {
.admin-well-statistics,
.admin-well-features {
padding-bottom: 46px;
}
}
.usage-data { .usage-data {
max-height: 400px; max-height: 400px;
} }
......
...@@ -15,49 +15,63 @@ ...@@ -15,49 +15,63 @@
= render_if_exists 'admin/licenses/breakdown' = render_if_exists 'admin/licenses/breakdown'
.admin-dashboard.gl-mt-3 .admin-dashboard.gl-mt-3
.h3.gl-mb-5.gl-mt-0= _('Instance overview')
.row .row
.col-sm-4 .col-md-4.gl-mb-6
.info-well.dark-well.flex-fill .gl-card
.well-segment.well-centered .gl-card-body.d-flex.justify-content-between.align-items-center.gl-p-6
= link_to admin_projects_path do %span
%h3.text-center .d-flex.align-items-center
= s_('AdminArea|Projects: %{number_of_projects}') % { number_of_projects: approximate_count_with_delimiters(@counts, Project) } = sprite_icon('project', size: 16, css_class: 'gl-text-gray-700')
%hr %h3.gl-m-0.gl-ml-3= approximate_count_with_delimiters(@counts, Project)
= link_to(s_('AdminArea|New project'), new_project_path, class: "btn gl-button btn-success gl-w-full") .gl-mt-3.text-uppercase= s_('AdminArea|Projects')
.col-sm-4 = link_to(s_('AdminArea|New project'), new_project_path, class: "btn gl-button btn-default")
.info-well.dark-well .gl-card-footer.gl-bg-transparent
.well-segment.well-centered.gl-text-center .d-flex.align-items-center
= link_to admin_users_path do = link_to(s_('AdminArea|View latest projects'), admin_projects_path)
%h3.gl-display-inline-block.gl-mb-0 = sprite_icon('angle-right', size: 12, css_class: 'gl-text-gray-700 gl-ml-2')
= s_('AdminArea|Users: %{number_of_users}') % { number_of_users: approximate_count_with_delimiters(@counts, User) } .col-md-4.gl-mb-6
.gl-card
%span.gl-outline-0.gl-ml-2{ href: "#", tabindex: "0", data: { container: "body", .gl-card-body.d-flex.justify-content-between.align-items-center.gl-p-6
toggle: "popover", %span
placement: "top", .d-flex.align-items-center
html: "true", = sprite_icon('users', size: 16, css_class: 'gl-text-gray-700')
trigger: "focus", %h3.gl-m-0.gl-ml-3= approximate_count_with_delimiters(@counts, User)
content: s_("AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}.").html_safe % { billable_users_link_start: billable_users_link_start, billable_users_link_end: '</a>'.html_safe }, %span.gl-outline-0.gl-ml-3{ tabindex: "0", data: { container: "body",
} } toggle: "popover",
= sprite_icon('question', size: 16, css_class: 'gl-text-gray-700 gl-mb-1') placement: "top",
html: "true",
%hr trigger: "focus",
.btn-group.d-flex{ role: 'group' } content: s_("AdminArea|All users created in the instance, including users who are not %{billable_users_link_start}billable users%{billable_users_link_end}.").html_safe % { billable_users_link_start: billable_users_link_start, billable_users_link_end: '</a>'.html_safe },
= link_to s_('AdminArea|New user'), new_admin_user_path, class: "btn gl-button btn-success gl-w-full" } }
= link_to s_('AdminArea|Users statistics'), admin_dashboard_stats_path, class: 'btn gl-button btn-info gl-w-full' = sprite_icon('question', size: 16, css_class: 'gl-text-gray-700')
.col-sm-4 .gl-mt-3.text-uppercase
.info-well.dark-well = s_('AdminArea|Users')
.well-segment.well-centered = link_to(s_('AdminArea|Users statistics'), admin_dashboard_stats_path, class: "text-capitalize gl-ml-2")
= link_to admin_groups_path do = link_to(s_('AdminArea|New user'), new_admin_user_path, class: "btn gl-button btn-default")
%h3.text-center .gl-card-footer.gl-bg-transparent
= s_('AdminArea|Groups: %{number_of_groups}') % { number_of_groups: approximate_count_with_delimiters(@counts, Group) } .d-flex.align-items-center
%hr = link_to(s_('AdminArea|View latest users'), admin_users_path)
= link_to s_('AdminArea|New group'), new_admin_group_path, class: "btn gl-button btn-success gl-w-full" = sprite_icon('angle-right', size: 12, css_class: 'gl-text-gray-700 gl-ml-2')
.col-md-4.gl-mb-6
.gl-card
.gl-card-body.d-flex.justify-content-between.align-items-center.gl-p-6
%span
.d-flex.align-items-center
= sprite_icon('group', size: 16, css_class: 'gl-text-gray-700')
%h3.gl-m-0.gl-ml-3= approximate_count_with_delimiters(@counts, Group)
.gl-mt-3.text-uppercase= s_('AdminArea|Projects')
= link_to(s_('AdminArea|New group'), new_admin_group_path, class: "btn gl-button btn-default")
.gl-card-footer.gl-bg-transparent
.d-flex.align-items-center
= link_to(s_('AdminArea|View latest groups'), admin_groups_path)
= sprite_icon('angle-right', size: 12, css_class: 'gl-text-gray-700 gl-ml-2')
.row .row
.col-md-4 .col-md-4.gl-mb-6
#js-admin-statistics-container #js-admin-statistics-container
.col-md-4 .col-md-4.gl-mb-6
.info-well .gl-card
.well-segment.admin-well.admin-well-features .gl-card-body
%h4= s_('AdminArea|Features') %h4= s_('AdminArea|Features')
= feature_entry(_('Sign up'), = feature_entry(_('Sign up'),
href: general_admin_application_settings_path(anchor: 'js-signup-settings'), href: general_admin_application_settings_path(anchor: 'js-signup-settings'),
...@@ -94,9 +108,9 @@ ...@@ -94,9 +108,9 @@
= feature_entry(_('Shared Runners'), = feature_entry(_('Shared Runners'),
href: admin_runners_path, href: admin_runners_path,
enabled: Gitlab.config.gitlab_ci.shared_runners_enabled) enabled: Gitlab.config.gitlab_ci.shared_runners_enabled)
.col-md-4 .col-md-4.gl-mb-6
.info-well .gl-card
.well-segment.admin-well .gl-card-body
%h4 %h4
= s_('AdminArea|Components') = s_('AdminArea|Components')
- if Gitlab::CurrentSettings.version_check_enabled - if Gitlab::CurrentSettings.version_check_enabled
...@@ -146,18 +160,18 @@ ...@@ -146,18 +160,18 @@
%p %p
= link_to _("Gitaly Servers"), admin_gitaly_servers_path = link_to _("Gitaly Servers"), admin_gitaly_servers_path
.row .row
.col-md-4 .col-md-4.gl-mb-6
.info-well .gl-card
.well-segment.admin-well .gl-card-body
%h4= s_('AdminArea|Latest projects') %h4= s_('AdminArea|Latest projects')
- @projects.each do |project| - @projects.each do |project|
%p %p
= link_to project.full_name, admin_project_path(project), class: 'str-truncated-60' = link_to project.full_name, admin_project_path(project), class: 'str-truncated-60'
%span.light.float-right %span.light.float-right
#{time_ago_with_tooltip(project.created_at)} #{time_ago_with_tooltip(project.created_at)}
.col-md-4 .col-md-4.gl-mb-6
.info-well .gl-card
.well-segment.admin-well .gl-card-body
%h4= s_('AdminArea|Latest users') %h4= s_('AdminArea|Latest users')
- @users.each do |user| - @users.each do |user|
%p %p
...@@ -165,9 +179,9 @@ ...@@ -165,9 +179,9 @@
= user.name = user.name
%span.light.float-right %span.light.float-right
#{time_ago_with_tooltip(user.created_at)} #{time_ago_with_tooltip(user.created_at)}
.col-md-4 .col-md-4.gl-mb-6
.info-well .gl-card
.well-segment.admin-well .gl-card-body
%h4= s_('AdminArea|Latest groups') %h4= s_('AdminArea|Latest groups')
- @groups.each do |group| - @groups.each do |group|
%p %p
......
---
title: Admin dashboard basic stats redesign
merge_request: 52176
author: Yogi (@yo)
type: changed
...@@ -4,46 +4,44 @@ ...@@ -4,46 +4,44 @@
- billable_users_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer nofollow">'.html_safe % { url: billable_users_url } - billable_users_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer nofollow">'.html_safe % { url: billable_users_url }
- link_end = '</a>'.html_safe - link_end = '</a>'.html_safe
.d-flex.gl-mb-5 .d-flex
.col-sm-6.d-flex.pl-0 .row
.info-well.dark-well.gl-mb-0 .col-sm-6.d-flex.gl-mb-5
.well-segment.well-centered .gl-card
%h3.center .gl-card-body
= _('Users in License:') %h2.gl-mt-0
= licensed_users(@license) = licensed_users(@license)
%hr .text-uppercase.gl-mb-4= _('Users in License')
- if @license.will_expire? - if @license.will_expire?
= _('Your license is valid from') = _('Your license is valid from')
%strong<> %strong<>
= _(' %{start} to %{end}') % { start: @license.starts_at, end: @license.expires_at } = _(' %{start} to %{end}') % { start: @license.starts_at, end: @license.expires_at }
\. \.
= _('The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal.').html_safe % { link_start: true_up_link_start, link_end: link_end } = _('The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal.').html_safe % { link_start: true_up_link_start, link_end: link_end }
= seats_calculation_message(@license) = seats_calculation_message(@license)
.col-sm-6.d-flex.pr-0 .col-sm-6.d-flex.gl-mb-5
.info-well.dark-well.gl-mb-0 .gl-card
.well-segment.well-centered .gl-card-body
%h3.center %h2.gl-mt-0
= _('Billable Users:') = number_with_delimiter @license.daily_billable_users_count
= number_with_delimiter @license.daily_billable_users_count .text-uppercase.gl-mb-4= _('Billable Users')
%hr
%p %p
= _('This is the number of %{billable_users_link_start}billable users%{link_end} on your installation, and this is the minimum number you need to purchase when you renew your license.').html_safe % { billable_users_link_start: billable_users_link_start, link_end: link_end } = _('This is the number of %{billable_users_link_start}billable users%{link_end} on your installation, and this is the minimum number you need to purchase when you renew your license.').html_safe % { billable_users_link_start: billable_users_link_start, link_end: link_end }
.d-flex.gl-pb-5 .d-flex
.col-sm-6.d-flex.pl-0 .row
.info-well.dark-well.flex-fill.gl-mb-0 .col-sm-6.d-flex.gl-mb-5
.well-segment.well-centered .gl-card.flex-fill
%h3.center .gl-card-body
= _('Maximum Users:') %h2.gl-mt-0
= number_with_delimiter @license.maximum_user_count = number_with_delimiter @license.maximum_user_count
%hr .text-uppercase.gl-mb-4= _('Maximum Users')
= _('This is the highest peak of users on your installation since the license started.') = _('This is the highest peak of users on your installation since the license started.')
.col-sm-6.d-flex.pr-0 .col-sm-6.d-flex.gl-mb-5
.info-well.dark-well.gl-mb-0 .gl-card
.well-segment.well-centered .gl-card-body
%h3.center %h2.gl-mt-0
= _('Users over License:') = number_with_delimiter users_over_license
= number_with_delimiter users_over_license .text-uppercase.gl-mb-4= _('Users over License')
%hr
- if users_over_license > 0 - if users_over_license > 0
.gl-alert.gl-alert-info.gl-mb-3{ role: 'alert' } .gl-alert.gl-alert-info.gl-mb-3{ role: 'alert' }
= sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title') = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
......
.gl-mb-5.info-well.dark-well .h3.gl-mb-5= _('License overview')
.gl-display-flex.gl-justify-content-space-between.gl-align-items-center.gl-p-5 .gl-mb-5.gl-card
.gl-display-flex.gl-justify-content-space-between.gl-align-items-center.gl-card-body
%div %div
%h4.gl-mt-0
= _('License overview')
%p.gl-mb-0 %p.gl-mb-0
= sprite_icon('license', css_class: 'gl-fill-gray-700') = sprite_icon('license', css_class: 'gl-fill-gray-700')
%span.gl-ml-3 %span.gl-ml-3
...@@ -15,4 +14,4 @@ ...@@ -15,4 +14,4 @@
%strong= @license.licensee['Name'] %strong= @license.licensee['Name']
= "(#{@license.licensee['Email']})" = "(#{@license.licensee['Email']})"
%div %div
= link_to 'View details', admin_license_path, class: "gl-button btn btn-secondary" = link_to 'View details', admin_license_path, class: "gl-button btn btn-default"
...@@ -45,7 +45,7 @@ RSpec.describe 'admin/dashboard/index.html.haml' do ...@@ -45,7 +45,7 @@ RSpec.describe 'admin/dashboard/index.html.haml' do
it 'includes license breakdown' do it 'includes license breakdown' do
render render
expect(rendered).to have_content "Users in License:" expect(rendered).to have_content "Users in License"
expect(rendered).to have_content "Billable Users" expect(rendered).to have_content "Billable Users"
expect(rendered).to have_content "Maximum Users" expect(rendered).to have_content "Maximum Users"
expect(rendered).to have_content "Users over License" expect(rendered).to have_content "Users over License"
...@@ -56,7 +56,7 @@ RSpec.describe 'admin/dashboard/index.html.haml' do ...@@ -56,7 +56,7 @@ RSpec.describe 'admin/dashboard/index.html.haml' do
it 'does not show content' do it 'does not show content' do
render render
expect(rendered).not_to have_content 'Users in License:' expect(rendered).not_to have_content "USERS IN LICENSE"
end end
end end
end end
...@@ -29,7 +29,7 @@ RSpec.describe 'admin/licenses/show.html.haml' do ...@@ -29,7 +29,7 @@ RSpec.describe 'admin/licenses/show.html.haml' do
expect(rendered).not_to have_content('Buy License') expect(rendered).not_to have_content('Buy License')
expect(rendered).to have_content('Licensed to') expect(rendered).to have_content('Licensed to')
expect(rendered).to have_content('Users in License:') expect(rendered).to have_content('Users in License')
expect(rendered).to have_content('Upload New License') expect(rendered).to have_content('Upload New License')
end end
end end
...@@ -39,7 +39,7 @@ RSpec.describe 'admin/licenses/show.html.haml' do ...@@ -39,7 +39,7 @@ RSpec.describe 'admin/licenses/show.html.haml' do
render render
expect(rendered).not_to have_content('Licensed to') expect(rendered).not_to have_content('Licensed to')
expect(rendered).not_to have_content('Users in License:') expect(rendered).not_to have_content('Users in License')
expect(rendered).to have_content('Upload New License') expect(rendered).to have_content('Upload New License')
end end
end end
......
...@@ -1927,9 +1927,6 @@ msgstr "" ...@@ -1927,9 +1927,6 @@ msgstr ""
msgid "AdminArea|Features" msgid "AdminArea|Features"
msgstr "" msgstr ""
msgid "AdminArea|Groups: %{number_of_groups}"
msgstr ""
msgid "AdminArea|Guest" msgid "AdminArea|Guest"
msgstr "" msgstr ""
...@@ -1963,7 +1960,7 @@ msgstr "" ...@@ -1963,7 +1960,7 @@ msgstr ""
msgid "AdminArea|Owner" msgid "AdminArea|Owner"
msgstr "" msgstr ""
msgid "AdminArea|Projects: %{number_of_projects}" msgid "AdminArea|Projects"
msgstr "" msgstr ""
msgid "AdminArea|Reporter" msgid "AdminArea|Reporter"
...@@ -1987,6 +1984,9 @@ msgstr "" ...@@ -1987,6 +1984,9 @@ msgstr ""
msgid "AdminArea|User cap" msgid "AdminArea|User cap"
msgstr "" msgstr ""
msgid "AdminArea|Users"
msgstr ""
msgid "AdminArea|Users statistics" msgid "AdminArea|Users statistics"
msgstr "" msgstr ""
...@@ -1996,7 +1996,13 @@ msgstr "" ...@@ -1996,7 +1996,13 @@ msgstr ""
msgid "AdminArea|Users without a Group and Project" msgid "AdminArea|Users without a Group and Project"
msgstr "" msgstr ""
msgid "AdminArea|Users: %{number_of_users}" msgid "AdminArea|View latest groups"
msgstr ""
msgid "AdminArea|View latest projects"
msgstr ""
msgid "AdminArea|View latest users"
msgstr "" msgstr ""
msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running." msgid "AdminArea|You’re about to stop all jobs.This will halt all current jobs that are running."
...@@ -4445,7 +4451,7 @@ msgstr "" ...@@ -4445,7 +4451,7 @@ msgstr ""
msgid "Bi-weekly code coverage" msgid "Bi-weekly code coverage"
msgstr "" msgstr ""
msgid "Billable Users:" msgid "Billable Users"
msgstr "" msgstr ""
msgid "Billing" msgid "Billing"
...@@ -15281,6 +15287,9 @@ msgstr "" ...@@ -15281,6 +15287,9 @@ msgstr ""
msgid "Instance administrators group already exists" msgid "Instance administrators group already exists"
msgstr "" msgstr ""
msgid "Instance overview"
msgstr ""
msgid "InstanceStatistics|Could not load the issues and merge requests chart. Please refresh the page to try again." msgid "InstanceStatistics|Could not load the issues and merge requests chart. Please refresh the page to try again."
msgstr "" msgstr ""
...@@ -17460,7 +17469,7 @@ msgstr "" ...@@ -17460,7 +17469,7 @@ msgstr ""
msgid "Maximum PyPI package file size in bytes" msgid "Maximum PyPI package file size in bytes"
msgstr "" msgstr ""
msgid "Maximum Users:" msgid "Maximum Users"
msgstr "" msgstr ""
msgid "Maximum allowable lifetime for personal access token (days)" msgid "Maximum allowable lifetime for personal access token (days)"
...@@ -31166,13 +31175,10 @@ msgstr "" ...@@ -31166,13 +31175,10 @@ msgstr ""
msgid "Users in License" msgid "Users in License"
msgstr "" msgstr ""
msgid "Users in License:"
msgstr ""
msgid "Users or groups set as approvers in the project's or merge request's settings." msgid "Users or groups set as approvers in the project's or merge request's settings."
msgstr "" msgstr ""
msgid "Users over License:" msgid "Users over License"
msgstr "" msgstr ""
msgid "Users requesting access to" msgid "Users requesting access to"
......
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