Skip to content

Commit

Permalink
Automated cherry pick of mattermost#6731 (mattermost#6761)
Browse files Browse the repository at this point in the history
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
  • Loading branch information
3 people committed Oct 13, 2020
1 parent e25227a commit d2c619c
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 74 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ executors:
aliases:
- &restore_cache
restore_cache:
key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-4
key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-5
- &save_cache
save_cache:
key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-4
key: dependencies-{{ .Branch }}-{{ checksum "package-lock.json" }}-5
paths:
- ~/mattermost/mattermost-webapp/node_modules

Expand Down
6 changes: 4 additions & 2 deletions components/admin_console/billing/billing_history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import FormattedAdminHeader from 'components/widgets/admin_console/formatted_adm
import FormattedMarkdownMessage from 'components/formatted_markdown_message';
import noBillingHistoryGraphic from 'images/no_billing_history_graphic.svg';

import {CloudLinks} from 'utils/constants';

import './billing_history.scss';

type Props = {
Expand All @@ -27,9 +29,9 @@ const noBillingHistorySection = (
/>
</div>
<a
target='_blank'
target='_new'
rel='noopener noreferrer'
href='http://www.google.com'
href={CloudLinks.BILLING_DOCS}
className='BillingHistory__noHistory-link'
>
<FormattedMessage
Expand Down
121 changes: 65 additions & 56 deletions components/admin_console/billing/billing_subscriptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// See LICENSE.txt for license information.

import React, {useState, useEffect} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {useDispatch, useStore, useSelector} from 'react-redux';
import {FormattedMessage, useIntl} from 'react-intl';

import {getCloudSubscription, getCloudProducts} from 'mattermost-redux/actions/cloud';
import {DispatchFunc} from 'mattermost-redux/types/actions';
Expand All @@ -17,6 +17,7 @@ import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences';

import {GlobalState} from 'types/store';
import {getCloudContactUsLink, InquiryType} from 'selectors/cloud';

import {trackEvent} from 'actions/telemetry_actions';

Expand All @@ -34,63 +35,9 @@ import privateCloudImage from 'images/private-cloud-image.svg';
import upgradeMattermostCloudImage from 'images/upgrade-mattermost-cloud-image.svg';

import PlanDetails from './plan_details';

import './billing_subscriptions.scss';
import BillingSummary from './billing_summary';

const upgradeMattermostCloud = () => (
<div className='UpgradeMattermostCloud'>
<div className='UpgradeMattermostCloud__image'>
<img src={upgradeMattermostCloudImage}/>
</div>
<div className='UpgradeMattermostCloud__title'>
<FormattedMessage
id='admin.billing.subscription.upgradeMattermostCloud.title'
defaultMessage='Need more users?'
/>
</div>
<div className='UpgradeMattermostCloud__description'>
<FormattedMarkdownMessage
id='admin.billing.subscription.upgradeMattermostCloud.description'
defaultMessage='The free tier is **limited to 10 users.** Get access to more users, teams and other great features'
/>
</div>
<button className='UpgradeMattermostCloud__upgradeButton'>
<FormattedMessage
id='admin.billing.subscription.upgradeMattermostCloud.upgradeButton'
defaultMessage='Upgrade Mattermost Cloud'
/>
</button>
</div>
);

const privateCloudCard = () => (
<div className='PrivateCloudCard'>
<div className='PrivateCloudCard__text'>
<div className='PrivateCloudCard__text-title'>
<FormattedMessage
id='admin.billing.subscription.privateCloudCard.title'
defaultMessage='Looking for a high-trust private cloud?'
/>
</div>
<div className='PrivateCloudCard__text-description'>
<FormattedMessage
id='admin.billing.subscription.privateCloudCard.description'
defaultMessage='If you need software with dedicated, single-tenant architecture, Mattermost Private Cloud (Beta) is the solution for high-trust collaboration.'
/>
</div>
<button className='PrivateCloudCard__contactSales'>
<FormattedMessage
id='admin.billing.subscription.privateCloudCard.contactSales'
defaultMessage='Contact Sales'
/>
</button>
</div>
<div className='PrivateCloudCard__image'>
<img src={privateCloudImage}/>
</div>
</div>
);
import './billing_subscriptions.scss';

const WARNING_THRESHOLD = 3;

Expand All @@ -112,6 +59,8 @@ const BillingSubscriptions: React.FC<Props> = () => {
const getCategory = makeGetCategory();
const preferences = useSelector<GlobalState, PreferenceType[]>((state) => getCategory(state, Preferences.ADMIN_CLOUD_UPGRADE_PANEL));

const contactSalesLink = useSelector((state: GlobalState) => getCloudContactUsLink(state, InquiryType.Sales));

useEffect(() => {
getCloudSubscription()(dispatch, store.getState());
getCloudProducts()(dispatch, store.getState());
Expand Down Expand Up @@ -159,6 +108,66 @@ const BillingSubscriptions: React.FC<Props> = () => {
]));
};

const upgradeMattermostCloud = () => (
<div className='UpgradeMattermostCloud'>
<div className='UpgradeMattermostCloud__image'>
<img src={upgradeMattermostCloudImage}/>
</div>
<div className='UpgradeMattermostCloud__title'>
<FormattedMessage
id='admin.billing.subscription.upgradeMattermostCloud.title'
defaultMessage='Need more users?'
/>
</div>
<div className='UpgradeMattermostCloud__description'>
<FormattedMarkdownMessage
id='admin.billing.subscription.upgradeMattermostCloud.description'
defaultMessage='The free tier is **limited to 10 users.** Get access to more users, teams and other great features'
/>
</div>
<button className='UpgradeMattermostCloud__upgradeButton'>
<FormattedMessage
id='admin.billing.subscription.upgradeMattermostCloud.upgradeButton'
defaultMessage='Upgrade Mattermost Cloud'
/>
</button>
</div>
);

const privateCloudCard = () => (
<div className='PrivateCloudCard'>
<div className='PrivateCloudCard__text'>
<div className='PrivateCloudCard__text-title'>
<FormattedMessage
id='admin.billing.subscription.privateCloudCard.title'
defaultMessage='Looking for a high-trust private cloud?'
/>
</div>
<div className='PrivateCloudCard__text-description'>
<FormattedMessage
id='admin.billing.subscription.privateCloudCard.description'
defaultMessage='If you need software with dedicated, single-tenant architecture, Mattermost Private Cloud (Beta) is the solution for high-trust collaboration.'
/>
</div>
<button className='PrivateCloudCard__contactSales'>
<a
href={contactSalesLink}
rel='noopener noreferrer'
target='_new'
>
<FormattedMessage
id='admin.billing.subscription.privateCloudCard.contactSales'
defaultMessage='Contact Sales'
/>
</a>
</button>
</div>
<div className='PrivateCloudCard__image'>
<img src={privateCloudImage}/>
</div>
</div>
);

return (
<div className='wrapper--fixed BillingSubscriptions'>
<FormattedAdminHeader
Expand Down
6 changes: 4 additions & 2 deletions components/admin_console/billing/billing_summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import React from 'react';
import {FormattedMessage} from 'react-intl';

import {CloudLinks} from 'utils/constants';

import noBillingHistoryGraphic from 'images/no_billing_history_graphic.svg';

import './billing_summary.scss';
Expand All @@ -27,9 +29,9 @@ const noBillingHistory = (
/>
</div>
<a
target='_blank'
target='_new'
rel='noopener noreferrer'
href='http://www.google.com'
href={CloudLinks.BILLING_DOCS}
className='BillingSummary__noBillingHistory-link'
>
<FormattedMessage
Expand Down
13 changes: 12 additions & 1 deletion components/admin_console/billing/plan_details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import OverlayTrigger from 'components/overlay_trigger';
import {getCurrentLocale} from 'selectors/i18n';
import {GlobalState} from 'types/store';
import {getMonthLong} from 'utils/i18n';
import {CloudLinks} from 'utils/constants';
import {localizeMessage} from 'utils/utils';

import './plan_details.scss';
Expand Down Expand Up @@ -67,8 +68,18 @@ const seatsAndSubscriptionDates = (locale: string, userCount: number, numberOfSe
<div className='BillingSubscriptions__tooltipMessage'>
<FormattedMarkdownMessage
id='admin.billing.subscription.planDetails.prolongedOverages'
defaultMessage='Prolonged overages may result in additional charges. [See how billing works](!https://google.com)'
defaultMessage='Prolonged overages may result in additional charges.'
/>
<a
target='_new'
rel='noopener noreferrer'
href={CloudLinks.BILLING_DOCS}
>
<FormattedMarkdownMessage
id='admin.billing.subscription.planDetails.howBillingWorks'
defaultMessage='See how billing works'
/>
</a>
</div>
</Tooltip>
)}
Expand Down
10 changes: 6 additions & 4 deletions components/purchase_modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,33 @@

import {connect} from 'react-redux';
import {bindActionCreators, Dispatch, ActionCreatorsMapObject} from 'redux';
import {Stripe} from '@stripe/stripe-js';

import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {GenericAction, ActionFunc} from 'mattermost-redux/types/actions';
import {Stripe} from '@stripe/stripe-js';

import {getCloudProducts, getCloudSubscription} from 'mattermost-redux/actions/cloud';
import {getClientConfig} from 'mattermost-redux/actions/general';

import {GlobalState} from 'types/store';
import {BillingDetails} from 'types/cloud/sku';

import {isModalOpen} from 'selectors/views/modals';
import {getCloudContactUsLink, InquiryType} from 'selectors/cloud';

import {ModalIdentifiers} from 'utils/constants';

import {closeModal} from 'actions/views/modals';
import {completeStripeAddPaymentMethod} from 'actions/cloud';

import {GlobalState} from 'types/store';

import PurchaseModal from './purchase_modal';

function mapStateToProps(state: GlobalState) {
return {
show: isModalOpen(state, ModalIdentifiers.CLOUD_PURCHASE),
products: state.entities.cloud!.products,
isDevMode: getConfig(state).EnableDeveloper === 'true',
contactSupportLink: getCloudContactUsLink(state, InquiryType.Technical),
contactSalesLink: getCloudContactUsLink(state, InquiryType.Sales),
};
}
type Actions = {
Expand Down
11 changes: 8 additions & 3 deletions components/purchase_modal/purchase_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ import blueDotes from 'images/cloud/blue.svg';
import LowerBlueDots from 'images/cloud/blue-lower.svg';
import cloudLogo from 'images/cloud/mattermost-cloud.svg';
import {trackEvent, pageVisited} from 'actions/telemetry_actions';
import {TELEMETRY_CATEGORIES} from 'utils/constants';

import {STRIPE_CSS_SRC, STRIPE_PUBLIC_KEY} from 'components/payment_form/stripe';
import RootPortal from 'components/root_portal';
import FullScreenModal from 'components/widgets/modals/full_screen_modal';
import {areBillingDetailsValid, BillingDetails} from 'types/cloud/sku';
import {getNextBillingDate} from 'utils/utils';
import {CloudLinks, TELEMETRY_CATEGORIES} from 'utils/constants';

import PaymentForm from '../payment_form/payment_form';

import ProcessPaymentSetup from './process_payment_setup';

import './purchase.scss';
import 'components/payment_form/payment_form.scss';
import ProcessPaymentSetup from './process_payment_setup';

const stripePromise = loadStripe(STRIPE_PUBLIC_KEY);

Expand Down Expand Up @@ -180,7 +181,11 @@ export default class PurchaseModal extends React.PureComponent<Props, State> {
/>
</span>
{'\u00A0'}
<a href='https://support.mattermost.com/hc/en-us/requests/new?ticket_form_id=360000640492'>
<a
href={CloudLinks.BILLING_DOCS}
target='_new'
rel='noopener noreferrer'
>
<FormattedMessage
defaultMessage={'See how billing works.'}
id={'admin.billing.subscription.howItWorks'}
Expand Down
3 changes: 2 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,11 @@
"admin.billing.subscription.planDetails.features.selfServiceDocumentation": "Self-Service documentation and forum support",
"admin.billing.subscription.planDetails.features.unlimitedIntegrations": "Unlimited Integrations",
"admin.billing.subscription.planDetails.features.unlimitedTeamsAndChannels": "Unlimited teams, channels, and search history",
"admin.billing.subscription.planDetails.howBillingWorks": "See how billing works",
"admin.billing.subscription.planDetails.numberOfSeats": "{numberOfSeats} seats",
"admin.billing.subscription.planDetails.numberOfSeatsRegistered": "({userCount} currently registered)",
"admin.billing.subscription.planDetails.perUserPerMonth": "/user/month",
"admin.billing.subscription.planDetails.prolongedOverages": "Prolonged overages may result in additional charges. [See how billing works](!https://google.com)",
"admin.billing.subscription.planDetails.prolongedOverages": "Prolonged overages may result in additional charges.",
"admin.billing.subscription.planDetails.seatCountOverages": "Seat count overages",
"admin.billing.subscription.planDetails.startDate": "Start Date: ",
"admin.billing.subscription.planDetails.tiers.free": "Free",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"localforage-observable": "2.0.1",
"mark.js": "8.11.1",
"marked": "github:mattermost/marked#87769262aa02e1784570f61f4f962050e07cc335",
"mattermost-redux": "github:mattermost/mattermost-redux#5f2f131e4660a9f58851835085fbe62d2f3419d5",
"mattermost-redux": "github:mattermost/mattermost-redux#15811ca565f1c72e666308c89babbc97d8da1dc0",
"moment-timezone": "0.5.31",
"p-queue": "6.6.1",
"pdfjs-dist": "2.1.266",
Expand Down
23 changes: 23 additions & 0 deletions selectors/cloud.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';

import {GlobalState} from 'types/store';

export enum InquiryType {
Technical = 'technical',
Sales = 'sales',
Billing = 'billing'
}

export function getCloudContactUsLink(state: GlobalState, inquiry: InquiryType): string {
// cloud/contact-us with query params for name, email and inquiry
const cwsUrl = getConfig(state).CWSUrl;
const user = getCurrentUser(state);
const fullName = `${user.first_name} ${user.last_name}`;

return `${cwsUrl}/cloud/contact-us?email=${encodeURIComponent(user.email)}&name=${encodeURIComponent(fullName)}&inquiry=${inquiry}`;
}
4 changes: 4 additions & 0 deletions utils/constants.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,10 @@ export const AboutLinks = {
PRIVACY_POLICY: 'https://about.mattermost.com/default-privacy-policy/',
};

export const CloudLinks = {
BILLING_DOCS: 'https://docs.mattermost.com/overview/mattermost-cloud-overview.html#how-billing-works',
};

export const PermissionsScope = {
[Permissions.INVITE_USER]: 'team_scope',
[Permissions.INVITE_GUEST]: 'team_scope',
Expand Down

0 comments on commit d2c619c

Please sign in to comment.