[CLD-6870] Remove CloudFreeDeprecated feature flag (#27675)
* Remove CloudFreeDeprecated feature flag * Fixes for CI pipelines * Remove CloudReverseTrial feature flag and accompanying code (#27676) Co-authored-by: Mattermost Build <build@mattermost.com> --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
@@ -36,8 +36,6 @@ type FeatureFlags struct {
|
|||||||
|
|
||||||
DeprecateCloudFree bool
|
DeprecateCloudFree bool
|
||||||
|
|
||||||
CloudReverseTrial bool
|
|
||||||
|
|
||||||
EnableExportDirectDownload bool
|
EnableExportDirectDownload bool
|
||||||
|
|
||||||
MoveThreadsEnabled bool
|
MoveThreadsEnabled bool
|
||||||
@@ -69,7 +67,6 @@ func (f *FeatureFlags) SetDefaults() {
|
|||||||
f.DeprecateCloudFree = false
|
f.DeprecateCloudFree = false
|
||||||
f.WysiwygEditor = false
|
f.WysiwygEditor = false
|
||||||
f.OnboardingTourTips = true
|
f.OnboardingTourTips = true
|
||||||
f.CloudReverseTrial = false
|
|
||||||
f.EnableExportDirectDownload = false
|
f.EnableExportDirectDownload = false
|
||||||
f.MoveThreadsEnabled = false
|
f.MoveThreadsEnabled = false
|
||||||
f.StreamlinedMarketplace = true
|
f.StreamlinedMarketplace = true
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ const initialState = {
|
|||||||
general: {
|
general: {
|
||||||
config: {
|
config: {
|
||||||
CWSURL: '',
|
CWSURL: '',
|
||||||
FeatureFlagDeprecateCloudFree: 'true',
|
|
||||||
},
|
},
|
||||||
license: {
|
license: {
|
||||||
IsLicensed: 'true',
|
IsLicensed: 'true',
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import type {GlobalState} from '@mattermost/types/store';
|
|||||||
|
|
||||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||||
import {getSubscriptionProduct as selectSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud';
|
import {getSubscriptionProduct as selectSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud';
|
||||||
import {deprecateCloudFree, get as getPreference} from 'mattermost-redux/selectors/entities/preferences';
|
import {get as getPreference} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import AnnouncementBar from 'components/announcement_bar/default_announcement_bar';
|
import AnnouncementBar from 'components/announcement_bar/default_announcement_bar';
|
||||||
@@ -48,7 +48,6 @@ export const ToPaidPlanBannerDismissable = () => {
|
|||||||
const currentUser = useSelector(getCurrentUser);
|
const currentUser = useSelector(getCurrentUser);
|
||||||
const isAdmin = useSelector(isCurrentUserSystemAdmin);
|
const isAdmin = useSelector(isCurrentUserSystemAdmin);
|
||||||
const product = useSelector(selectSubscriptionProduct);
|
const product = useSelector(selectSubscriptionProduct);
|
||||||
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
|
|
||||||
const currentProductStarter = product?.sku === CloudProducts.STARTER;
|
const currentProductStarter = product?.sku === CloudProducts.STARTER;
|
||||||
|
|
||||||
const now = moment(Date.now());
|
const now = moment(Date.now());
|
||||||
@@ -123,10 +122,6 @@ export const ToPaidPlanBannerDismissable = () => {
|
|||||||
}]));
|
}]));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!cloudFreeDeprecated) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!show) {
|
if (!show) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ describe('components/feature_discovery', () => {
|
|||||||
hadPrevCloudTrial={false}
|
hadPrevCloudTrial={false}
|
||||||
isSubscriptionLoaded={true}
|
isSubscriptionLoaded={true}
|
||||||
isPaidSubscription={false}
|
isPaidSubscription={false}
|
||||||
cloudFreeDeprecated={false}
|
|
||||||
actions={{
|
actions={{
|
||||||
getPrevTrialLicense,
|
getPrevTrialLicense,
|
||||||
getCloudSubscription,
|
getCloudSubscription,
|
||||||
@@ -104,7 +103,6 @@ describe('components/feature_discovery', () => {
|
|||||||
hadPrevCloudTrial={false}
|
hadPrevCloudTrial={false}
|
||||||
isPaidSubscription={false}
|
isPaidSubscription={false}
|
||||||
isSubscriptionLoaded={true}
|
isSubscriptionLoaded={true}
|
||||||
cloudFreeDeprecated={false}
|
|
||||||
actions={{
|
actions={{
|
||||||
getPrevTrialLicense,
|
getPrevTrialLicense,
|
||||||
getCloudSubscription,
|
getCloudSubscription,
|
||||||
@@ -165,7 +163,6 @@ describe('components/feature_discovery', () => {
|
|||||||
hadPrevCloudTrial={false}
|
hadPrevCloudTrial={false}
|
||||||
isSubscriptionLoaded={false}
|
isSubscriptionLoaded={false}
|
||||||
isPaidSubscription={false}
|
isPaidSubscription={false}
|
||||||
cloudFreeDeprecated={false}
|
|
||||||
actions={{
|
actions={{
|
||||||
getPrevTrialLicense,
|
getPrevTrialLicense,
|
||||||
getCloudSubscription,
|
getCloudSubscription,
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ type Props = {
|
|||||||
isSubscriptionLoaded: boolean;
|
isSubscriptionLoaded: boolean;
|
||||||
isPaidSubscription: boolean;
|
isPaidSubscription: boolean;
|
||||||
customer?: CloudCustomer;
|
customer?: CloudCustomer;
|
||||||
cloudFreeDeprecated: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {getPrevTrialLicense} from 'mattermost-redux/actions/admin';
|
|||||||
import {getCloudSubscription} from 'mattermost-redux/actions/cloud';
|
import {getCloudSubscription} from 'mattermost-redux/actions/cloud';
|
||||||
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 {openModal} from 'actions/views/modals';
|
import {openModal} from 'actions/views/modals';
|
||||||
|
|
||||||
@@ -29,7 +28,6 @@ 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,
|
||||||
@@ -39,7 +37,6 @@ 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,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ type Props = {
|
|||||||
daysLeftOnTrial: number;
|
daysLeftOnTrial: number;
|
||||||
isCloud: boolean;
|
isCloud: boolean;
|
||||||
subscription?: Subscription;
|
subscription?: Subscription;
|
||||||
reverseTrial: boolean;
|
|
||||||
actions: {
|
actions: {
|
||||||
savePreferences: (userId: string, preferences: PreferenceType[]) => void;
|
savePreferences: (userId: string, preferences: PreferenceType[]) => void;
|
||||||
getCloudSubscription: () => void;
|
getCloudSubscription: () => void;
|
||||||
@@ -131,7 +130,7 @@ class CloudTrialAnnouncementBar extends React.PureComponent<Props> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let trialMoreThan7DaysMsg = (
|
const trialMoreThan7DaysMsg = (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='admin.billing.subscription.cloudTrial.daysLeft'
|
id='admin.billing.subscription.cloudTrial.daysLeft'
|
||||||
defaultMessage='Your trial has started! There are {daysLeftOnTrial} days left'
|
defaultMessage='Your trial has started! There are {daysLeftOnTrial} days left'
|
||||||
@@ -139,63 +138,26 @@ class CloudTrialAnnouncementBar extends React.PureComponent<Props> {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
let modalButtonText;
|
const modalButtonText = messages.trialButton;
|
||||||
if (this.props.reverseTrial) {
|
|
||||||
modalButtonText = messages.trialButton;
|
|
||||||
} else {
|
|
||||||
modalButtonText = messages.reverseTrialButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.reverseTrial) {
|
const trialLessThan7DaysMsg = (
|
||||||
const trialEnd = getLocaleDateFromUTC((this.props.subscription?.trial_end_at as number / 1000), 'MMMM Do');
|
|
||||||
trialMoreThan7DaysMsg = (
|
|
||||||
<FormattedMessage
|
|
||||||
id='admin.billing.subscription.cloudTrial.moreThan3Days'
|
|
||||||
defaultMessage='Your 30 day Enterprise trial has started! Purchase before {trialEnd} to keep your workspace.'
|
|
||||||
values={{trialEnd}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let trialLessThan7DaysMsg = (
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='admin.billing.subscription.cloudTrial.daysLeftOnTrial'
|
id='admin.billing.subscription.cloudReverseTrial.daysLeftOnTrial'
|
||||||
defaultMessage='There are {daysLeftOnTrial} days left on your free trial'
|
defaultMessage='{daysLeftOnTrial} days left on your trial. Purchase a plan or contact sales to keep your workspace.'
|
||||||
values={{daysLeftOnTrial}}
|
values={{daysLeftOnTrial}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.props.reverseTrial) {
|
|
||||||
trialLessThan7DaysMsg = (
|
|
||||||
<FormattedMessage
|
|
||||||
id='admin.billing.subscription.cloudReverseTrial.daysLeftOnTrial'
|
|
||||||
defaultMessage='{daysLeftOnTrial} days left on your trial. Purchase a plan or contact sales to keep your workspace.'
|
|
||||||
values={{daysLeftOnTrial}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const userEndTrialDate = getLocaleDateFromUTC((this.props.subscription?.trial_end_at as number / 1000), 'MMMM Do YYYY');
|
|
||||||
const userEndTrialHour = getLocaleDateFromUTC((this.props.subscription?.trial_end_at as number / 1000), 'HH:mm', this.props.currentUser.timezone?.automaticTimezone as string);
|
const userEndTrialHour = getLocaleDateFromUTC((this.props.subscription?.trial_end_at as number / 1000), 'HH:mm', this.props.currentUser.timezone?.automaticTimezone as string);
|
||||||
|
|
||||||
let trialLastDaysMsg = (
|
const trialLastDaysMsg = (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='admin.billing.subscription.cloudTrial.lastDay'
|
id='admin.billing.subscription.cloudReverseTrial.lastDay'
|
||||||
defaultMessage='This is the last day of your free trial. Your access will expire on {userEndTrialDate} at {userEndTrialHour}.'
|
defaultMessage='This is the last day of your trial. Purchase a plan before {userEndTrialHour} or contact sales'
|
||||||
values={{userEndTrialHour, userEndTrialDate}}
|
values={{userEndTrialHour}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.props.reverseTrial) {
|
|
||||||
trialLastDaysMsg = (
|
|
||||||
<FormattedMessage
|
|
||||||
id='admin.billing.subscription.cloudReverseTrial.lastDay'
|
|
||||||
defaultMessage='This is the last day of your trial. Purchase a plan before {userEndTrialHour} or contact sales'
|
|
||||||
values={{userEndTrialHour}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let bannerMessage;
|
let bannerMessage;
|
||||||
let icon;
|
let icon;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import type {Dispatch} from 'redux';
|
|||||||
|
|
||||||
import {getCloudSubscription} from 'mattermost-redux/actions/cloud';
|
import {getCloudSubscription} from 'mattermost-redux/actions/cloud';
|
||||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||||
import {getConfig} from 'mattermost-redux/selectors/entities/admin';
|
|
||||||
import {getLicense} from 'mattermost-redux/selectors/entities/general';
|
import {getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||||
import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences';
|
import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
@@ -28,7 +27,6 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
const isCloud = getLicense(state).Cloud === 'true';
|
const isCloud = getLicense(state).Cloud === 'true';
|
||||||
let isFreeTrial = false;
|
let isFreeTrial = false;
|
||||||
let daysLeftOnTrial = 0;
|
let daysLeftOnTrial = 0;
|
||||||
const config = getConfig(state);
|
|
||||||
|
|
||||||
if (isCloud && subscription?.is_free_trial === 'true') {
|
if (isCloud && subscription?.is_free_trial === 'true') {
|
||||||
isFreeTrial = true;
|
isFreeTrial = true;
|
||||||
@@ -46,7 +44,6 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
isCloud,
|
isCloud,
|
||||||
subscription,
|
subscription,
|
||||||
preferences: getCategory(state, Preferences.CLOUD_TRIAL_BANNER),
|
preferences: getCategory(state, Preferences.CLOUD_TRIAL_BANNER),
|
||||||
reverseTrial: Boolean(config.FeatureFlags?.CloudReverseTrial),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {useSelector, useDispatch} from 'react-redux';
|
|||||||
import {getPrevTrialLicense} from 'mattermost-redux/actions/admin';
|
import {getPrevTrialLicense} from 'mattermost-redux/actions/admin';
|
||||||
import {getSubscriptionProduct, checkHadPriorTrial} from 'mattermost-redux/selectors/entities/cloud';
|
import {getSubscriptionProduct, checkHadPriorTrial} from 'mattermost-redux/selectors/entities/cloud';
|
||||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||||
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
|
|
||||||
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import {closeModal, openModal} from 'actions/views/modals';
|
import {closeModal, openModal} from 'actions/views/modals';
|
||||||
@@ -40,7 +39,6 @@ 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();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -83,7 +81,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 || cloudFreeDeprecated) ? formatMessage({id: 'free.professional_feature.upgrade', defaultMessage: 'Upgrade'}) : formatMessage({id: 'free.professional_feature.try_free', defaultMessage: 'Professional feature- try it out free'});
|
ctaExtraContentMsg = (hasPriorTrial) ? 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 = (
|
||||||
|
|||||||
@@ -2,16 +2,9 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {FormattedMessage} from 'react-intl';
|
|
||||||
import {useSelector} from 'react-redux';
|
|
||||||
|
|
||||||
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
|
|
||||||
|
|
||||||
import ExternalLink from 'components/external_link';
|
|
||||||
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 {AboutLinks, LicenseLinks} from 'utils/constants';
|
|
||||||
|
|
||||||
import './learn_more_trial_modal_step.scss';
|
import './learn_more_trial_modal_step.scss';
|
||||||
|
|
||||||
export type LearnMoreTrialModalStepProps = {
|
export type LearnMoreTrialModalStepProps = {
|
||||||
@@ -38,7 +31,6 @@ const LearnMoreTrialModalStep = (
|
|||||||
buttonLabel,
|
buttonLabel,
|
||||||
handleOnClose,
|
handleOnClose,
|
||||||
}: LearnMoreTrialModalStepProps) => {
|
}: LearnMoreTrialModalStepProps) => {
|
||||||
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id={`learnMoreTrialModalStep-${id}`}
|
id={`learnMoreTrialModalStep-${id}`}
|
||||||
@@ -63,36 +55,6 @@ const LearnMoreTrialModalStep = (
|
|||||||
telemetryId={'learn_more_trial_modal'}
|
telemetryId={'learn_more_trial_modal'}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{
|
|
||||||
cloudFreeDeprecated ? '' : (
|
|
||||||
<div className='disclaimer'>
|
|
||||||
<span>
|
|
||||||
<FormattedMessage
|
|
||||||
id='start_trial.modal.disclaimer'
|
|
||||||
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.'
|
|
||||||
values={{
|
|
||||||
linkEvaluation: (msg: React.ReactNode) => (
|
|
||||||
<ExternalLink
|
|
||||||
href={LicenseLinks.SOFTWARE_SERVICES_LICENSE_AGREEMENT}
|
|
||||||
location='learn_more_trial_modal_step'
|
|
||||||
>
|
|
||||||
{msg}
|
|
||||||
</ExternalLink>
|
|
||||||
),
|
|
||||||
linkPrivacy: (msg: React.ReactNode) => (
|
|
||||||
<ExternalLink
|
|
||||||
href={AboutLinks.PRIVACY_POLICY}
|
|
||||||
location='learn_more_trial_modal_step'
|
|
||||||
>
|
|
||||||
{msg}
|
|
||||||
</ExternalLink>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{bottomLeftMessage && (
|
{bottomLeftMessage && (
|
||||||
<div className='bottom-text-left-message'>
|
<div className='bottom-text-left-message'>
|
||||||
{bottomLeftMessage}
|
{bottomLeftMessage}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
getSubscriptionProduct as selectSubscriptionProduct,
|
getSubscriptionProduct as selectSubscriptionProduct,
|
||||||
getCloudProducts as selectCloudProducts,
|
getCloudProducts as selectCloudProducts,
|
||||||
} from 'mattermost-redux/selectors/entities/cloud';
|
} from 'mattermost-redux/selectors/entities/cloud';
|
||||||
import {deprecateCloudFree} from 'mattermost-redux/selectors/entities/preferences';
|
|
||||||
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import {trackEvent} from 'actions/telemetry_actions';
|
import {trackEvent} from 'actions/telemetry_actions';
|
||||||
@@ -27,7 +26,6 @@ import {findOnlyYearlyProducts, findProductBySku} from 'utils/products';
|
|||||||
|
|
||||||
import Card, {BlankCard, ButtonCustomiserClasses} from './card';
|
import Card, {BlankCard, ButtonCustomiserClasses} from './card';
|
||||||
import ContactSalesCTA from './contact_sales_cta';
|
import ContactSalesCTA from './contact_sales_cta';
|
||||||
import StartTrialCaution from './start_trial_caution';
|
|
||||||
|
|
||||||
import './content.scss';
|
import './content.scss';
|
||||||
|
|
||||||
@@ -48,7 +46,6 @@ function Content(props: ContentProps) {
|
|||||||
const currentProduct = useSelector(selectSubscriptionProduct);
|
const currentProduct = useSelector(selectSubscriptionProduct);
|
||||||
const products = useSelector(selectCloudProducts);
|
const products = useSelector(selectCloudProducts);
|
||||||
|
|
||||||
const cloudFreeDeprecated = useSelector(deprecateCloudFree);
|
|
||||||
const yearlyProducts = findOnlyYearlyProducts(products || {}); // pricing modal should now only show yearly products
|
const yearlyProducts = findOnlyYearlyProducts(products || {}); // pricing modal should now only show yearly products
|
||||||
|
|
||||||
const currentSubscriptionIsMonthly = currentProduct?.recurring_interval === RecurringIntervals.MONTH;
|
const currentSubscriptionIsMonthly = currentProduct?.recurring_interval === RecurringIntervals.MONTH;
|
||||||
@@ -220,10 +217,10 @@ function Content(props: ContentProps) {
|
|||||||
renderLastDaysOnTrial={true}
|
renderLastDaysOnTrial={true}
|
||||||
/>) : undefined}
|
/>) : undefined}
|
||||||
buttonDetails={enterpriseBtnDetails()}
|
buttonDetails={enterpriseBtnDetails()}
|
||||||
planTrialDisclaimer={(!isPostTrial && isAdmin && !cloudFreeDeprecated) ? <StartTrialCaution/> : undefined}
|
planTrialDisclaimer={undefined}
|
||||||
contactSalesCTA={(isPostTrial || !isAdmin || cloudFreeDeprecated) ? undefined : <ContactSalesCTA/>}
|
contactSalesCTA={(isPostTrial || !isAdmin) ? undefined : <ContactSalesCTA/>}
|
||||||
briefing={{
|
briefing={{
|
||||||
title: cloudFreeDeprecated ? formatMessage({id: 'pricing_modal.briefing.title_large_scale', defaultMessage: 'Large scale collaboration'}) : formatMessage({id: 'pricing_modal.briefing.title', defaultMessage: 'Top features'}),
|
title: formatMessage({id: 'pricing_modal.briefing.title_large_scale', defaultMessage: 'Large scale collaboration'}),
|
||||||
items: [
|
items: [
|
||||||
formatMessage({id: 'pricing_modal.briefing.enterprise.groupSync', defaultMessage: 'AD/LDAP group sync'}),
|
formatMessage({id: 'pricing_modal.briefing.enterprise.groupSync', defaultMessage: 'AD/LDAP group sync'}),
|
||||||
formatMessage({id: 'pricing_modal.briefing.enterprise.rolesAndPermissions', defaultMessage: 'Advanced roles and permissions'}),
|
formatMessage({id: 'pricing_modal.briefing.enterprise.rolesAndPermissions', defaultMessage: 'Advanced roles and permissions'}),
|
||||||
|
|||||||
@@ -162,43 +162,6 @@ describe('components/widgets/menu/menu_items/menu_cloud_trial', () => {
|
|||||||
expect(wrapper.find('.MenuCloudTrial').exists()).toEqual(false);
|
expect(wrapper.find('.MenuCloudTrial').exists()).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should invite to start trial when the subscription is not paid and have not had trial before', () => {
|
|
||||||
const state = {
|
|
||||||
entities: {
|
|
||||||
general: {
|
|
||||||
license: {
|
|
||||||
IsLicensed: 'true',
|
|
||||||
Cloud: 'true',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
cloud: {
|
|
||||||
subscription: {
|
|
||||||
is_free_trial: 'false',
|
|
||||||
trial_end_at: 0,
|
|
||||||
product_id: 'prod_starter',
|
|
||||||
},
|
|
||||||
products: {
|
|
||||||
prod_starter: {
|
|
||||||
id: 'prod_starter',
|
|
||||||
sku: CloudProducts.STARTER,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
limits,
|
|
||||||
},
|
|
||||||
usage,
|
|
||||||
users: {
|
|
||||||
currentUserId: 'current_user_id',
|
|
||||||
profiles: {
|
|
||||||
current_user_id: {roles: 'system_admin'},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const store = mockStore(state);
|
|
||||||
const wrapper = mountWithIntl(<Provider store={store}><MenuCloudTrial id='menuCloudTrial'/></Provider>);
|
|
||||||
expect(wrapper.find('.open-learn-more-trial-modal').exists()).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should show the open trial benefits modal when is free trial', () => {
|
test('should show the open trial benefits modal when is free trial', () => {
|
||||||
const state = {
|
const state = {
|
||||||
entities: {
|
entities: {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import {useSelector, useDispatch} from 'react-redux';
|
|||||||
|
|
||||||
import {getCloudSubscription, getSubscriptionProduct} from 'mattermost-redux/selectors/entities/cloud';
|
import {getCloudSubscription, getSubscriptionProduct} 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 {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
|
||||||
import {openModal} from 'actions/views/modals';
|
import {openModal} from 'actions/views/modals';
|
||||||
@@ -17,7 +16,6 @@ import useGetHighestThresholdCloudLimit from 'components/common/hooks/useGetHigh
|
|||||||
import useGetLimits from 'components/common/hooks/useGetLimits';
|
import useGetLimits from 'components/common/hooks/useGetLimits';
|
||||||
import useGetUsage from 'components/common/hooks/useGetUsage';
|
import useGetUsage from 'components/common/hooks/useGetUsage';
|
||||||
import useOpenPricingModal from 'components/common/hooks/useOpenPricingModal';
|
import useOpenPricingModal from 'components/common/hooks/useOpenPricingModal';
|
||||||
import LearnMoreTrialModal from 'components/learn_more_trial_modal/learn_more_trial_modal';
|
|
||||||
import TrialBenefitsModal from 'components/trial_benefits_modal/trial_benefits_modal';
|
import TrialBenefitsModal from 'components/trial_benefits_modal/trial_benefits_modal';
|
||||||
|
|
||||||
import {ModalIdentifiers, CloudProducts} from 'utils/constants';
|
import {ModalIdentifiers, CloudProducts} from 'utils/constants';
|
||||||
@@ -31,12 +29,10 @@ 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();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const isCloud = license?.Cloud === 'true';
|
const isCloud = license?.Cloud === 'true';
|
||||||
const isFreeTrial = subscription?.is_free_trial === 'true';
|
const isFreeTrial = subscription?.is_free_trial === 'true';
|
||||||
const noPriorTrial = !(subscription?.is_free_trial === 'false' && subscription?.trial_end_at > 0);
|
|
||||||
const freeTrialEndDay = moment(subscription?.trial_end_at).format('MMMM DD');
|
const freeTrialEndDay = moment(subscription?.trial_end_at).format('MMMM DD');
|
||||||
const isAdmin = useSelector(isCurrentUserSystemAdmin);
|
const isAdmin = useSelector(isCurrentUserSystemAdmin);
|
||||||
const openPricingModal = useOpenPricingModal();
|
const openPricingModal = useOpenPricingModal();
|
||||||
@@ -48,16 +44,6 @@ const MenuCloudTrial = ({id}: Props): JSX.Element | null => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const openLearnMoreTrialModal = async () => {
|
|
||||||
await dispatch(openModal({
|
|
||||||
modalId: ModalIdentifiers.LEARN_MORE_TRIAL_MODAL,
|
|
||||||
dialogType: LearnMoreTrialModal,
|
|
||||||
dialogProps: {
|
|
||||||
launchedBy: 'main_menu_cloud_trial',
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const someLimitNeedsAttention = Boolean(useGetHighestThresholdCloudLimit(useGetUsage(), useGetLimits()[0]));
|
const someLimitNeedsAttention = Boolean(useGetHighestThresholdCloudLimit(useGetUsage(), useGetLimits()[0]));
|
||||||
|
|
||||||
if (!isCloud) {
|
if (!isCloud) {
|
||||||
@@ -109,24 +95,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 && !cloudFreeDeprecated) ? (
|
const noFreeTrialContent = (
|
||||||
<FormattedMessage
|
|
||||||
id='menu.cloudFree.priorTrial.tryEnterprise'
|
|
||||||
defaultMessage='Interested in a limitless plan with high-security features? <openModalLink>Try Enterprise free for 30 days</openModalLink>'
|
|
||||||
values={
|
|
||||||
{
|
|
||||||
openModalLink: (msg: string) => (
|
|
||||||
<a
|
|
||||||
className='open-learn-more-trial-modal style-link'
|
|
||||||
onClick={openLearnMoreTrialModal}
|
|
||||||
>
|
|
||||||
{msg}
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='menu.cloudFree.postTrial.tryEnterprise'
|
id='menu.cloudFree.postTrial.tryEnterprise'
|
||||||
defaultMessage='Interested in a limitless plan with high-security features? <openModalLink>See plans</openModalLink>'
|
defaultMessage='Interested in a limitless plan with high-security features? <openModalLink>See plans</openModalLink>'
|
||||||
|
|||||||
@@ -336,9 +336,6 @@
|
|||||||
"admin.billing.subscription.cloudReverseTrial.lastDay": "This is the last day of your trial. Purchase a plan before {userEndTrialHour} or contact sales",
|
"admin.billing.subscription.cloudReverseTrial.lastDay": "This is the last day of your trial. Purchase a plan before {userEndTrialHour} or contact sales",
|
||||||
"admin.billing.subscription.cloudReverseTrial.subscribeButton": "Review your options",
|
"admin.billing.subscription.cloudReverseTrial.subscribeButton": "Review your options",
|
||||||
"admin.billing.subscription.cloudTrial.daysLeft": "Your trial has started! There are {daysLeftOnTrial} days left",
|
"admin.billing.subscription.cloudTrial.daysLeft": "Your trial has started! There are {daysLeftOnTrial} days left",
|
||||||
"admin.billing.subscription.cloudTrial.daysLeftOnTrial": "There are {daysLeftOnTrial} days left on your free trial",
|
|
||||||
"admin.billing.subscription.cloudTrial.lastDay": "This is the last day of your free trial. Your access will expire on {userEndTrialDate} at {userEndTrialHour}.",
|
|
||||||
"admin.billing.subscription.cloudTrial.moreThan3Days": "Your trial has started! There are {daysLeftOnTrial} days left",
|
|
||||||
"admin.billing.subscription.cloudTrial.subscribeButton": "Upgrade Now",
|
"admin.billing.subscription.cloudTrial.subscribeButton": "Upgrade Now",
|
||||||
"admin.billing.subscription.cloudTrialBadge.daysLeftOnTrial": "{daysLeftOnTrial} trial days left",
|
"admin.billing.subscription.cloudTrialBadge.daysLeftOnTrial": "{daysLeftOnTrial} trial days left",
|
||||||
"admin.billing.subscription.cloudYearlyBadge": "Annual",
|
"admin.billing.subscription.cloudYearlyBadge": "Annual",
|
||||||
@@ -4151,7 +4148,6 @@
|
|||||||
"menu.cloudFree.enterpriseTrialDescription": "Your trial is active until {trialEndDay}. Discover our top Enterprise features. <openModalLink>Learn more</openModalLink>",
|
"menu.cloudFree.enterpriseTrialDescription": "Your trial is active until {trialEndDay}. Discover our top Enterprise features. <openModalLink>Learn more</openModalLink>",
|
||||||
"menu.cloudFree.enterpriseTrialTitle": "Enterprise Trial",
|
"menu.cloudFree.enterpriseTrialTitle": "Enterprise Trial",
|
||||||
"menu.cloudFree.postTrial.tryEnterprise": "Interested in a limitless plan with high-security features? <openModalLink>See plans</openModalLink>",
|
"menu.cloudFree.postTrial.tryEnterprise": "Interested in a limitless plan with high-security features? <openModalLink>See plans</openModalLink>",
|
||||||
"menu.cloudFree.priorTrial.tryEnterprise": "Interested in a limitless plan with high-security features? <openModalLink>Try Enterprise free for 30 days</openModalLink>",
|
|
||||||
"message_submit_error.invalidCommand": "Command with a trigger of ''{command}'' not found. ",
|
"message_submit_error.invalidCommand": "Command with a trigger of ''{command}'' not found. ",
|
||||||
"message_submit_error.sendAsMessageLink": "Click here to send as a message.",
|
"message_submit_error.sendAsMessageLink": "Click here to send as a message.",
|
||||||
"mfa.confirm.complete": "**Set up complete!**",
|
"mfa.confirm.complete": "**Set up complete!**",
|
||||||
@@ -5041,7 +5037,6 @@
|
|||||||
"start_trial_form.modal_title": "Start Trial",
|
"start_trial_form.modal_title": "Start Trial",
|
||||||
"start_trial_form.name": "Name",
|
"start_trial_form.name": "Name",
|
||||||
"start_trial.modal_btn.start_free_trial": "Start free 30-day trial",
|
"start_trial.modal_btn.start_free_trial": "Start free 30-day trial",
|
||||||
"start_trial.modal.disclaimer": "By clicking “Start free 30-day trial”, I agree to the <linkEvaluation>Mattermost Software Evaluation Agreement</linkEvaluation>, <linkPrivacy>privacy policy</linkPrivacy> and receiving product emails.",
|
|
||||||
"start_trial.modal.failed": "Failed",
|
"start_trial.modal.failed": "Failed",
|
||||||
"start_trial.modal.gettingTrial": "Getting Trial...",
|
"start_trial.modal.gettingTrial": "Getting Trial...",
|
||||||
"start_trial.modal.loaded": "Loaded!",
|
"start_trial.modal.loaded": "Loaded!",
|
||||||
|
|||||||
@@ -329,14 +329,6 @@ export function onboardingTourTipsEnabled(state: GlobalState): boolean {
|
|||||||
return getFeatureFlagValue(state, 'OnboardingTourTips') === 'true';
|
return getFeatureFlagValue(state, 'OnboardingTourTips') === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deprecateCloudFree(state: GlobalState): boolean {
|
|
||||||
return getFeatureFlagValue(state, 'DeprecateCloudFree') === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cloudReverseTrial(state: GlobalState): boolean {
|
|
||||||
return getFeatureFlagValue(state, 'CloudReverseTrial') === 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function moveThreadsEnabled(state: GlobalState): boolean {
|
export function moveThreadsEnabled(state: GlobalState): boolean {
|
||||||
return getFeatureFlagValue(state, 'MoveThreadsEnabled') === 'true' && getLicense(state).IsLicensed === 'true';
|
return getFeatureFlagValue(state, 'MoveThreadsEnabled') === 'true' && getLicense(state).IsLicensed === 'true';
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user