[MM-52425] - Remove leftover Start Trial CTAs (#23099)

* [MM-52425] - Remove leftover Cloud Start Trial CTAs

* fix translations

* fix feature discovery

* fix feature restricted modal

* fix test

* feedback impl

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Allan Guwatudde 2023-04-27 16:30:09 +03:00 committed by GitHub
parent 0c6ac000d3
commit c87fe742be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 97 additions and 34 deletions

View File

@ -31,6 +31,7 @@ describe('components/feature_discovery', () => {
hadPrevCloudTrial={false} hadPrevCloudTrial={false}
isSubscriptionLoaded={true} isSubscriptionLoaded={true}
isPaidSubscription={false} isPaidSubscription={false}
cloudFreeDeprecated={false}
actions={{ actions={{
getPrevTrialLicense: jest.fn(), getPrevTrialLicense: jest.fn(),
getCloudSubscription: jest.fn(), getCloudSubscription: jest.fn(),
@ -58,6 +59,7 @@ describe('components/feature_discovery', () => {
isCloudTrial={false} isCloudTrial={false}
hadPrevCloudTrial={false} hadPrevCloudTrial={false}
isPaidSubscription={false} isPaidSubscription={false}
cloudFreeDeprecated={false}
isSubscriptionLoaded={true} isSubscriptionLoaded={true}
actions={{ actions={{
getPrevTrialLicense: jest.fn(), getPrevTrialLicense: jest.fn(),
@ -87,6 +89,7 @@ describe('components/feature_discovery', () => {
isCloudTrial={false} isCloudTrial={false}
hadPrevCloudTrial={false} hadPrevCloudTrial={false}
isSubscriptionLoaded={false} isSubscriptionLoaded={false}
cloudFreeDeprecated={false}
isPaidSubscription={false} isPaidSubscription={false}
actions={{ actions={{
getPrevTrialLicense: jest.fn(), getPrevTrialLicense: jest.fn(),

View File

@ -59,6 +59,7 @@ type Props = {
isSubscriptionLoaded: boolean; isSubscriptionLoaded: boolean;
isPaidSubscription: boolean; isPaidSubscription: boolean;
customer?: CloudCustomer; customer?: CloudCustomer;
cloudFreeDeprecated: boolean;
} }
type State = { type State = {
@ -205,6 +206,23 @@ export default class FeatureDiscovery extends React.PureComponent<Props, State>
extraClass='btn btn-primary' extraClass='btn btn-primary'
/> />
); );
if (this.props.cloudFreeDeprecated) {
ctaPrimaryButton = (
<button
className='btn btn-primary'
data-testid='featureDiscovery_primaryCallToAction'
onClick={() => {
trackEvent(TELEMETRY_CATEGORIES.SELF_HOSTED_ADMIN, 'click_enterprise_contact_sales_feature_discovery');
this.contactSalesFunc();
}}
>
<FormattedMessage
id='admin.ldap_feature_discovery_cloud.call_to_action.primary_sales'
defaultMessage='Contact sales'
/>
</button>
);
}
} else if (hadPrevCloudTrial) { } else if (hadPrevCloudTrial) {
// if it is cloud, but this account already had a free trial, then the cta button must be Upgrade now // if it is cloud, but this account already had a free trial, then the cta button must be Upgrade now
ctaPrimaryButton = ( ctaPrimaryButton = (
@ -259,7 +277,7 @@ export default class FeatureDiscovery extends React.PureComponent<Props, State>
/> />
</ExternalLink> </ExternalLink>
{gettingTrialError} {gettingTrialError}
{(!this.props.isCloud || canRequestCloudFreeTrial) && <p className='trial-legal-terms'> {((!this.props.isCloud || canRequestCloudFreeTrial) && !this.props.cloudFreeDeprecated) && <p className='trial-legal-terms'>
{canRequestCloudFreeTrial ? ( {canRequestCloudFreeTrial ? (
<FormattedMessage <FormattedMessage
id='admin.feature_discovery.trial-request.accept-terms.cloudFree' id='admin.feature_discovery.trial-request.accept-terms.cloudFree'

View File

@ -9,6 +9,7 @@ import {getCloudSubscription} from 'mattermost-redux/actions/cloud';
import {Action, GenericAction} from 'mattermost-redux/types/actions'; import {Action, GenericAction} from 'mattermost-redux/types/actions';
import {checkHadPriorTrial, getCloudCustomer} from 'mattermost-redux/selectors/entities/cloud'; import {checkHadPriorTrial, getCloudCustomer} from 'mattermost-redux/selectors/entities/cloud';
import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
import {ModalData} from 'types/actions'; import {ModalData} from 'types/actions';
import {GlobalState} from 'types/store'; import {GlobalState} from 'types/store';
@ -29,6 +30,7 @@ function mapStateToProps(state: GlobalState) {
const hasPriorTrial = checkHadPriorTrial(state); const hasPriorTrial = checkHadPriorTrial(state);
const isCloudTrial = subscription?.is_free_trial === 'true'; const isCloudTrial = subscription?.is_free_trial === 'true';
const customer = getCloudCustomer(state); const customer = getCloudCustomer(state);
const cloudFreeDeprecated = deprecateCloudFree(state);
return { return {
stats: state.entities.admin.analytics, stats: state.entities.admin.analytics,
prevTrialLicense: state.entities.admin.prevTrialLicense, prevTrialLicense: state.entities.admin.prevTrialLicense,
@ -38,6 +40,7 @@ function mapStateToProps(state: GlobalState) {
hadPrevCloudTrial: hasPriorTrial, hadPrevCloudTrial: hasPriorTrial,
isPaidSubscription: isCloud && license?.SkuShortName !== LicenseSkus.Starter && !isCloudTrial, isPaidSubscription: isCloud && license?.SkuShortName !== LicenseSkus.Starter && !isCloudTrial,
customer, customer,
cloudFreeDeprecated,
}; };
} }

View File

@ -13,6 +13,7 @@ import {checkHadPriorTrial} from 'mattermost-redux/selectors/entities/cloud';
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users'; import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {getPrevTrialLicense} from 'mattermost-redux/actions/admin'; import {getPrevTrialLicense} from 'mattermost-redux/actions/admin';
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
import CloudStartTrialButton from 'components/cloud_start_trial/cloud_start_trial_btn'; import CloudStartTrialButton from 'components/cloud_start_trial/cloud_start_trial_btn';
import StartTrialBtn from 'components/learn_more_trial_modal/start_trial_btn'; import StartTrialBtn from 'components/learn_more_trial_modal/start_trial_btn';
@ -59,6 +60,7 @@ const FeatureRestrictedModal = ({
dispatch(getPrevTrialLicense()); dispatch(getPrevTrialLicense());
}, []); }, []);
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
const hasCloudPriorTrial = useSelector(checkHadPriorTrial); const hasCloudPriorTrial = useSelector(checkHadPriorTrial);
const prevTrialLicense = useSelector((state: GlobalState) => state.entities.admin.prevTrialLicense); const prevTrialLicense = useSelector((state: GlobalState) => state.entities.admin.prevTrialLicense);
const hasSelfHostedPriorTrial = prevTrialLicense.IsLicensed === 'true'; const hasSelfHostedPriorTrial = prevTrialLicense.IsLicensed === 'true';
@ -100,7 +102,7 @@ const FeatureRestrictedModal = ({
const getTitle = () => { const getTitle = () => {
if (isSystemAdmin) { if (isSystemAdmin) {
return hasPriorTrial ? titleAdminPostTrial : titleAdminPreTrial; return (hasPriorTrial || cloudFreeDeprecated) ? titleAdminPostTrial : titleAdminPreTrial;
} }
return titleEndUser; return titleEndUser;
@ -108,13 +110,13 @@ const FeatureRestrictedModal = ({
const getMessage = () => { const getMessage = () => {
if (isSystemAdmin) { if (isSystemAdmin) {
return hasPriorTrial ? messageAdminPostTrial : messageAdminPreTrial; return (hasPriorTrial || cloudFreeDeprecated) ? messageAdminPostTrial : messageAdminPreTrial;
} }
return messageEndUser; return messageEndUser;
}; };
const showStartTrial = isSystemAdmin && !hasPriorTrial; const showStartTrial = isSystemAdmin && !hasPriorTrial && !cloudFreeDeprecated;
// define what is the secondary button text and action, by default will be the View Plan button // define what is the secondary button text and action, by default will be the View Plan button
let secondaryBtnMsg = formatMessage({id: 'feature_restricted_modal.button.plans', defaultMessage: 'View plans'}); let secondaryBtnMsg = formatMessage({id: 'feature_restricted_modal.button.plans', defaultMessage: 'View plans'});

View File

@ -14,6 +14,7 @@ import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/user
import {getSubscriptionProduct, checkHadPriorTrial} from 'mattermost-redux/selectors/entities/cloud'; import {getSubscriptionProduct, checkHadPriorTrial} from 'mattermost-redux/selectors/entities/cloud';
import {DispatchFunc} from 'mattermost-redux/types/actions'; import {DispatchFunc} from 'mattermost-redux/types/actions';
import {getPrevTrialLicense} from 'mattermost-redux/actions/admin'; import {getPrevTrialLicense} from 'mattermost-redux/actions/admin';
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
import {closeModal, openModal} from 'actions/views/modals'; import {closeModal, openModal} from 'actions/views/modals';
@ -43,6 +44,7 @@ export type Props = {
export default function InviteAs(props: Props) { export default function InviteAs(props: Props) {
const {formatMessage} = useIntl(); const {formatMessage} = useIntl();
const license = useSelector(getLicense); const license = useSelector(getLicense);
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
const dispatch = useDispatch<DispatchFunc>(); const dispatch = useDispatch<DispatchFunc>();
useEffect(() => { useEffect(() => {
@ -85,7 +87,7 @@ export default function InviteAs(props: Props) {
if (isFreeTrial) { if (isFreeTrial) {
ctaExtraContentMsg = formatMessage({id: 'free.professional_feature.professional', defaultMessage: 'Professional feature'}); ctaExtraContentMsg = formatMessage({id: 'free.professional_feature.professional', defaultMessage: 'Professional feature'});
} else { } else {
ctaExtraContentMsg = hasPriorTrial ? formatMessage({id: 'free.professional_feature.upgrade', defaultMessage: 'Upgrade'}) : formatMessage({id: 'free.professional_feature.try_free', defaultMessage: 'Professional feature- try it out free'}); ctaExtraContentMsg = (hasPriorTrial || cloudFreeDeprecated) ? formatMessage({id: 'free.professional_feature.upgrade', defaultMessage: 'Upgrade'}) : formatMessage({id: 'free.professional_feature.try_free', defaultMessage: 'Professional feature- try it out free'});
} }
const restrictedIndicator = ( const restrictedIndicator = (

View File

@ -33,6 +33,12 @@ describe('components/learn_more_trial_modal/learn_more_trial_modal', () => {
entities: { entities: {
users: { users: {
currentUserId: 'current_user_id', currentUserId: 'current_user_id',
profiles: {
current_user_id: {
id: 'current_user_id',
roles: '',
},
},
}, },
admin: { admin: {
analytics: { analytics: {

View File

@ -2,7 +2,7 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useState} from 'react'; import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {useIntl} from 'react-intl'; import {FormattedMessage, useIntl} from 'react-intl';
import {useSelector, useDispatch} from 'react-redux'; import {useSelector, useDispatch} from 'react-redux';
import {trackEvent} from 'actions/telemetry_actions'; import {trackEvent} from 'actions/telemetry_actions';
@ -16,10 +16,13 @@ import MonitorImacLikeSVG from 'components/common/svg_images_components/monitor_
import SystemRolesSVG from 'components/admin_console/feature_discovery/features/images/system_roles_svg'; import SystemRolesSVG from 'components/admin_console/feature_discovery/features/images/system_roles_svg';
import CloudStartTrialButton from 'components/cloud_start_trial/cloud_start_trial_btn'; import CloudStartTrialButton from 'components/cloud_start_trial/cloud_start_trial_btn';
import {BtnStyle} from 'components/common/carousel/carousel_button'; import {BtnStyle} from 'components/common/carousel/carousel_button';
import useOpenSalesLink from 'components/common/hooks/useOpenSalesLink';
import ExternalLink from 'components/external_link';
import {closeModal} from 'actions/views/modals'; import {closeModal} from 'actions/views/modals';
import {DispatchFunc} from 'mattermost-redux/types/actions'; import {DispatchFunc} from 'mattermost-redux/types/actions';
import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
import StartTrialBtn from './start_trial_btn'; import StartTrialBtn from './start_trial_btn';
@ -43,8 +46,11 @@ const LearnMoreTrialModal = (
const [embargoed, setEmbargoed] = useState(false); const [embargoed, setEmbargoed] = useState(false);
const dispatch = useDispatch<DispatchFunc>(); const dispatch = useDispatch<DispatchFunc>();
const [, salesLink] = useOpenSalesLink();
// Cloud conditions // Cloud conditions
const license = useSelector(getLicense); const license = useSelector(getLicense);
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
const isCloud = license?.Cloud === 'true'; const isCloud = license?.Cloud === 'true';
const handleEmbargoError = useCallback(() => { const handleEmbargoError = useCallback(() => {
@ -78,6 +84,20 @@ const LearnMoreTrialModal = (
extraClass={'btn btn-primary start-cloud-trial-btn'} extraClass={'btn btn-primary start-cloud-trial-btn'}
/> />
); );
if (cloudFreeDeprecated) {
startTrialBtn = (
<ExternalLink
location='learn_more_trial_modal'
href={salesLink}
className='btn btn-primary start-cloud-trial-btn'
>
<FormattedMessage
id='learn_more_trial_modal.contact_sales'
defaultMessage='Contact sales'
/>
</ExternalLink>
);
}
} }
const handleOnClose = useCallback(() => { const handleOnClose = useCallback(() => {

View File

@ -2,10 +2,11 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React from 'react'; import React from 'react';
import {useSelector} from 'react-redux';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import TrialBenefitsModalStepMore from 'components/trial_benefits_modal/trial_benefits_modal_step_more'; import TrialBenefitsModalStepMore from 'components/trial_benefits_modal/trial_benefits_modal_step_more';
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
import './learn_more_trial_modal_step.scss'; import './learn_more_trial_modal_step.scss';
import {AboutLinks, LicenseLinks} from 'utils/constants'; import {AboutLinks, LicenseLinks} from 'utils/constants';
@ -35,6 +36,7 @@ const LearnMoreTrialModalStep = (
buttonLabel, buttonLabel,
handleOnClose, handleOnClose,
}: LearnMoreTrialModalStepProps) => { }: LearnMoreTrialModalStepProps) => {
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
return ( return (
<div <div
id={`learnMoreTrialModalStep-${id}`} id={`learnMoreTrialModalStep-${id}`}
@ -59,32 +61,36 @@ const LearnMoreTrialModalStep = (
telemetryId={'learn_more_trial_modal'} telemetryId={'learn_more_trial_modal'}
/> />
)} )}
<div className='disclaimer'> {
<span> cloudFreeDeprecated ? '' : (
<FormattedMessage <div className='disclaimer'>
id='start_trial.modal.disclaimer' <span>
defaultMessage='By clicking “Start trial”, I agree to the <linkEvaluation>Mattermost Software and Services License Agreement</linkEvaluation>, <linkPrivacy>privacy policy</linkPrivacy> and receiving product emails.' <FormattedMessage
values={{ id='start_trial.modal.disclaimer'
linkEvaluation: (msg: React.ReactNode) => ( defaultMessage='By clicking “Start trial”, I agree to the <linkEvaluation>Mattermost Software and Services License Agreement</linkEvaluation>, <linkPrivacy>privacy policy</linkPrivacy> and receiving product emails.'
<ExternalLink values={{
href={LicenseLinks.SOFTWARE_SERVICES_LICENSE_AGREEMENT} linkEvaluation: (msg: React.ReactNode) => (
location='learn_more_trial_modal_step' <ExternalLink
> href={LicenseLinks.SOFTWARE_SERVICES_LICENSE_AGREEMENT}
{msg} location='learn_more_trial_modal_step'
</ExternalLink> >
), {msg}
linkPrivacy: (msg: React.ReactNode) => ( </ExternalLink>
<ExternalLink ),
href={AboutLinks.PRIVACY_POLICY} linkPrivacy: (msg: React.ReactNode) => (
location='learn_more_trial_modal_step' <ExternalLink
> href={AboutLinks.PRIVACY_POLICY}
{msg} location='learn_more_trial_modal_step'
</ExternalLink> >
), {msg}
}} </ExternalLink>
/> ),
</span> }}
</div> />
</span>
</div>
)
}
{bottomLeftMessage && ( {bottomLeftMessage && (
<div className='bottom-text-left-message'> <div className='bottom-text-left-message'>
{bottomLeftMessage} {bottomLeftMessage}

View File

@ -14,6 +14,7 @@ import {DispatchFunc} from 'mattermost-redux/types/actions';
import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users'; import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
import {getCloudSubscription, getSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud'; import {getCloudSubscription, getSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud';
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
import {openModal} from 'actions/views/modals'; import {openModal} from 'actions/views/modals';
@ -32,6 +33,7 @@ const MenuCloudTrial = ({id}: Props): JSX.Element | null => {
const subscription = useSelector(getCloudSubscription); const subscription = useSelector(getCloudSubscription);
const subscriptionProduct = useSelector(getSubscriptionProduct); const subscriptionProduct = useSelector(getSubscriptionProduct);
const license = useSelector(getLicense); const license = useSelector(getLicense);
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
const dispatch = useDispatch<DispatchFunc>(); const dispatch = useDispatch<DispatchFunc>();
const isCloud = license?.Cloud === 'true'; const isCloud = license?.Cloud === 'true';
@ -109,7 +111,7 @@ const MenuCloudTrial = ({id}: Props): JSX.Element | null => {
); );
// menu option displayed when the workspace is not running any trial // menu option displayed when the workspace is not running any trial
const noFreeTrialContent = noPriorTrial ? ( const noFreeTrialContent = (noPriorTrial && !cloudFreeDeprecated) ? (
<FormattedMessage <FormattedMessage
id='menu.cloudFree.priorTrial.tryEnterprise' id='menu.cloudFree.priorTrial.tryEnterprise'
defaultMessage='Interested in a limitless plan with high-security features? <openModalLink>Try Enterprise free for 30 days</openModalLink>' defaultMessage='Interested in a limitless plan with high-security features? <openModalLink>Try Enterprise free for 30 days</openModalLink>'

View File

@ -4036,6 +4036,7 @@
"learn_more_about_trial.modal.useSsoDescription": "Sign on quickly and easily with our SSO feature that works with OpenID, SAML, Google, and O365.", "learn_more_about_trial.modal.useSsoDescription": "Sign on quickly and easily with our SSO feature that works with OpenID, SAML, Google, and O365.",
"learn_more_about_trial.modal.useSsoTitle": "Use SSO (with OpenID, SAML, Google, O365)", "learn_more_about_trial.modal.useSsoTitle": "Use SSO (with OpenID, SAML, Google, O365)",
"learn_more_trial_modal_step.learnMoreAboutFeature": "Learn more about this feature.", "learn_more_trial_modal_step.learnMoreAboutFeature": "Learn more about this feature.",
"learn_more_trial_modal.contact_sales": "Contact Sales",
"learn_more_trial_modal.pretitle": "With Enterprise, you can...", "learn_more_trial_modal.pretitle": "With Enterprise, you can...",
"leave_private_channel_modal.leave": "Yes, leave channel", "leave_private_channel_modal.leave": "Yes, leave channel",
"leave_private_channel_modal.message": "Are you sure you wish to leave the private channel {channel}? You must be re-invited in order to re-join this channel in the future.", "leave_private_channel_modal.message": "Are you sure you wish to leave the private channel {channel}? You must be re-invited in order to re-join this channel in the future.",