Commit 3f1e96e6 authored by Jay Swain's avatar Jay Swain

Update messaging and styling for renewal banner

Update the messaging and styling of the renewal banner. This is one of a
series of commits to getting the banner to be more helpful for customers
who are trying to renew.

part of: https://gitlab.com/gitlab-org/growth/product/-/issues/102
parent e52da1e7
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
.border-color-blue-300 { border-color: $blue-300; } .border-color-blue-300 { border-color: $blue-300; }
.border-color-default { border-color: $border-color; } .border-color-default { border-color: $border-color; }
.border-bottom-color-default { border-bottom-color: $border-color; } .border-bottom-color-default { border-bottom-color: $border-color; }
.border-radius-default { border-radius: $border-radius-default; }
.box-shadow-default { box-shadow: 0 2px 4px 0 $black-transparent; } .box-shadow-default { box-shadow: 0 2px 4px 0 $black-transparent; }
.gl-children-ml-sm-3 > * { .gl-children-ml-sm-3 > * {
......
...@@ -17,36 +17,22 @@ ...@@ -17,36 +17,22 @@
/* Trial Banner */ /* Trial Banner */
.gitlab-ee-license-banner.alert { .gitlab-ee-license-banner.alert {
padding: 15px 35px;
position: relative;
background: $red-400;
color: $white-light;
text-align: center;
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
padding: 10px 35px; img {
} width: 30px;
}
.close { a {
color: $white-dark; margin-left: 0 !important;
opacity: 0.7;
position: absolute;
top: 12px;
right: $gl-padding;
&:hover { &:last-child {
color: $black; margin-top: 1rem;
}
} }
} }
p a { .close {
text-decoration: none; opacity: 0.6;
font-weight: $gl-font-weight-bold;
&:hover {
color: $white-dark;
text-decoration: underline;
}
} }
} }
......
...@@ -25,12 +25,8 @@ module LicenseHelper ...@@ -25,12 +25,8 @@ module LicenseHelper
message = [] message = []
is_trial = current_license.trial? message << license_message_subject
message << expiration_blocking_message
message << license_message_subject(is_trial: is_trial)
message << trial_purchase_message if is_trial
message << expiration_blocking_message(is_admin: is_admin)
message << renewal_instructions_message unless is_trial
message.reject {|string| string.blank? }.join(' ').html_safe message.reject {|string| string.blank? }.join(' ').html_safe
end end
...@@ -110,73 +106,43 @@ module LicenseHelper ...@@ -110,73 +106,43 @@ module LicenseHelper
User.active.count User.active.count
end end
def license_message_subject(is_trial:) def license_message_subject
message = []
if current_license.expired? if current_license.expired?
expires_at = current_license.expires_at message = if current_license.block_changes?
_('Your subscription has been downgraded')
message << if is_trial else
_('Your trial license expired on %{expires_at}.') % { expires_at: expires_at } _('Your subscription expired!')
else end
_('Your license expired on %{expires_at}.') % { expires_at: expires_at }
end
else else
remaining_days = pluralize(current_license.remaining_days, 'day') remaining_days = pluralize(current_license.remaining_days, 'day')
message << if is_trial message = _('Your subscription will expire in %{remaining_days}') % { remaining_days: remaining_days }
_('Your trial license will expire in %{remaining_days}.') % { remaining_days: remaining_days }
else
_('Your license will expire in %{remaining_days}.') % { remaining_days: remaining_days }
end
end end
message.join(' ') message = content_tag(:strong, message)
end
def trial_purchase_message
buy_now_url = ::EE::SUBSCRIPTIONS_PLANS_URL
buy_now_link_start = "<a href='#{buy_now_url}' target='_blank' rel='noopener'>".html_safe
link_end = '</a>'.html_safe
_('%{buy_now_link_start}Buy now!%{link_end}') % { buy_now_link_start: buy_now_link_start, link_end: link_end } content_tag(:p, message, class: 'mb-2')
end end
def expiration_blocking_message(is_admin:) def expiration_blocking_message
return '' unless current_license.expired? && current_license.will_block_changes? return '' unless current_license.will_block_changes?
message = []
message << if current_license.block_changes?
_('Pushing code and creation of issues and merge requests has been disabled.')
else
_('Pushing code and creation of issues and merge requests will be disabled on %{disabled_on}.') % { disabled_on: current_license.block_changes_at }
end
message << if is_admin
if current_license.block_changes? plan_name = current_license.plan.titleize
_('Upload a new license in the admin area to restore service.') strong = "<strong>".html_safe
else strong_close = "</strong>".html_safe
_('Upload a new license in the admin area to ensure uninterrupted service.')
end
else
if current_license.block_changes?
_('Ask an admin to upload a new license to restore service.')
else
_('Ask an admin to upload a new license to ensure uninterrupted service.')
end
end
message.join(' ')
end
def renewal_instructions_message if current_license.expired?
renewal_faq_url = 'https://docs.gitlab.com/ee/subscriptions/#renew-your-subscription' if current_license.block_changes?
message = _('You didn\'t renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan.') % { plan_name: plan_name, strong: strong, strong_close: strong_close }
else
remaining_days = pluralize((current_license.block_changes_at - Date.today).to_i, 'day')
renewal_faq_link_start = "<a href='#{renewal_faq_url}' target='_blank' rel='noopener'>".html_safe message = _('No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription.') % { plan_name: plan_name, remaining_days: remaining_days, strong: strong, strong_close: strong_close }
link_end = '</a>'.html_safe end
else
message = _('Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features.') % { expires_on: current_license.expires_at.strftime("%Y-%m-%d"), plan_name: plan_name, strong: strong, strong_close: strong_close }
end
_('For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}') % { link_start: renewal_faq_link_start, link_end: link_end } content_tag(:p, message.html_safe)
end end
end end
- if license_message.present? - if license_message.present?
.alert.alert-dismissible.gitlab-ee-license-banner.hidden.js-gitlab-ee-license-banner{ role: 'alert', data: { license_expiry: current_license.expires_at } } .container-fluid.container-limited.pt-3
-# Show dismiss button only when license expiry is about trial license .alert.alert-dismissible.gitlab-ee-license-banner.hidden.js-gitlab-ee-license-banner.pb-5.border-width-1px.border-style-solid.border-color-default.border-radius-default{ role: 'alert', data: { license_expiry: current_license.expires_at } }
- if current_license.trial? %button.close.p-2{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'Dismiss banner' }
%button.close{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'Dismiss banner' } %span{ 'aria-hidden' => 'true' }
= icon('times', 'aria-hidden' => 'true') = sprite_icon('merge-request-close-m', size: 24)
%p .d-flex.flex-row
= license_message .pr-4.pl-3.pt-2
- if current_license.expired?
- if current_license.block_changes?
= image_tag('illustrations/subscription-downgraded.svg')
- else
= image_tag('illustrations/subscription-cancelled.svg')
- else
= image_tag('illustrations/subscription-warning.svg')
.text-left.pt-2
= license_message
- if current_license.block_changes?
= link_to 'Upgrade your plan', 'https://customers.gitlab.com/subscriptions/my_renewal', class: 'btn btn-primary'
- else
= link_to 'Renew subscription', 'https://customers.gitlab.com/subscriptions/my_renewal', class: 'btn btn-primary'
= link_to "Thats ok, I don't want to renew", '#', data: { 'dismiss' => 'alert' }, 'aira-label' => 'Dismiss banner', class: 'btn btn-inverted-secondary ml-2'
---
title: Update renewal banner messaging and styling
merge_request: 27530
author:
type: changed
...@@ -24,31 +24,6 @@ describe "Admin views license" do ...@@ -24,31 +24,6 @@ describe "Admin views license" do
end end
end end
context "when license is trial" do
let_it_be(:license) { create(:license, trial: true) }
before do
visit(admin_license_path)
end
it "shows expiration duration with license type" do
page.within(".js-license-info-panel") do
expect(page).to have_content("Expires: Free trial will expire in")
end
end
context "when license is expired" do
let_it_be(:license) { create(:license, trial: true, expired: true) }
it "does not mention blocking of changes" do
page.within(".gitlab-ee-license-banner") do
expect(page).to have_content("Your trial license expired on")
.and have_no_content("Pushing code and creation of issues and merge requests has been disabled")
end
end
end
end
context "when license is regular" do context "when license is regular" do
let_it_be(:license) { create(:license) } let_it_be(:license) { create(:license) }
...@@ -56,23 +31,15 @@ describe "Admin views license" do ...@@ -56,23 +31,15 @@ describe "Admin views license" do
visit(admin_license_path) visit(admin_license_path)
end end
it "shows only expiration duration" do
expect(page).to have_content(license.licensee.each_value.first)
page.within(".js-license-info-panel") do
expect(page).not_to have_content("Expires: Free trial will expire in")
end
end
context "when license expired" do context "when license expired" do
let_it_be(:license) { build(:license, data: build(:gitlab_license, expires_at: Date.yesterday).export).save(validate: false) } let_it_be(:license) { build(:license, data: build(:gitlab_license, expires_at: Date.yesterday).export).save(validate: false) }
it { expect(page).to have_content("Your license expired") } it { expect(page).to have_content("Your subscription expired!") }
context "when license blocks changes" do context "when license blocks changes" do
let_it_be(:license) { build(:license, data: build(:gitlab_license, expires_at: Date.yesterday, block_changes_at: Date.today).export).save(validate: false) } let_it_be(:license) { build(:license, data: build(:gitlab_license, expires_at: Date.yesterday, block_changes_at: Date.today).export).save(validate: false) }
it { expect(page).to have_content "Pushing code and creation of issues and merge requests has been disabled." } it { expect(page).to have_content "You didn't renew your Starter subscription so it was downgraded to the GitLab Core Plan" }
end end
end end
......
...@@ -13,9 +13,13 @@ describe LicenseHelper do ...@@ -13,9 +13,13 @@ describe LicenseHelper do
context 'license installed' do context 'license installed' do
let(:license) { double(:license) } let(:license) { double(:license) }
let(:expired_date) { Time.utc(2020, 3, 9, 10) }
let(:today) { Time.utc(2020, 3, 7, 10) }
before do before do
allow(License).to receive(:current).and_return(license) allow(License).to receive(:current).and_return(license)
allow(license).to receive(:plan).and_return('ultimate')
allow(license).to receive(:expires_at).and_return(expired_date)
end end
context 'license is notify admins' do context 'license is notify admins' do
...@@ -27,108 +31,76 @@ describe LicenseHelper do ...@@ -27,108 +31,76 @@ describe LicenseHelper do
let(:signed_in) { true } let(:signed_in) { true }
let(:is_admin) { true } let(:is_admin) { true }
context 'license is trial' do context 'license expired' do
let(:expired_date) { Time.utc(2020, 3, 9).to_date }
before do before do
allow(license).to receive(:trial?).and_return(true) allow(license).to receive(:expired?).and_return(true)
allow(license).to receive(:expires_at).and_return(expired_date)
end end
context 'license expired' do context 'and it will block changes when it expires' do
let(:expired_date) { Date.parse('2020-03-09') }
before do before do
allow(license).to receive(:expired?).and_return(true) allow(license).to receive(:will_block_changes?).and_return(true)
allow(license).to receive(:expires_at).and_return(expired_date)
end
it 'has a nice subject' do
allow(license).to receive(:will_block_changes?).and_return(false)
regex = /Your trial license expired on 2020-03-09\. <a href=\'https?:\/\/.*\/plans\' target=\'_blank\' rel=\'noopener\'>Buy now!<\/a>/
expect(subject).to match(regex)
end end
context 'and it will block changes when it expires' do context 'and its currently blocking changes' do
before do before do
allow(license).to receive(:will_block_changes?).and_return(true) allow(license).to receive(:block_changes?).and_return(true)
allow(license).to receive(:block_changes_at).and_return(expired_date)
end end
context 'and its currently blocking changes' do it 'has a nice subject' do
before do allow(license).to receive(:will_block_changes?).and_return(false)
allow(license).to receive(:block_changes?).and_return(true)
end
it 'has an expiration blocking message' do expect(subject).to have_text('Your subscription has been downgraded')
regex = <<~HEREDOC.chomp end
Pushing code and creation of issues and merge requests has been disabled. Upload a new license in the admin area to restore service.
HEREDOC
expect(subject).to match(regex) it 'has an expiration blocking message' do
Timecop.freeze(today) do
expect(subject).to have_text("You didn't renew your Ultimate subscription so it was downgraded to the GitLab Core Plan")
end end
end
end
context 'not admin' do context 'and its NOT currently blocking changes' do
let(:is_admin) { false } before do
allow(license).to receive(:block_changes?).and_return(false)
it 'has an expiration blocking message' do end
allow(license).to receive(:notify_users?).and_return(true)
regex = <<~HEREDOC.chomp it 'has a nice subject' do
Pushing code and creation of issues and merge requests has been disabled. Ask an admin to upload a new license to restore service. allow(license).to receive(:will_block_changes?).and_return(false)
HEREDOC
expect(subject).to match(regex) expect(subject).to have_text('Your subscription expired!')
end
end
end end
context 'and its NOT currently blocking changes' do it 'has an expiration blocking message' do
it 'has an expiration blocking message' do allow(license).to receive(:block_changes_at).and_return(expired_date)
allow(license).to receive(:block_changes?).and_return(false)
allow(license).to receive(:block_changes_at).and_return(expired_date)
regex = <<~HEREDOC.chomp Timecop.freeze(today) do
Pushing code and creation of issues and merge requests will be disabled on 2020-03-09. Upload a new license in the admin area to ensure uninterrupted service. expect(subject).to have_text('No worries, you can still use all the Ultimate features for now. You have 2 days to renew your subscription.')
HEREDOC
expect(subject).to match(regex)
end end
end end
end end
end end
context 'license NOT expired' do
it 'has a nice subject' do
allow(license).to receive(:expired?).and_return(false)
allow(license).to receive(:remaining_days).and_return(4)
allow(license).to receive(:will_block_changes?).and_return(false)
regex = /Your trial license will expire in 4 days\. <a href=\'https?:\/\/.*\/plans\' target=\'_blank\' rel=\'noopener\'>Buy now!<\/a>/
expect(subject).to match(regex)
end
end
end end
context 'license is NOT trial' do context 'license NOT expired' do
let(:expired_date) { Date.parse('2020-03-09') }
before do before do
allow(license).to receive(:trial?).and_return(false) allow(license).to receive(:expired?).and_return(false)
allow(license).to receive(:expired?).and_return(true) allow(license).to receive(:remaining_days).and_return(4)
allow(license).to receive(:expires_at).and_return(expired_date) allow(license).to receive(:will_block_changes?).and_return(true)
allow(license).to receive(:will_block_changes?).and_return(false) allow(license).to receive(:block_changes_at).and_return(expired_date)
end end
it 'has a nice subject' do it 'has a nice subject' do
regex = <<~HEREDOC.chomp expect(subject).to have_text('Your subscription will expire in 4 days')
Your license expired on 2020-03-09. For renewal instructions <a href='https://docs.gitlab.com/ee/subscriptions/#renew-your-subscription' target='_blank' rel='noopener'>view our Licensing FAQ.</a>
HEREDOC
expect(subject).to match(regex)
end end
it 'does not have buy now link' do it 'has an expiration blocking message' do
expect(subject).not_to include('Buy now!') Timecop.freeze(today) do
expect(subject).to have_text('Your Ultimate subscription will expire on 2020-03-09. After that, you will not to be able to create issues or merge requests as well as many other features.')
end
end end
end end
end end
......
...@@ -217,9 +217,6 @@ msgstr "" ...@@ -217,9 +217,6 @@ msgstr ""
msgid "%{authorsName}'s thread" msgid "%{authorsName}'s thread"
msgstr "" msgstr ""
msgid "%{buy_now_link_start}Buy now!%{link_end}"
msgstr ""
msgid "%{commit_author_link} authored %{commit_timeago}" msgid "%{commit_author_link} authored %{commit_timeago}"
msgstr "" msgstr ""
...@@ -2409,12 +2406,6 @@ msgstr "" ...@@ -2409,12 +2406,6 @@ msgstr ""
msgid "Ascending" msgid "Ascending"
msgstr "" msgstr ""
msgid "Ask an admin to upload a new license to ensure uninterrupted service."
msgstr ""
msgid "Ask an admin to upload a new license to restore service."
msgstr ""
msgid "Ask your group maintainer to set up a group Runner." msgid "Ask your group maintainer to set up a group Runner."
msgstr "" msgstr ""
...@@ -8962,9 +8953,6 @@ msgstr "" ...@@ -8962,9 +8953,6 @@ msgstr ""
msgid "For public projects, anyone can view pipelines and access job details (output logs and artifacts)" msgid "For public projects, anyone can view pipelines and access job details (output logs and artifacts)"
msgstr "" msgstr ""
msgid "For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}"
msgstr ""
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "" msgstr ""
...@@ -13379,6 +13367,9 @@ msgstr "" ...@@ -13379,6 +13367,9 @@ msgstr ""
msgid "No webhooks found, add one in the form above." msgid "No webhooks found, add one in the form above."
msgstr "" msgstr ""
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} to renew your subscription."
msgstr ""
msgid "No, directly import the existing email addresses and usernames." msgid "No, directly import the existing email addresses and usernames."
msgstr "" msgstr ""
...@@ -16177,12 +16168,6 @@ msgstr "" ...@@ -16177,12 +16168,6 @@ msgstr ""
msgid "Pushes" msgid "Pushes"
msgstr "" msgstr ""
msgid "Pushing code and creation of issues and merge requests has been disabled."
msgstr ""
msgid "Pushing code and creation of issues and merge requests will be disabled on %{disabled_on}."
msgstr ""
msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"." msgid "PushoverService|%{user_name} deleted branch \"%{ref}\"."
msgstr "" msgstr ""
...@@ -21618,12 +21603,6 @@ msgstr "" ...@@ -21618,12 +21603,6 @@ msgstr ""
msgid "Upload a certificate for your domain with all intermediates" msgid "Upload a certificate for your domain with all intermediates"
msgstr "" msgstr ""
msgid "Upload a new license in the admin area to ensure uninterrupted service."
msgstr ""
msgid "Upload a new license in the admin area to restore service."
msgstr ""
msgid "Upload a private key for your certificate" msgid "Upload a private key for your certificate"
msgstr "" msgstr ""
...@@ -23017,6 +22996,9 @@ msgstr "" ...@@ -23017,6 +22996,9 @@ msgstr ""
msgid "You could not create a new trigger." msgid "You could not create a new trigger."
msgstr "" msgstr ""
msgid "You didn't renew your %{strong}%{plan_name}%{strong_close} subscription so it was downgraded to the GitLab Core Plan."
msgstr ""
msgid "You do not have any subscriptions yet" msgid "You do not have any subscriptions yet"
msgstr "" msgstr ""
...@@ -23236,6 +23218,9 @@ msgstr "" ...@@ -23236,6 +23218,9 @@ msgstr ""
msgid "YouTube" msgid "YouTube"
msgstr "" msgstr ""
msgid "Your %{strong}%{plan_name}%{strong_close} subscription will expire on %{strong}%{expires_on}%{strong_close}. After that, you will not to be able to create issues or merge requests as well as many other features."
msgstr ""
msgid "Your Commit Email will be used for web based operations, such as edits and merges." msgid "Your Commit Email will be used for web based operations, such as edits and merges."
msgstr "" msgstr ""
...@@ -23356,15 +23341,9 @@ msgstr "" ...@@ -23356,15 +23341,9 @@ msgstr ""
msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email." msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
msgstr "" msgstr ""
msgid "Your license expired on %{expires_at}."
msgstr ""
msgid "Your license is valid from" msgid "Your license is valid from"
msgstr "" msgstr ""
msgid "Your license will expire in %{remaining_days}."
msgstr ""
msgid "Your message here" msgid "Your message here"
msgstr "" msgstr ""
...@@ -23395,10 +23374,13 @@ msgstr "" ...@@ -23395,10 +23374,13 @@ msgstr ""
msgid "Your request for access has been queued for review." msgid "Your request for access has been queued for review."
msgstr "" msgstr ""
msgid "Your trial license expired on %{expires_at}." msgid "Your subscription expired!"
msgstr ""
msgid "Your subscription has been downgraded"
msgstr "" msgstr ""
msgid "Your trial license will expire in %{remaining_days}." msgid "Your subscription will expire in %{remaining_days}"
msgstr "" msgstr ""
msgid "Zoom meeting added" msgid "Zoom meeting added"
......
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