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 @@
.border-color-blue-300 { border-color: $blue-300; }
.border-color-default { border-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; }
.gl-children-ml-sm-3 > * {
......
......@@ -17,36 +17,22 @@
/* Trial Banner */
.gitlab-ee-license-banner.alert {
padding: 15px 35px;
position: relative;
background: $red-400;
color: $white-light;
text-align: center;
@include media-breakpoint-down(md) {
padding: 10px 35px;
}
img {
width: 30px;
}
.close {
color: $white-dark;
opacity: 0.7;
position: absolute;
top: 12px;
right: $gl-padding;
a {
margin-left: 0 !important;
&:hover {
color: $black;
&:last-child {
margin-top: 1rem;
}
}
}
p a {
text-decoration: none;
font-weight: $gl-font-weight-bold;
&:hover {
color: $white-dark;
text-decoration: underline;
}
.close {
opacity: 0.6;
}
}
......
......@@ -25,12 +25,8 @@ module LicenseHelper
message = []
is_trial = current_license.trial?
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 << license_message_subject
message << expiration_blocking_message
message.reject {|string| string.blank? }.join(' ').html_safe
end
......@@ -110,73 +106,43 @@ module LicenseHelper
User.active.count
end
def license_message_subject(is_trial:)
message = []
def license_message_subject
if current_license.expired?
expires_at = current_license.expires_at
message << if is_trial
_('Your trial license expired on %{expires_at}.') % { expires_at: expires_at }
else
_('Your license expired on %{expires_at}.') % { expires_at: expires_at }
end
message = if current_license.block_changes?
_('Your subscription has been downgraded')
else
_('Your subscription expired!')
end
else
remaining_days = pluralize(current_license.remaining_days, 'day')
message << if is_trial
_('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
message = _('Your subscription will expire in %{remaining_days}') % { remaining_days: remaining_days }
end
message.join(' ')
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
message = content_tag(:strong, message)
_('%{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
def expiration_blocking_message(is_admin:)
return '' unless current_license.expired? && 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
def expiration_blocking_message
return '' unless current_license.will_block_changes?
if current_license.block_changes?
_('Upload a new license in the admin area to restore service.')
else
_('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
plan_name = current_license.plan.titleize
strong = "<strong>".html_safe
strong_close = "</strong>".html_safe
def renewal_instructions_message
renewal_faq_url = 'https://docs.gitlab.com/ee/subscriptions/#renew-your-subscription'
if current_license.expired?
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
link_end = '</a>'.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 }
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
- 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 } }
-# Show dismiss button only when license expiry is about trial license
- if current_license.trial?
%button.close{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'Dismiss banner' }
= icon('times', 'aria-hidden' => 'true')
%p
= license_message
.container-fluid.container-limited.pt-3
.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 } }
%button.close.p-2{ type: 'button', 'data-dismiss' => 'alert', 'aria-label' => 'Dismiss banner' }
%span{ 'aria-hidden' => 'true' }
= sprite_icon('merge-request-close-m', size: 24)
.d-flex.flex-row
.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
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
let_it_be(:license) { create(:license) }
......@@ -56,23 +31,15 @@ describe "Admin views license" do
visit(admin_license_path)
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
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
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
......
......@@ -13,9 +13,13 @@ describe LicenseHelper do
context 'license installed' do
let(:license) { double(:license) }
let(:expired_date) { Time.utc(2020, 3, 9, 10) }
let(:today) { Time.utc(2020, 3, 7, 10) }
before do
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
context 'license is notify admins' do
......@@ -27,108 +31,76 @@ describe LicenseHelper do
let(:signed_in) { 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
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
context 'license expired' do
let(:expired_date) { Date.parse('2020-03-09') }
context 'and it will block changes when it expires' do
before do
allow(license).to receive(:expired?).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)
allow(license).to receive(:will_block_changes?).and_return(true)
end
context 'and it will block changes when it expires' do
context 'and its currently blocking changes' 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
context 'and its currently blocking changes' do
before do
allow(license).to receive(:block_changes?).and_return(true)
end
it 'has a nice subject' do
allow(license).to receive(:will_block_changes?).and_return(false)
it 'has an expiration blocking message' do
regex = <<~HEREDOC.chomp
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 have_text('Your subscription has been downgraded')
end
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
context 'not admin' do
let(:is_admin) { false }
it 'has an expiration blocking message' do
allow(license).to receive(:notify_users?).and_return(true)
context 'and its NOT currently blocking changes' do
before do
allow(license).to receive(:block_changes?).and_return(false)
end
regex = <<~HEREDOC.chomp
Pushing code and creation of issues and merge requests has been disabled. Ask an admin to upload a new license to restore service.
HEREDOC
it 'has a nice subject' do
allow(license).to receive(:will_block_changes?).and_return(false)
expect(subject).to match(regex)
end
end
expect(subject).to have_text('Your subscription expired!')
end
context 'and its NOT currently blocking changes' do
it 'has an expiration blocking message' do
allow(license).to receive(:block_changes?).and_return(false)
allow(license).to receive(:block_changes_at).and_return(expired_date)
it 'has an expiration blocking message' do
allow(license).to receive(:block_changes_at).and_return(expired_date)
regex = <<~HEREDOC.chomp
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.
HEREDOC
expect(subject).to match(regex)
Timecop.freeze(today) do
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.')
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
context 'license is NOT trial' do
let(:expired_date) { Date.parse('2020-03-09') }
context 'license NOT expired' do
before do
allow(license).to receive(:trial?).and_return(false)
allow(license).to receive(:expired?).and_return(true)
allow(license).to receive(:expires_at).and_return(expired_date)
allow(license).to receive(:will_block_changes?).and_return(false)
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(true)
allow(license).to receive(:block_changes_at).and_return(expired_date)
end
it 'has a nice subject' do
regex = <<~HEREDOC.chomp
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)
expect(subject).to have_text('Your subscription will expire in 4 days')
end
it 'does not have buy now link' do
expect(subject).not_to include('Buy now!')
it 'has an expiration blocking message' do
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
......
......@@ -217,9 +217,6 @@ msgstr ""
msgid "%{authorsName}'s thread"
msgstr ""
msgid "%{buy_now_link_start}Buy now!%{link_end}"
msgstr ""
msgid "%{commit_author_link} authored %{commit_timeago}"
msgstr ""
......@@ -2409,12 +2406,6 @@ msgstr ""
msgid "Ascending"
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."
msgstr ""
......@@ -8962,9 +8953,6 @@ msgstr ""
msgid "For public projects, anyone can view pipelines and access job details (output logs and artifacts)"
msgstr ""
msgid "For renewal instructions %{link_start}view our Licensing FAQ.%{link_end}"
msgstr ""
msgid "Forgot your password?"
msgstr ""
......@@ -13379,6 +13367,9 @@ msgstr ""
msgid "No webhooks found, add one in the form above."
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."
msgstr ""
......@@ -16177,12 +16168,6 @@ msgstr ""
msgid "Pushes"
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}\"."
msgstr ""
......@@ -21618,12 +21603,6 @@ msgstr ""
msgid "Upload a certificate for your domain with all intermediates"
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"
msgstr ""
......@@ -23017,6 +22996,9 @@ msgstr ""
msgid "You could not create a new trigger."
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"
msgstr ""
......@@ -23236,6 +23218,9 @@ msgstr ""
msgid "YouTube"
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."
msgstr ""
......@@ -23356,15 +23341,9 @@ msgstr ""
msgid "Your issues will be imported in the background. Once finished, you'll get a confirmation email."
msgstr ""
msgid "Your license expired on %{expires_at}."
msgstr ""
msgid "Your license is valid from"
msgstr ""
msgid "Your license will expire in %{remaining_days}."
msgstr ""
msgid "Your message here"
msgstr ""
......@@ -23395,10 +23374,13 @@ msgstr ""
msgid "Your request for access has been queued for review."
msgstr ""
msgid "Your trial license expired on %{expires_at}."
msgid "Your subscription expired!"
msgstr ""
msgid "Your subscription has been downgraded"
msgstr ""
msgid "Your trial license will expire in %{remaining_days}."
msgid "Your subscription will expire in %{remaining_days}"
msgstr ""
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