Commit 1938962d authored by Ragnar Hardarson's avatar Ragnar Hardarson Committed by Michael Kozono

Convert Billing Plan table to Card layout

Transform billing plans table to cards from Bootstrap.
parent 623a3db3
......@@ -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;
}
.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;
&-active {
background-color: $gray-light;
}
.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
- purchase_link = plan.purchase_link
- is_current_plan = purchase_link.action == 'current_plan'
.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")
.card-body
.price-per-month
.append-right-5
= number_to_plan_currency(plan.price_per_month)
%ul.billing-conditions
%ul.conditions.p-0.my-auto
%li= s_("BillingPlans|per user")
%li= s_("BillingPlans|monthly")
.price-per-year
- if plan.price_per_year > 0
.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 }
%hr.mt-3.mb-3
%ul.feature-list.bordered-list
- plan.features.each do |feature|
%li
- if feature.highlight
%strong= feature.title
- else
%ul.unstyled-list
- plan_feature_short_list(plan).each do |feature|
%li.p-0{ class: ("font-weight-bold" if feature.highlight) }
= feature.title
%li
%li.p-0.pt-3
- if plan.about_page_href
= link_to s_("BillingPlans|See all %{plan_name} features") % { plan_name: plan.name }, plan.about_page_href
- purchase_link = plan.purchase_link
= 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
.billing-plans.mt-5.row
- plans_data.each do |plan|
= render 'shared/billings/billing_plan', namespace: namespace, plan: 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,11 +38,13 @@ describe 'Groups > Billing', :js do
visit group_billings_path(group)
expect(page).to have_content("#{group.name} is currently using the Free plan")
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
context 'with a paid plan' do
let(:plan) { 'bronze' }
......@@ -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")
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")
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