diff --git a/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..5b65c7c21fa522f79fef3df6dc73f9fde6e2ad29 --- /dev/null +++ b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.html.haml @@ -0,0 +1,13 @@ += render Pajamas::CardComponent.new(card_options: card_options) do |c| + - c.with_body do + .gl-text-size-h2.gl-font-bold + = icon + = title + .gl-mb-5 + - body.map do |line| + .gl-mt-3 + = line + .gl-flex.gl-flex-wrap.gl-gap-3 + = render Pajamas::ButtonComponent.new(**primary_cta_options) do + = primary_cta + .js-hand-raise-lead-trigger{ data: hand_raise_lead_data } diff --git a/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb new file mode 100644 index 0000000000000000000000000000000000000000..a75a37bf36801006bca58f35191480657cbba52b --- /dev/null +++ b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/base_component.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +module GitlabSubscriptions + module DuoEnterpriseAlert + class BaseComponent < ViewComponent::Base + # @param [Namespace or Group] namespace + # @param [User] user + + def initialize(namespace:, user:) + @namespace = namespace + @user = user + end + + private + + attr_reader :namespace, :user + + delegate :sprite_icon, to: :helpers + + def duo_enterprise_trials_enabled? + Feature.enabled?(:duo_enterprise_trials, user) + end + + def card_options + { + class: 'gl-border gl-border-blue-300 gl-bg-blue-50 gl-rounded-base gl-text-left gl-mt-6 gl-p-3', + data: { testid: 'duo-enterprise-trial-alert' } + } + end + + def icon + sprite_icon('tanuki-ai', css_class: 'gl-mr-2 !gl-align-baseline') + end + + def title + s_('BillingPlans|Get the most out of GitLab with Ultimate and GitLab Duo Enterprise') + end + + def primary_cta_options + { + href: primary_link, + variant: 'confirm', + button_text_classes: '!gl-whitespace-normal', + button_options: { + class: 'gl-w-full sm:gl-w-auto', + data: { + event_tracking: 'click_duo_enterprise_trial_billing_page', + event_label: primary_tracking_label + } + } + } + end + + def primary_link + new_trial_path(namespace_id: namespace.id) + end + + def primary_tracking_label + 'ultimate_and_duo_enterprise_trial' + end + + def primary_cta + s_('BillingPlans|Start free trial of GitLab Ultimate and GitLab Duo Enterprise') + end + + def hand_raise_lead_data + { + glm_content: 'billing-group', + cta_tracking: { + action: 'hand_raise_form_viewed', + label: 'click_duo_enterprise_trial_billing_page' + }.to_json, + button_attributes: { + variant: 'confirm', + category: 'secondary', + class: 'gl-w-full sm:gl-w-auto' + }.to_json + } + end + end + end +end diff --git a/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb new file mode 100644 index 0000000000000000000000000000000000000000..e244e13a9e2b5597dbf10c5ff63f7a2561e5b5ba --- /dev/null +++ b/ee/app/components/gitlab_subscriptions/duo_enterprise_alert/free_component.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module GitlabSubscriptions + module DuoEnterpriseAlert + class FreeComponent < BaseComponent + private + + def render? + duo_enterprise_trials_enabled? && + namespace.free_plan? && + GitlabSubscriptions::DuoEnterprise.no_add_on_purchase_for_namespace?(namespace) + end + + def body + [ + s_('BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to ' \ + 'try the complete set of features from GitLab. GitLab Duo Enterprise ' \ + 'gives you access to the full product offering from GitLab, including ' \ + 'AI-powered features. You can try it for free, no credit card required.') + ] + end + end + end +end diff --git a/ee/app/helpers/billing_plans_helper.rb b/ee/app/helpers/billing_plans_helper.rb index 71708d33972c95bfc4f822004c1f167d0ee1433e..8ec9460e6fd0fe3b42df51820c8643b8b5fe5052 100644 --- a/ee/app/helpers/billing_plans_helper.rb +++ b/ee/app/helpers/billing_plans_helper.rb @@ -151,7 +151,7 @@ def add_namespace_plan_to_group_instructions def show_duo_enterprise_trial_alert?(namespace) return false if Feature.disabled?(:duo_enterprise_trials, current_user) - if namespace.ultimate_plan? || namespace.free_plan? + if namespace.ultimate_plan? GitlabSubscriptions::DuoEnterprise.no_add_on_purchase_for_namespace?(namespace) elsif namespace.premium_plan? GitlabSubscriptions::Duo.no_add_on_purchase_for_namespace?(namespace) @@ -176,13 +176,6 @@ def duo_enterprise_trial_alert_data(namespace) s_('BillingPlans|Not ready to trial the full suite of GitLab and GitLab Duo features? Start a free trial of GitLab Duo Pro instead.') ] } - else - { - title: s_('BillingPlans|Get the most out of GitLab with Ultimate and GitLab Duo Enterprise'), - body: [ - s_('BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to try the complete set of features from GitLab. GitLab Duo Enterprise gives you access to the full product offering from GitLab, including AI-powered features. You can try it for free, no credit card required.') - ] - } end end diff --git a/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml b/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml index d263a6e9d7c3dfe856bebcce6354ff0ac5f9c23c..8e0bb320b1f3ae73bb6e65688cf50c5c9706aaef 100644 --- a/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml +++ b/ee/app/views/groups/billings/_free_and_trial_plan_billing_index.html.haml @@ -11,9 +11,8 @@ = html_escape(s_("BillingPlans|Not the group you're looking for? %{all_groups_link}")) % { all_groups_link: all_groups_link.html_safe } - - if show_duo_enterprise_trial_alert?(namespace) - .billing-plan-divider.gl-mx-auto - = render 'shared/billings/duo_enterprise_trial_alert', namespace: namespace + .billing-plan-divider.gl-mx-auto + = render GitlabSubscriptions::DuoEnterpriseAlert::FreeComponent.new(namespace: namespace, user: current_user) .gl-flex-row.gl-flex.gl-flex-wrap.gl-justify-center.gl-mb-7.gl-ml-7{ data: { track_action: 'render', testid: 'billing-plans' } } = render Billing::PlanComponent.with_collection(plans_data, namespace: namespace, current_plan: current_plan) diff --git a/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..c7ddbb3b9f472744090b80e7b154d87722163030 --- /dev/null +++ b/ee/spec/components/gitlab_subscriptions/duo_enterprise_alert/free_component_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSubscriptions::DuoEnterpriseAlert::FreeComponent, :saas, :aggregate_failures, + type: :component, feature_category: :acquisition do + let(:namespace) { build(:group, id: non_existing_record_id) } + let(:user) { build(:user) } + + subject(:component) do + render_inline(described_class.new(namespace: namespace, user: user)) && page + end + + before do + build(:gitlab_subscription, :free, namespace: namespace) + end + + context 'when duo_enterprise_trials is disabled' do + before do + stub_feature_flags(duo_enterprise_trials: false) + end + + it { is_expected.to have_content('') } + end + + context 'when ultimate_trial plan' do + before do + build(:gitlab_subscription, :ultimate_trial, :active_trial, namespace: namespace) + end + + it { is_expected.to have_content('') } + end + + context 'when there is Duo Enterprise add-on' do + before do + allow(GitlabSubscriptions::DuoEnterprise) + .to receive(:no_add_on_purchase_for_namespace?) + .with(namespace) + .and_return(false) + end + + it { is_expected.to have_content('') } + end + + context 'when rendering' do + it 'has the correct text' do + is_expected.to have_content( + 'Get the most out of GitLab with Ultimate and GitLab Duo Enterprise' + ) + + is_expected.to have_content( + 'Start an Ultimate trial with GitLab Duo Enterprise to try the ' \ + 'complete set of features from GitLab. GitLab Duo Enterprise gives ' \ + 'you access to the full product offering from GitLab, including ' \ + 'AI-powered features. You can try it for free, no credit card required.' + ) + end + + it 'has the primary action' do + is_expected.to have_link( + 'Start free trial of GitLab Ultimate and GitLab Duo Enterprise', + href: new_trial_path(namespace_id: namespace.id) + ) + + is_expected.to have_css( + '[data-event-tracking="click_duo_enterprise_trial_billing_page"]' \ + '[data-event-label="ultimate_and_duo_enterprise_trial"]' + ) + end + + it 'has the hand raise lead selector' do + is_expected.to have_selector('.js-hand-raise-lead-trigger') + end + end +end diff --git a/ee/spec/helpers/billing_plans_helper_spec.rb b/ee/spec/helpers/billing_plans_helper_spec.rb index d9769ee813b7331d3b649fb4a785eee2c6174438..4fbdad5191f9305676db2105a374c8dfab31b455 100644 --- a/ee/spec/helpers/billing_plans_helper_spec.rb +++ b/ee/spec/helpers/billing_plans_helper_spec.rb @@ -600,16 +600,6 @@ end end - context 'when free plan' do - before do - build(:gitlab_subscription, :free, namespace: namespace) - end - - it_behaves_like 'available plan' do - let(:finder) { GitlabSubscriptions::DuoEnterprise } - end - end - context 'when ultimate trial plan' do before do build(:gitlab_subscription, :ultimate_trial, :active_trial, namespace: namespace) diff --git a/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb b/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb index ede6949b68c7a3d7934e954c99f78566fde44d8b..0b98768478423259292f9760e605e8165294b196 100644 --- a/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb +++ b/ee/spec/views/shared/billings/_duo_enterprise_trial_alert.html.haml_spec.rb @@ -103,45 +103,4 @@ def render ) end end - - context 'when free plan' do - before do - build(:gitlab_subscription, :free, namespace: group) - end - - it 'contains the correct text' do - render - - expect(rendered).to have_content( - 'Get the most out of GitLab with Ultimate and GitLab Duo Enterprise' - ) - - expect(rendered).to have_content( - 'Start an Ultimate trial with GitLab Duo Enterprise to try the ' \ - 'complete set of features from GitLab. GitLab Duo Enterprise gives ' \ - 'you access to the full product offering from GitLab, including ' \ - 'AI-powered features. You can try it for free, no credit card required.' - ) - end - - it 'contains the primary action' do - render - - expect(rendered).to have_link( - 'Start free trial of GitLab Ultimate and GitLab Duo Enterprise', - href: new_trial_path(namespace_id: group.id) - ) - - expect(rendered).to have_css( - '[data-event-tracking="click_duo_enterprise_trial_billing_page"]' \ - '[data-event-label="ultimate_and_duo_enterprise_trial"]' - ) - end - - it 'contains the hand raise lead selector' do - render - - expect(rendered).to have_selector('.js-hand-raise-lead-trigger') - end - end end