diff --git a/app/helpers/namespace_storage_limit_alert_helper.rb b/app/helpers/namespace_storage_limit_alert_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..d7174c3825459f6f7e98ccb70ca010050b31dce0 --- /dev/null +++ b/app/helpers/namespace_storage_limit_alert_helper.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module NamespaceStorageLimitAlertHelper + # Overridden in EE + def display_namespace_storage_limit_alert! + end +end + +NamespaceStorageLimitAlertHelper.prepend_if_ee('EE::NamespaceStorageLimitAlertHelper') diff --git a/app/views/groups/_flash_messages.html.haml b/app/views/groups/_flash_messages.html.haml index d1fea0e60c69975f118e71da7edf954749bc0c66..fa1a9d2cca44fd406da58523e163bdfb2674044f 100644 --- a/app/views/groups/_flash_messages.html.haml +++ b/app/views/groups/_flash_messages.html.haml @@ -1,3 +1,2 @@ = content_for :flash_message do = render_if_exists 'shared/shared_runners_minutes_limit', namespace: @group, classes: [container_class, ("limit-container-width" unless fluid_layout)] - = render_if_exists 'shared/namespace_storage_limit_alert', namespace: @group, classes: [container_class, ("limit-container-width" unless fluid_layout)] diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 72b88fa8f7fe3d4f31f86ea8af10fad8c6f52791..b2e545bd0cbe13a35b5e38894bc74bd23ffcc9ea 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -15,6 +15,7 @@ = render "shared/ping_consent" = render_account_recovery_regular_check = render_if_exists "layouts/header/ee_subscribable_banner" + = render_if_exists "shared/namespace_storage_limit_alert" - unless @hide_breadcrumbs = render "layouts/nav/breadcrumbs" .d-flex diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml index 36b664e5888b8a86f1864f54a1ab4c0a925670cf..8f4c89a9e77f512cc42e4c6c2030f2843c128c8a 100644 --- a/app/views/layouts/group.html.haml +++ b/app/views/layouts/group.html.haml @@ -3,6 +3,7 @@ - header_title group_title(@group) unless header_title - nav "group" - display_subscription_banner! +- display_namespace_storage_limit_alert! - @left_sidebar = true - content_for :page_specific_javascripts do diff --git a/app/views/projects/_flash_messages.html.haml b/app/views/projects/_flash_messages.html.haml index ab8275ba5e41f1d93c89b110e6e903712224fc2f..f9222387e97f2d31183f8d12cfc9c0fc5c42595a 100644 --- a/app/views/projects/_flash_messages.html.haml +++ b/app/views/projects/_flash_messages.html.haml @@ -9,4 +9,3 @@ = render 'shared/auto_devops_implicitly_enabled_banner', project: project = render_if_exists 'projects/above_size_limit_warning', project: project = render_if_exists 'shared/shared_runners_minutes_limit', project: project, classes: [container_class, ("limit-container-width" unless fluid_layout)] - = render_if_exists 'shared/namespace_storage_limit_alert', namespace: project.namespace, classes: [container_class, ("limit-container-width" unless fluid_layout)] diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 4a521f2f46e19ccc98f2607022645eb49408fb88..56b5b7613449a4c229b44a5ab976e62c24583d70 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,6 +1,7 @@ - breadcrumb_title _("Details") - page_title _("Projects") - @content_class = "limit-container-width" unless fluid_layout +- display_namespace_storage_limit_alert! = content_for :meta_tags do = auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity") diff --git a/ee/app/assets/javascripts/main_ee.js b/ee/app/assets/javascripts/main_ee.js index 7109c61dc535ea58d0ddd3a8b2680915ee0de7c4..bb96889a30062bd2b7f217ca16ef65572c751d03 100644 --- a/ee/app/assets/javascripts/main_ee.js +++ b/ee/app/assets/javascripts/main_ee.js @@ -1,6 +1,7 @@ import $ from 'jquery'; import initEETrialBanner from 'ee/ee_trial_banner'; import trackNavbarEvents from 'ee/event_tracking/navbar'; +import initNamespaceStorageLimitAlert from 'ee/namespace_storage_limit_alert'; $(() => { /** @@ -10,6 +11,7 @@ $(() => { // EE specific calls initEETrialBanner(); + initNamespaceStorageLimitAlert(); trackNavbarEvents(); }); diff --git a/ee/app/assets/javascripts/pages/groups/show/index.js b/ee/app/assets/javascripts/pages/groups/show/index.js index 0fa680549b94b7bf9a35265991b57b9551777aab..a1a90e4f607ff43329dad82289cff39186294108 100644 --- a/ee/app/assets/javascripts/pages/groups/show/index.js +++ b/ee/app/assets/javascripts/pages/groups/show/index.js @@ -3,7 +3,6 @@ import leaveByUrl from '~/namespaces/leave_by_url'; import initGroupDetails from '~/pages/groups/shared/group_details'; import initGroupAnalytics from 'ee/analytics/group_analytics/group_analytics_bundle'; import initVueAlerts from '~/vue_alerts'; -import initNamespaceStorageLimitAlert from 'ee/namespace_storage_limit_alert'; document.addEventListener('DOMContentLoaded', () => { leaveByUrl('group'); @@ -16,5 +15,4 @@ document.addEventListener('DOMContentLoaded', () => { initGroupAnalytics(); initVueAlerts(); - initNamespaceStorageLimitAlert(); }); diff --git a/ee/app/assets/javascripts/pages/projects/show/index.js b/ee/app/assets/javascripts/pages/projects/show/index.js index f3d127421015f1edb9d6254dc166813dbbf6a29e..3c35264a524e66422f7fcf539001b0ab3bb420de 100644 --- a/ee/app/assets/javascripts/pages/projects/show/index.js +++ b/ee/app/assets/javascripts/pages/projects/show/index.js @@ -1,8 +1,6 @@ import '~/pages/projects/show/index'; import initVueAlerts from '~/vue_alerts'; -import initNamespaceStorageLimitAlert from 'ee/namespace_storage_limit_alert'; document.addEventListener('DOMContentLoaded', () => { initVueAlerts(); - initNamespaceStorageLimitAlert(); }); diff --git a/ee/app/helpers/ee/namespace_storage_limit_alert_helper.rb b/ee/app/helpers/ee/namespace_storage_limit_alert_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..31a6aa690a6076e8d684dd918bcc3fd9a182d144 --- /dev/null +++ b/ee/app/helpers/ee/namespace_storage_limit_alert_helper.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module EE + module NamespaceStorageLimitAlertHelper + extend ::Gitlab::Utils::Override + + override :display_namespace_storage_limit_alert! + def display_namespace_storage_limit_alert! + @display_namespace_storage_limit_alert = true + end + + def display_namespace_storage_limit_alert? + @display_namespace_storage_limit_alert + end + + def namespace_storage_alert(namespace) + return {} if current_user.nil? + + payload = Namespaces::CheckStorageSizeService.new(namespace, current_user).execute.payload + + return {} if payload.empty? + + alert_level = payload[:alert_level] + root_namespace = payload[:root_namespace] + + return {} if cookies["hide_storage_limit_alert_#{root_namespace.id}_#{alert_level}"] == 'true' + + payload + end + + def namespace_storage_alert_style(alert_level) + if alert_level == :error || alert_level == :alert + 'danger' + else + alert_level.to_s + end + end + + def namespace_storage_alert_icon(alert_level) + if alert_level == :error || alert_level == :alert + 'error' + elsif alert_level == :info + 'information-o' + else + alert_level.to_s + end + end + + def namespace_storage_usage_link(namespace) + if namespace.group? + group_usage_quotas_path(namespace, anchor: 'storage-quota-tab') + else + profile_usage_quotas_path(anchor: 'storage-quota-tab') + end + end + + def purchase_storage_url + return unless ::Gitlab.dev_env_or_com? + return unless ::Feature.enabled?(:buy_storage_link) + + EE::SUBSCRIPTIONS_MORE_STORAGE_URL + end + end +end diff --git a/ee/app/helpers/ee/namespaces_helper.rb b/ee/app/helpers/ee/namespaces_helper.rb index 19e61acf3e84afd5fb7f45e8672883c9a1fe2eef..dfaac97e260b30edd8b83b66033de9ba01b0845e 100644 --- a/ee/app/helpers/ee/namespaces_helper.rb +++ b/ee/app/helpers/ee/namespaces_helper.rb @@ -32,59 +32,11 @@ module EE end end - def namespace_storage_alert(namespace) - return {} if current_user.nil? - - payload = Namespaces::CheckStorageSizeService.new(namespace, current_user).execute.payload - - return {} if payload.empty? - - alert_level = payload[:alert_level] - root_namespace = payload[:root_namespace] - - return {} if cookies["hide_storage_limit_alert_#{root_namespace.id}_#{alert_level}"] == 'true' - - payload - end - - def namespace_storage_alert_style(alert_level) - if alert_level == :error || alert_level == :alert - 'danger' - else - alert_level.to_s - end - end - - def namespace_storage_alert_icon(alert_level) - if alert_level == :error || alert_level == :alert - 'error' - elsif alert_level == :info - 'information-o' - else - alert_level.to_s - end - end - def temporary_storage_increase_visible?(namespace) return false unless ::Gitlab.dev_env_or_com? return false unless ::Feature.enabled?(:temporary_storage_increase, namespace) current_user.can?(:admin_namespace, namespace.root_ancestor) end - - def namespace_storage_usage_link(namespace) - if namespace.group? - group_usage_quotas_path(namespace, anchor: 'storage-quota-tab') - else - profile_usage_quotas_path(anchor: 'storage-quota-tab') - end - end - - def purchase_storage_url - return unless ::Gitlab.dev_env_or_com? - return unless ::Feature.enabled?(:buy_storage_link) - - EE::SUBSCRIPTIONS_MORE_STORAGE_URL - end end end diff --git a/ee/app/views/shared/_flash_messages.html.haml b/ee/app/views/shared/_flash_messages.html.haml index d1fea0e60c69975f118e71da7edf954749bc0c66..fa1a9d2cca44fd406da58523e163bdfb2674044f 100644 --- a/ee/app/views/shared/_flash_messages.html.haml +++ b/ee/app/views/shared/_flash_messages.html.haml @@ -1,3 +1,2 @@ = content_for :flash_message do = render_if_exists 'shared/shared_runners_minutes_limit', namespace: @group, classes: [container_class, ("limit-container-width" unless fluid_layout)] - = render_if_exists 'shared/namespace_storage_limit_alert', namespace: @group, classes: [container_class, ("limit-container-width" unless fluid_layout)] diff --git a/ee/app/views/shared/_namespace_storage_limit_alert.html.haml b/ee/app/views/shared/_namespace_storage_limit_alert.html.haml index 95f27cde15b3dbc4b91d9dab15a842bda042dd74..07de6d30b6d331f9e10d3748957c7b8f5e226524 100644 --- a/ee/app/views/shared/_namespace_storage_limit_alert.html.haml +++ b/ee/app/views/shared/_namespace_storage_limit_alert.html.haml @@ -1,4 +1,8 @@ - return unless current_user +- return unless display_namespace_storage_limit_alert? + +- namespace = @project&.namespace || @group +- return unless namespace.present? - payload = namespace_storage_alert(namespace) - return if payload.empty? @@ -10,7 +14,7 @@ - icon = namespace_storage_alert_icon(alert_level) - link = namespace_storage_usage_link(root_namespace) -%div{ class: [classes, 'js-namespace-storage-alert'] } +%div{ class: ['js-namespace-storage-alert', [container_class, ("limit-container-width" unless fluid_layout)]] } .gl-pt-5.gl-pb-3 .gl-alert{ class: "gl-alert-#{style}", role: 'alert' } = sprite_icon(icon, css_class: "gl-icon gl-alert-icon") diff --git a/ee/spec/helpers/ee/namespace_storage_limit_alert_helper_spec.rb b/ee/spec/helpers/ee/namespace_storage_limit_alert_helper_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..43b66f06921f40d0b0e453afd69816a767c5bc7e --- /dev/null +++ b/ee/spec/helpers/ee/namespace_storage_limit_alert_helper_spec.rb @@ -0,0 +1,150 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe EE::NamespaceStorageLimitAlertHelper do + using RSpec::Parameterized::TableSyntax + + let!(:admin) { create(:admin) } + + describe '#display_namespace_storage_limit_alert!' do + it 'sets @display_namespace_storage_limit_alert to true' do + expect(helper.instance_variable_get(:@display_namespace_storage_limit_alert)).to be nil + + helper.display_namespace_storage_limit_alert! + + expect(helper.instance_variable_get(:@display_namespace_storage_limit_alert)).to be true + end + end + + describe '#namespace_storage_usage_link' do + subject { helper.namespace_storage_usage_link(namespace) } + + context 'when namespace is a group' do + let(:namespace) { build(:group) } + + it { is_expected.to eq(group_usage_quotas_path(namespace, anchor: 'storage-quota-tab')) } + end + + context 'when namespace is a user' do + let(:namespace) { build(:namespace) } + + it { is_expected.to eq(profile_usage_quotas_path(anchor: 'storage-quota-tab')) } + end + end + + describe '#purchase_storage_url' do + subject { helper.purchase_storage_url } + + context 'when on .com' do + before do + allow(::Gitlab).to receive(:com?).and_return(true) + end + + it { is_expected.to eq(EE::SUBSCRIPTIONS_MORE_STORAGE_URL) } + + context 'when feature flag disabled' do + before do + stub_feature_flags(buy_storage_link: false) + end + + it { is_expected.to be_nil } + end + end + + context 'when not on .com' do + before do + allow(::Gitlab).to receive(:com?).and_return(false) + end + + it { is_expected.to be_nil } + end + end + + describe '#namespace_storage_alert' do + subject { helper.namespace_storage_alert(namespace) } + + let(:namespace) { build(:namespace) } + + let(:payload) do + { + alert_level: :info, + usage_message: "Usage", + explanation_message: "Explanation", + root_namespace: namespace + } + end + + before do + allow(helper).to receive(:current_user).and_return(admin) + allow_next_instance_of(Namespaces::CheckStorageSizeService, namespace, admin) do |check_storage_size_service| + expect(check_storage_size_service).to receive(:execute).and_return(ServiceResponse.success(payload: payload)) + end + end + + context 'when payload is not empty and no cookie is set' do + it { is_expected.to eq(payload) } + end + + context 'when there is no current_user' do + before do + allow(helper).to receive(:current_user).and_return(nil) + end + + it { is_expected.to eq({}) } + end + + context 'when payload is empty' do + let(:payload) { {} } + + it { is_expected.to eq({}) } + end + + context 'when cookie is set' do + before do + helper.request.cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true' + end + + it { is_expected.to eq({}) } + end + + context 'when payload is empty and cookie is set' do + let(:payload) { {} } + + before do + helper.request.cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true' + end + + it { is_expected.to eq({}) } + end + end + + describe '#namespace_storage_alert_style' do + subject { helper.namespace_storage_alert_style(alert_level) } + + where(:alert_level, :result) do + :info | 'info' + :warning | 'warning' + :error | 'danger' + :alert | 'danger' + end + + with_them do + it { is_expected.to eq(result) } + end + end + + describe '#namespace_storage_alert_icon' do + subject { helper.namespace_storage_alert_icon(alert_level) } + + where(:alert_level, :result) do + :info | 'information-o' + :warning | 'warning' + :error | 'error' + :alert | 'error' + end + + with_them do + it { is_expected.to eq(result) } + end + end +end diff --git a/ee/spec/helpers/ee/namespaces_helper_spec.rb b/ee/spec/helpers/ee/namespaces_helper_spec.rb index 666a5235b0eec9473cf125e50a6f7e12391c62c1..3aa0709ff3a9233afd8c5620f40d641e41157f4e 100644 --- a/ee/spec/helpers/ee/namespaces_helper_spec.rb +++ b/ee/spec/helpers/ee/namespaces_helper_spec.rb @@ -151,140 +151,4 @@ RSpec.describe EE::NamespacesHelper do end end end - - describe '#namespace_storage_usage_link' do - subject { helper.namespace_storage_usage_link(namespace) } - - context 'when namespace is a group' do - let(:namespace) { build(:group) } - - it { is_expected.to eq(group_usage_quotas_path(namespace, anchor: 'storage-quota-tab')) } - end - - context 'when namespace is a user' do - let(:namespace) { build(:namespace) } - - it { is_expected.to eq(profile_usage_quotas_path(anchor: 'storage-quota-tab')) } - end - end - - describe '#purchase_storage_url' do - subject { helper.purchase_storage_url } - - context 'when on .com' do - before do - allow(::Gitlab).to receive(:com?).and_return(true) - end - - it { is_expected.to eq(EE::SUBSCRIPTIONS_MORE_STORAGE_URL) } - - context 'when feature flag disabled' do - before do - stub_feature_flags(buy_storage_link: false) - end - - it { is_expected.to be_nil } - end - end - - context 'when not on .com' do - before do - allow(::Gitlab).to receive(:com?).and_return(false) - end - - it { is_expected.to be_nil } - end - end - - describe '#namespace_storage_alert' do - subject { helper.namespace_storage_alert(namespace) } - - let(:namespace) { build(:namespace) } - - let(:payload) do - { - alert_level: :info, - usage_message: "Usage", - explanation_message: "Explanation", - root_namespace: namespace - } - end - - before do - allow(helper).to receive(:current_user).and_return(admin) - allow_next_instance_of(Namespaces::CheckStorageSizeService, namespace, admin) do |check_storage_size_service| - expect(check_storage_size_service).to receive(:execute).and_return(ServiceResponse.success(payload: payload)) - end - end - - context 'when payload is not empty and no cookie is set' do - it { is_expected.to eq(payload) } - end - - context 'when there is no current_user' do - before do - allow(helper).to receive(:current_user).and_return(nil) - end - - it { is_expected.to eq({}) } - end - - context 'when payload is empty' do - let(:payload) { {} } - - it { is_expected.to eq({}) } - end - - context 'when cookie is set' do - before do - helper.request.cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true' - end - - it { is_expected.to eq({}) } - end - - context 'when payload is empty and cookie is set' do - let(:payload) { {} } - - before do - helper.request.cookies["hide_storage_limit_alert_#{namespace.id}_info"] = 'true' - end - - it { is_expected.to eq({}) } - end - end - - describe '#namespace_storage_alert_style' do - using RSpec::Parameterized::TableSyntax - - subject { helper.namespace_storage_alert_style(alert_level) } - - where(:alert_level, :result) do - :info | 'info' - :warning | 'warning' - :error | 'danger' - :alert | 'danger' - end - - with_them do - it { is_expected.to eq(result) } - end - end - - describe '#namespace_storage_alert_icon' do - using RSpec::Parameterized::TableSyntax - - subject { helper.namespace_storage_alert_icon(alert_level) } - - where(:alert_level, :result) do - :info | 'information-o' - :warning | 'warning' - :error | 'error' - :alert | 'error' - end - - with_them do - it { is_expected.to eq(result) } - end - end end diff --git a/spec/helpers/namespace_storage_limit_alert_helper_spec.rb b/spec/helpers/namespace_storage_limit_alert_helper_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..ab3cf96edefb52a451c9bda5e206e2ac0481099d --- /dev/null +++ b/spec/helpers/namespace_storage_limit_alert_helper_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe NamespaceStorageLimitAlertHelper do + describe '#display_namespace_storage_limit_alert!' do + it 'is defined in CE' do + expect { helper.display_namespace_storage_limit_alert! }.not_to raise_error + end + end +end