Commit 1dc056b3 authored by Michael Kozono's avatar Michael Kozono

Merge branch 'add-purchase-point-to-group-billing-page' into 'master'

Use Billing Plan Card layout in profile/billing and group/billing

Closes #13485 and #31471

See merge request gitlab-org/gitlab!15437
parents 623a3db3 1938962d
......@@ -20,133 +20,36 @@
}
.billing-plans {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
margin-top: 8px;
.card-header {
border-bottom: 0;
}
.card {
display: flex;
flex-direction: column;
margin: 8px;
width: 100%;
border: 0;
&:first-of-type {
margin-left: 0;
}
&:last-of-type {
margin-right: 0;
&-header {
line-height: $gl-line-height-20;
}
@include media-breakpoint-up(sm) {
width: 280px;
&-active {
background-color: $gray-light;
}
.card-header,
.card-body {
border-left: 1px solid $list-border;
border-right: 1px solid $list-border;
}
.card-header {
background-color: $blue-500;
color: $white-light;
border: 0;
border-radius: 4px 4px 0 0;
font-size: 20px;
text-align: center;
}
.card-body {
flex-grow: 1;
border-radius: 0 0 4px 4px;
border-bottom: 1px solid $list-border;
padding: 0;
display: flex;
flex-direction: column;
.price-per-month {
display: flex;
flex-direction: row;
color: $blue-500;
padding: 16px;
padding-bottom: 0;
justify-content: center;
font-size: 50px;
font-size: 48px;
font-weight: $gl-font-weight-bold;
line-height: 1;
.billing-conditions {
.conditions {
list-style: none;
font-size: 20px;
font-size: $gl-font-size-large;
font-weight: $gl-font-weight-bold;
margin: auto 0;
line-height: 20px;
padding: 0;
line-height: $gl-line-height;
}
}
.price-per-year {
color: $blue-500;
text-align: center;
font-size: 12px;
font-size: $gl-font-size-small;
font-weight: $gl-font-weight-bold;
padding-bottom: 16px;
height: 32px;
}
.feature-list {
display: flex;
flex-direction: column;
flex-grow: 1;
text-align: center;
margin: 0;
li {
background-color: $gray-light;
&:first-child {
border-top: 1px solid $list-border;
}
&:last-child {
border-bottom: 1px solid $list-border;
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
&:last-child:hover {
background-color: $gray-light;
}
}
}
.plan-action {
padding: 16px;
.btn {
width: 100%;
}
}
}
&.current {
.card-body {
border-color: $blue-600;
border-width: 2px;
.price-per-month,
.price-per-year {
color: $blue-600;
}
}
}
}
......
......@@ -15,7 +15,7 @@ module BillingPlansHelper
def plan_purchase_link(href, link_text)
if href
link_to link_text, href, class: 'btn btn-primary btn-inverted'
link_to link_text, href, class: 'btn btn-success'
else
button_tag link_text, class: 'btn disabled'
end
......@@ -42,6 +42,24 @@ module BillingPlansHelper
"#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/upgrade/#{plan.id}"
end
def plan_purchase_url(group, plan)
"#{plan.purchase_link.href}&gl_namespace_id=#{group.id}"
end
def plan_feature_short_list(plan)
return [] unless plan.features
plan.features.sort_by! { |feature| feature.highlight ? 0 : 1 }[0...4]
end
def plan_purchase_or_upgrade_url(group, plan, current_plan)
if group.upgradable?
plan_upgrade_url(group, current_plan)
else
plan_purchase_url(group, plan)
end
end
def show_trial_banner?(namespace)
return false unless params[:trial]
......
- page_title "Billing"
- current_plan = subscription_plan_info(@plans_data, @group.actual_plan_name)
- support_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: EE::CUSTOMER_SUPPORT_URL }
- support_link_end = '</a>'.html_safe
- if @top_most_group
- top_most_group_plan = subscription_plan_info(@plans_data, @top_most_group.actual_plan_name)
= render 'shared/billings/billing_plan_header', namespace: @group, plan: top_most_group_plan, parent_group: @top_most_group
- else
= render 'shared/billings/billing_plan_header', namespace: @group, plan: current_plan
= render 'shared/billings/billing_plans', plans_data: @plans_data, namespace: @group
#js-billing-plans{ data: subscription_plan_data_attributes(@group, current_plan) }
- if @group.actual_plan
.center
= s_('BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}.').html_safe % { support_link_start: support_link_start, support_link_end: support_link_end }
#js-billing-plans{ data: subscription_plan_data_attributes(@group, current_plan) }
.card{ class: ('current' if current_plan?(plan)) }
.card-header.bg-info.text-white
= plan.name
- purchase_link = plan.purchase_link
- is_current_plan = purchase_link.action == 'current_plan'
.card-body
.price-per-month
.append-right-5
= number_to_plan_currency(plan.price_per_month)
.col-md-6.col-lg-3
.card.mb-5{ class: ("card-active" if is_current_plan) }
.card-header.font-weight-bold.p-3
= plan.name
- if is_current_plan
.pull-right.text-muted
= _("Current Plan")
%ul.billing-conditions
%li= s_("BillingPlans|per user")
%li= s_("BillingPlans|monthly")
.price-per-year
- if plan.price_per_year > 0
.card-body
.price-per-month
.append-right-5
= number_to_plan_currency(plan.price_per_month)
%ul.conditions.p-0.my-auto
%li= s_("BillingPlans|per user")
%li= s_("BillingPlans|monthly")
.price-per-year.text-left{ class: ("invisible" unless plan.price_per_year.positive?) }
- price_per_year = number_to_plan_currency(plan.price_per_year)
= s_("BillingPlans|paid annually at %{price_per_year}") % { price_per_year: price_per_year }
= s_("BillingPlans|billed annually at %{price_per_year}") % { price_per_year: price_per_year }
%ul.feature-list.bordered-list
- plan.features.each do |feature|
%li
- if feature.highlight
%strong= feature.title
- else
= feature.title
%li
- if plan.about_page_href
= link_to s_("BillingPlans|See all %{plan_name} features") % { plan_name: plan.name }, plan.about_page_href
%hr.mt-3.mb-3
- purchase_link = plan.purchase_link
%ul.unstyled-list
- plan_feature_short_list(plan).each do |feature|
%li.p-0{ class: ("font-weight-bold" if feature.highlight) }
= feature.title
%li.p-0.pt-3
- if plan.about_page_href
= link_to s_("BillingPlans|See all %{plan_name} features") % { plan_name: plan.name }, EE::SUBSCRIPTIONS_COMPARISON_URL
- if purchase_link
.plan-action
- href = purchase_link.href&.concat("&gl_namespace_id=#{namespace.id}")
- case purchase_link.action
- when 'downgrade'
= plan_purchase_link(href, s_("BillingPlans|Downgrade"))
- when 'current_plan'
= plan_purchase_link(href, s_("BillingPlans|Current plan"))
- when 'upgrade'
= plan_purchase_link(href, s_("BillingPlans|Upgrade"))
.card-footer.p-3
.pull-right{ class: ("invisible" unless purchase_link.action == 'upgrade' || is_current_plan) }
- upgrade_button_class = "disabled" if is_current_plan
= link_to s_('BillingPlan|Upgrade'), plan_purchase_or_upgrade_url(namespace, plan, current_plan), class: "btn btn-success #{upgrade_button_class}"
......@@ -25,11 +25,10 @@
= group_icon(@group, class: 'avatar avatar-tile s96', width: 96, height: 96, alt: @group.name)
%h4
- plan_link = plan.about_page_href ? link_to(plan.code.titleize, plan.about_page_href) : plan.name
- if namespace == current_user.namespace
= s_("BillingPlans|@%{user_name} you are currently using the %{plan_link} plan.").html_safe % { user_name: current_user.username, plan_link: plan_link }
= s_("BillingPlans|@%{user_name} you are currently using the %{plan_name} plan.").html_safe % { user_name: current_user.username, plan_name: plan.code.titleize }
- else
= s_("BillingPlans|%{group_name} is currently using the %{plan_link} plan.").html_safe % { group_name: namespace.full_name, plan_link: plan_link }
= s_("BillingPlans|%{group_name} is currently using the %{plan_name} plan.").html_safe % { group_name: namespace.full_name, plan_name: plan.code.titleize }
- if parent_group
%p= s_("BillingPlans|This group uses the plan associated with its parent group.")
......
......@@ -6,14 +6,9 @@
= render 'shared/billings/billing_plan_header', namespace: namespace, plan: current_plan
- unless namespace.gold_plan?
- if namespace.upgradable?
.gl-p-4.center
= link_to s_('BillingPlan|Upgrade plan'), plan_upgrade_url(namespace, current_plan), class: 'btn btn-success'
- else
.billing-plans
- plans_data.each do |plan|
= render 'shared/billings/billing_plan', namespace: namespace, plan: plan
.billing-plans.mt-5.row
- plans_data.each do |plan|
= render 'shared/billings/billing_plan', namespace: namespace, plan: plan, current_plan: current_plan
- if namespace.actual_plan
.center
......
---
title: Show Billing Plan as Cards in profile and groups
merge_request: 15437
author:
type: added
......@@ -2,7 +2,8 @@
module EE
SUBSCRIPTIONS_URL = ENV.fetch('CUSTOMER_PORTAL_URL', 'https://customers.gitlab.com').freeze
SUBSCRIPTIONS_PLANS_URL = "#{SUBSCRIPTIONS_URL}/plans".freeze
SUBSCRIPTIONS_COMPARISON_URL = "https://about.gitlab.com/pricing/gitlab-com/feature-comparison".freeze
SUBSCRIPTIONS_MORE_MINUTES_URL = "#{SUBSCRIPTIONS_URL}/buy_pipeline_minutes".freeze
SUBSCRIPTIONS_PLANS_URL = "#{SUBSCRIPTIONS_URL}/plans".freeze
CUSTOMER_SUPPORT_URL = 'https://support.gitlab.com'.freeze
end
......@@ -60,7 +60,7 @@ describe 'Billing plan pages', :feature do
it 'displays correct plan actions' do
expected_actions = plans_data.map { |data| data.fetch(:purchase_link).fetch(:action) }
plan_actions = page.all('.billing-plans .card .plan-action')
plan_actions = page.all('.billing-plans .card .card-footer')
expect(plan_actions.length).to eq(expected_actions.length)
expected_actions.each_with_index do |expected_action, index|
......@@ -68,13 +68,13 @@ describe 'Billing plan pages', :feature do
case expected_action
when 'downgrade'
expect(action).to have_content('Downgrade')
expect(action).to have_css('.disabled')
expect(action).not_to have_link('Upgrade')
expect(action).not_to have_css('.disabled')
when 'current_plan'
expect(action).to have_content('Current plan')
expect(action).to have_link('Upgrade')
expect(action).to have_css('.disabled')
when 'upgrade'
expect(action).to have_content('Upgrade')
expect(action).to have_link('Upgrade')
expect(action).not_to have_css('.disabled')
end
end
......@@ -100,7 +100,7 @@ describe 'Billing plan pages', :feature do
end
page.within('.content') do
expect(page).to have_link('Upgrade plan', href: external_upgrade_url(namespace, bronze_plan))
expect(page).to have_link('Upgrade', href: external_upgrade_url(namespace, bronze_plan))
expect(page).to have_content('downgrade your plan')
expect(page).to have_link('Customer Support', href: EE::CUSTOMER_SUPPORT_URL)
end
......@@ -126,7 +126,6 @@ describe 'Billing plan pages', :feature do
end
page.within('.content') do
expect(page).not_to have_link('Upgrade plan')
expect(page).to have_content('downgrade your plan')
expect(page).to have_link('Customer Support', href: EE::CUSTOMER_SUPPORT_URL)
end
......@@ -162,8 +161,8 @@ describe 'Billing plan pages', :feature do
end
end
it 'does not display the billing plans table' do
expect(page).not_to have_css('.billing-plans')
it 'does display the billing plans table' do
expect(page).to have_css('.billing-plans')
end
it 'displays subscription table', :js do
......
......@@ -13,6 +13,10 @@ describe 'Groups > Billing', :js do
date.strftime("%B %-d, %Y")
end
def subscription_table
'.subscription-table'
end
before do
stub_full_request("https://customers.gitlab.com/gitlab_plans?plan=#{plan}")
.to_return(status: 200, body: File.new(Rails.root.join('ee/spec/fixtures/gitlab_com_plans.json')))
......@@ -34,9 +38,11 @@ describe 'Groups > Billing', :js do
visit group_billings_path(group)
expect(page).to have_content("#{group.name} is currently using the Free plan")
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
expect(page).not_to have_link("Manage")
within subscription_table do
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
expect(page).not_to have_link("Manage")
end
end
end
......@@ -54,25 +60,29 @@ describe 'Groups > Billing', :js do
"#{EE::SUBSCRIPTIONS_URL}/gitlab/namespaces/#{group.id}/upgrade/bronze-external-id"
expect(page).to have_content("#{group.name} is currently using the Bronze plan")
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: upgrade_url)
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
within subscription_table do
expect(page).to have_content("start date #{formatted_date(subscription.start_date)}")
expect(page).to have_link("Upgrade", href: upgrade_url)
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
end
end
end
context 'with a legacy paid plan' do
let(:plan) { 'bronze' }
before do
group.update_attribute(:plan, bronze_plan)
let!(:subscription) do
create(:gitlab_subscription, end_date: 1.week.ago, namespace: group, hosted_plan: bronze_plan, seats: 15)
end
it 'shows the proper title and subscription data' do
visit group_billings_path(group)
expect(page).to have_content("#{group.name} is currently using the Bronze plan")
expect(page).not_to have_link("Upgrade")
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
within subscription_table do
expect(page).not_to have_link("Upgrade")
expect(page).to have_link("Manage", href: "#{EE::SUBSCRIPTIONS_URL}/subscriptions")
end
end
end
end
......@@ -2376,21 +2376,15 @@ msgstr ""
msgid "Billing"
msgstr ""
msgid "BillingPlans|%{group_name} is currently using the %{plan_link} plan."
msgid "BillingPlans|%{group_name} is currently using the %{plan_name} plan."
msgstr ""
msgid "BillingPlans|@%{user_name} you are currently using the %{plan_link} plan."
msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name} plan."
msgstr ""
msgid "BillingPlans|Congratulations, your new trial is activated"
msgstr ""
msgid "BillingPlans|Current plan"
msgstr ""
msgid "BillingPlans|Downgrade"
msgstr ""
msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}."
msgstr ""
......@@ -2415,15 +2409,15 @@ msgstr ""
msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}."
msgstr ""
msgid "BillingPlans|Upgrade"
msgstr ""
msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. %{learn_more_text}"
msgstr ""
msgid "BillingPlans|Your GitLab.com trial will <strong>expire after %{expiration_date}</strong>. You can learn more about GitLab.com Gold by reading about our %{features_link}."
msgstr ""
msgid "BillingPlans|billed annually at %{price_per_year}"
msgstr ""
msgid "BillingPlans|features"
msgstr ""
......@@ -2433,13 +2427,10 @@ msgstr ""
msgid "BillingPlans|monthly"
msgstr ""
msgid "BillingPlans|paid annually at %{price_per_year}"
msgstr ""
msgid "BillingPlans|per user"
msgstr ""
msgid "BillingPlan|Upgrade plan"
msgid "BillingPlan|Upgrade"
msgstr ""
msgid "Bitbucket Server Import"
......@@ -4798,6 +4789,9 @@ msgstr ""
msgid "Current Branch"
msgstr ""
msgid "Current Plan"
msgstr ""
msgid "Current Project"
msgstr ""
......
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