Commit 076d6356 authored by Martin Wortschack's avatar Martin Wortschack

Merge branch...

Merge branch 'display-banner-warning-admin-when-the-licensed-user-count-has-been-exceeded-215959' into 'master'

Display banner to admins when there are users over license

See merge request gitlab-org/gitlab!30813
parents 4c5b344d 6d66d9d6
...@@ -111,6 +111,9 @@ function deferredInitialisation() { ...@@ -111,6 +111,9 @@ function deferredInitialisation() {
const recoverySettingsCallout = document.querySelector('.js-recovery-settings-callout'); const recoverySettingsCallout = document.querySelector('.js-recovery-settings-callout');
PersistentUserCallout.factory(recoverySettingsCallout); PersistentUserCallout.factory(recoverySettingsCallout);
const usersOverLicenseCallout = document.querySelector('.js-users-over-license-callout');
PersistentUserCallout.factory(usersOverLicenseCallout);
if (document.querySelector('.search')) initSearchAutocomplete(); if (document.querySelector('.search')) initSearchAutocomplete();
addSelectOnFocusBehaviour('.js-select-on-focus'); addSelectOnFocusBehaviour('.js-select-on-focus');
......
...@@ -18,6 +18,11 @@ export default class PersistentUserCallout { ...@@ -18,6 +18,11 @@ export default class PersistentUserCallout {
init() { init() {
const closeButton = this.container.querySelector('.js-close'); const closeButton = this.container.querySelector('.js-close');
if (!closeButton) {
return;
}
closeButton.addEventListener('click', event => this.dismiss(event)); closeButton.addEventListener('click', event => this.dismiss(event));
if (this.deferLinks) { if (this.deferLinks) {
......
...@@ -54,6 +54,10 @@ module ApplicationHelper ...@@ -54,6 +54,10 @@ module ApplicationHelper
args.any? { |v| v.to_s.downcase == action_name } args.any? { |v| v.to_s.downcase == action_name }
end end
def admin_section?
controller.class.ancestors.include?(Admin::ApplicationController)
end
def last_commit(project) def last_commit(project)
if project.repo_exists? if project.repo_exists?
time_ago_with_tooltip(project.repository.commit.committed_date) time_ago_with_tooltip(project.repository.commit.committed_date)
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
.mobile-overlay .mobile-overlay
.alert-wrapper .alert-wrapper
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
= render_if_exists 'layouts/header/users_over_license_banner'
- if Feature.enabled?(:subscribable_banner_license, default_enabled: true) - if Feature.enabled?(:subscribable_banner_license, default_enabled: true)
= render_if_exists "layouts/header/ee_subscribable_banner" = render_if_exists "layouts/header/ee_subscribable_banner"
= render "layouts/broadcast" = render "layouts/broadcast"
......
...@@ -11,6 +11,7 @@ module EE ...@@ -11,6 +11,7 @@ module EE
GOLD_TRIAL_BILLINGS = 'gold_trial_billings' GOLD_TRIAL_BILLINGS = 'gold_trial_billings'
THREAT_MONITORING_INFO = 'threat_monitoring_info' THREAT_MONITORING_INFO = 'threat_monitoring_info'
ACCOUNT_RECOVERY_REGULAR_CHECK = 'account_recovery_regular_check' ACCOUNT_RECOVERY_REGULAR_CHECK = 'account_recovery_regular_check'
USERS_OVER_LICENSE_BANNER = 'users_over_license_banner'
def show_canary_deployment_callout?(project) def show_canary_deployment_callout?(project)
!user_dismissed?(CANARY_DEPLOYMENT) && !user_dismissed?(CANARY_DEPLOYMENT) &&
......
# frozen_string_literal: true
module LicenseMonitoringHelper
include Gitlab::Utils::StrongMemoize
def show_users_over_license_banner?
current_user&.admin? && license_is_over_capacity?
end
private
def license_is_over_capacity?
return if current_license.nil? || current_license.trial?
current_license_overage > 0
end
def current_license
strong_memoize(:current_license) { License.current }
end
def current_license_overage
strong_memoize(:current_license_overage) { current_license.overage_with_historical_max }
end
end
...@@ -16,7 +16,8 @@ module EE ...@@ -16,7 +16,8 @@ module EE
canary_deployment: 7, canary_deployment: 7,
gold_trial_billings: 8, gold_trial_billings: 8,
threat_monitoring_info: 11, threat_monitoring_info: 11,
account_recovery_regular_check: 12 account_recovery_regular_check: 12,
users_over_license_banner: 16
) )
end end
end end
......
- not_dismissed_or_in_admin_area = admin_section? || !user_dismissed?(UserCalloutsHelper::USERS_OVER_LICENSE_BANNER)
- return unless not_dismissed_or_in_admin_area && show_users_over_license_banner?
.gl-alert.gl-alert-info.js-users-over-license-callout{ role: 'alert', data: { feature_id: "users_over_license_banner", dismiss_endpoint: user_callouts_path, defer_links: "true" } }
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon')
- unless admin_section?
%button.js-close.gl-alert-dismiss.gl-cursor-pointer{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', size: 16, css_class: 'gl-icon')
.gl-alert-body
%h3.gl-alert-title= s_('License|Licensed user count exceeded')
%p
= s_("License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill.").html_safe % {extra_users_count: current_license_overage}
.gl-alert-actions
= link_to _('Learn more'), 'https://docs.gitlab.com/ee/subscriptions', class: 'btn btn-info gl-alert-action', target: '_blank'
= link_to _('Contact support'), 'https://about.gitlab.com/support/#contact-support', class: 'btn btn-info btn-secondary gl-button', target: '_blank'
---
title: Display banner to admins when there are users over license
merge_request: 30813
author:
type: added
# frozen_string_literal: true
FactoryBot.define do
factory :historical_data do
date { Date.today }
active_user_count { 1 }
end
end
# frozen_string_literal: true
require 'spec_helper'
describe 'Show users over license banner', :js do
include StubRequests
let_it_be(:admin) { create(:admin) }
let_it_be(:user) { create(:user) }
let_it_be(:license_seats_limit) { 10 }
let_it_be(:license) do
create(:license, data: build(:gitlab_license, restrictions: { active_user_count: license_seats_limit }).export)
end
shared_examples_for "a visible banner" do
let(:visit_path) { root_dashboard_path }
it 'shows the banner' do
visit visit_path
expect(page).to have_content('Licensed user count exceeded')
end
end
shared_examples_for "a hidden banner" do
it 'does not show the banner' do
visit root_dashboard_path
expect(page).not_to have_content('Licensed user count exceeded')
end
end
before do
create(:historical_data, date: license.created_at + 1.month, active_user_count: active_user_count)
end
context "with users over license" do
let(:active_user_count) { license_seats_limit + 5 }
context 'when admin is logged in' do
before do
gitlab_sign_in(admin)
end
it_behaves_like 'a visible banner'
context 'when banner was dismissed' do
before do
visit root_dashboard_path
find('.gl-alert-dismiss').click
end
it_behaves_like 'a hidden banner'
context 'when visiting the admin section' do
it_behaves_like 'a visible banner' do
let(:visit_path) { admin_users_path }
end
end
end
end
context 'when regular user is logged in' do
before do
gitlab_sign_in(user)
end
it_behaves_like 'a hidden banner'
end
end
context "without users over license" do
let(:active_user_count) { 1 }
context 'when admin is logged in' do
before do
gitlab_sign_in(admin)
end
it_behaves_like 'a hidden banner'
end
context 'when regular user is logged in' do
before do
gitlab_sign_in(user)
end
it_behaves_like 'a hidden banner'
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe LicenseMonitoringHelper do
let_it_be(:admin) { create(:admin) }
let_it_be(:user) { create(:user) }
let_it_be(:license_seats_limit) { 10 }
let_it_be(:license) do
create(:license, data: build(:gitlab_license, restrictions: { active_user_count: license_seats_limit }).export)
end
describe '#show_users_over_license_banner?' do
subject { helper.show_users_over_license_banner? }
before do
create(:historical_data, date: license.created_at + 1.month, active_user_count: active_user_count)
end
context 'when admin is logged in' do
before do
allow(helper).to receive(:current_user).and_return(admin)
end
context 'when license is above the threshold' do
let(:active_user_count) { license_seats_limit + 5 }
it { is_expected.to eq(true) }
end
context 'when license is below the threshold' do
let(:active_user_count) { 1 }
it { is_expected.to eq(false) }
end
end
context 'when regular user is logged in' do
before do
allow(helper).to receive(:current_user).and_return(user)
end
context 'when license is above the threshold' do
let(:active_user_count) { license_seats_limit + 5 }
it { is_expected.to eq(false) }
end
context 'when license is below the threshold' do
let(:active_user_count) { 1 }
it { is_expected.to eq(false) }
end
end
context 'with anonymous user' do
before do
allow(helper).to receive(:current_user).and_return(nil)
end
context 'when license is above the threshold' do
let(:active_user_count) { license_seats_limit + 5 }
it { is_expected.to be_falsey }
end
context 'when license is below the threshold' do
let(:active_user_count) { 1 }
it { is_expected.to be_falsey }
end
end
end
end
...@@ -5719,6 +5719,9 @@ msgstr "" ...@@ -5719,6 +5719,9 @@ msgstr ""
msgid "Contact sales to upgrade" msgid "Contact sales to upgrade"
msgstr "" msgstr ""
msgid "Contact support"
msgstr ""
msgid "Container Registry" msgid "Container Registry"
msgstr "" msgstr ""
...@@ -12732,6 +12735,9 @@ msgstr "" ...@@ -12732,6 +12735,9 @@ msgstr ""
msgid "License|License" msgid "License|License"
msgstr "" msgstr ""
msgid "License|Licensed user count exceeded"
msgstr ""
msgid "License|You can restore access to the Gold features at any time by upgrading." msgid "License|You can restore access to the Gold features at any time by upgrading."
msgstr "" msgstr ""
...@@ -12747,6 +12753,9 @@ msgstr "" ...@@ -12747,6 +12753,9 @@ msgstr ""
msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}." msgid "License|Your free trial of GitLab Ultimate expired on %{trial_ends_on}."
msgstr "" msgstr ""
msgid "License|Your instance has exceeded your subscription's number of licensed users by %{extra_users_count}. You can continue to add more users and we'll include the overage in your next bill."
msgstr ""
msgid "Limit display of time tracking units to hours." msgid "Limit display of time tracking units to hours."
msgstr "" msgstr ""
......
...@@ -71,6 +71,28 @@ describe ApplicationHelper do ...@@ -71,6 +71,28 @@ describe ApplicationHelper do
end end
end end
describe '#admin_section?' do
context 'when controller is under the admin namespace' do
before do
allow(helper).to receive(:controller).and_return(Admin::UsersController.new)
end
it 'returns true' do
expect(helper.admin_section?).to eq(true)
end
end
context 'when controller is not under the admin namespace' do
before do
allow(helper).to receive(:controller).and_return(UsersController.new)
end
it 'returns true' do
expect(helper.admin_section?).to eq(false)
end
end
end
describe 'simple_sanitize' do describe 'simple_sanitize' do
let(:a_tag) { '<a href="#">Foo</a>' } let(:a_tag) { '<a href="#">Foo</a>' }
......
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