Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

[MM-27142] In-Web-App purchase of Mattermost Cloud #6583

Merged
merged 76 commits into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
cbdfc57
[MM-26468][MM-26483] Progress Bar Common Component/Sidebar Next Steps…
devinbinnie Jul 13, 2020
7cf611c
[MM-26465] Background and general layout for cloud onboarding (#5823)
devinbinnie Jul 13, 2020
25cacae
[MM-26480] Card/Accordion Common Component (#5861)
devinbinnie Jul 16, 2020
a93932e
[MM-26470] Base Next Step Wizard Controller and Styling (#5893)
devinbinnie Jul 23, 2020
d461828
Merge remote-tracking branch 'upstream/master' into feature/cloud-onb…
devinbinnie Jul 24, 2020
77f56af
[MM-26466] Close Next Steps Modal and functionality (#5995)
devinbinnie Jul 28, 2020
fbd0184
[MM-27164] Picture Selector Common Component (#5973)
devinbinnie Aug 4, 2020
18a3ba3
[MM-26482] Textbox Common Component for Cloud Onboarding (#5904)
devinbinnie Aug 4, 2020
681f8a5
Merge branch 'master' into feature/cloud-onboarding
devinbinnie Aug 5, 2020
cf33468
[MM-26469] Complete Profile Step (#6077)
devinbinnie Aug 10, 2020
26701b5
[MM-26473] Tips and Next Steps screen (#6020)
devinbinnie Aug 10, 2020
ad19b71
[MM-26471] Team Profile Setup step (#6083)
devinbinnie Aug 11, 2020
585b048
WIP
marianunez Aug 27, 2020
f704dd3
WIP
marianunez Sep 9, 2020
a4f7122
Final screens WIP
marianunez Sep 17, 2020
5713fac
WIP
marianunez Sep 24, 2020
9e31f28
Lot's of CSS fixes, some SVG's added, general cleanup
nickmisasi Sep 28, 2020
770f58c
Merge master into inapp-purchase
nickmisasi Sep 28, 2020
fe4b4d7
Adding translations all over
nickmisasi Sep 28, 2020
82da2da
Have the user_limit_modal component open the PurchaseModal when upgra…
nickmisasi Sep 28, 2020
84f1981
Merge branch 'master' into inapp-purchase
nickmisasi Sep 29, 2020
600db7f
merge master (banners), hook up announcement banner 'Upgrade Mattermo…
nickmisasi Sep 29, 2020
c9a5a8c
Fix issue with optional subtitle prop in IconMessage
nickmisasi Sep 29, 2020
e28d4cb
Fix linter
nickmisasi Sep 29, 2020
3247dac
Fix i18n
nickmisasi Sep 29, 2020
ab63fb4
Fix a bunch of types
nickmisasi Sep 29, 2020
d64151f
Fix country sort definitions
nickmisasi Sep 29, 2020
7b38947
fix most type issues
nickmisasi Sep 29, 2020
383982d
Fix flow
nickmisasi Sep 29, 2020
c6ab664
Fix lint
nickmisasi Sep 29, 2020
4bd1215
Fix isDevMode
nickmisasi Sep 29, 2020
f987c98
Fix lint
nickmisasi Sep 29, 2020
024164c
Attempt at fixing error with payment processing
nickmisasi Sep 30, 2020
46247a6
fix weird issue with padding
nickmisasi Sep 30, 2020
6b728eb
remove main menu item
nickmisasi Sep 30, 2020
eb07d46
Few changes for MR review
nickmisasi Sep 30, 2020
13a2780
Theme changes
nickmisasi Sep 30, 2020
37d56f9
Appease the pipeline gods
nickmisasi Sep 30, 2020
7ef206a
some fixes
nickmisasi Sep 30, 2020
be246fb
Fixing card input typescript issue
marianunez Sep 30, 2020
0a4c80e
Merge branch 'inapp-purchase' of https://github.com/mattermost/matter…
marianunez Sep 30, 2020
34d945a
First batch of CSS fixes
nickmisasi Oct 1, 2020
5388118
Merge branch 'inapp-purchase' of github.com:mattermost/mattermost-web…
nickmisasi Oct 1, 2020
698ab55
Fix CSS on progress and success screens
nickmisasi Oct 1, 2020
eda3d2c
Update redux, fix tsc
nickmisasi Oct 1, 2020
896c553
Fix pipeline
nickmisasi Oct 1, 2020
bcb7ed4
Fix placeholder text colour
nickmisasi Oct 1, 2020
91be41f
fix credit card entry error state
nickmisasi Oct 1, 2020
f146a3f
Merge branch 'master' into inapp-purchase
nickmisasi Oct 1, 2020
08473b7
Some changes
nickmisasi Oct 1, 2020
d9d382f
One more change
nickmisasi Oct 1, 2020
6e84e4f
Fixed one issue
nickmisasi Oct 1, 2020
e0be94a
Some more fixes
nickmisasi Oct 1, 2020
b33ec45
Dropdown styling
marianunez Oct 1, 2020
bb77d57
Integrate state/province selector with Devin's common component
nickmisasi Oct 2, 2020
7dbca7a
Fix pipeline
nickmisasi Oct 2, 2020
a3f2de2
fix i18n
nickmisasi Oct 2, 2020
00b3d21
Add types/cloud/sku, remove the customer type in favour of mattermost…
nickmisasi Oct 2, 2020
35543bf
Delete customer.ts
nickmisasi Oct 2, 2020
d5caa61
Couple UX fixes
nickmisasi Oct 5, 2020
1ae9848
One more fix
nickmisasi Oct 5, 2020
e98e0a1
Adding lower right blue dots
nickmisasi Oct 5, 2020
4a1b428
Remove comment
nickmisasi Oct 6, 2020
a2f0d25
Merge master into inapp-purchase
nickmisasi Oct 6, 2020
846d9c1
Update components/payment_form/card_input.css
nickmisasi Oct 6, 2020
6afb530
Update components/payment_form/payment_form.scss
nickmisasi Oct 6, 2020
e51b435
Bunch of changes for PR
nickmisasi Oct 6, 2020
b23ac08
Merge branch 'inapp-purchase' of github.com:mattermost/mattermost-web…
nickmisasi Oct 6, 2020
5bba0eb
More code changes
nickmisasi Oct 6, 2020
91325e4
Remove debug logs
nickmisasi Oct 6, 2020
c7ada1a
Changes for PR review
nickmisasi Oct 6, 2020
938d0e2
Fix i18n
nickmisasi Oct 6, 2020
46afba4
Fixes for PR
nickmisasi Oct 6, 2020
bd5ccd0
Localize
nickmisasi Oct 6, 2020
a393594
Fixes for PR
nickmisasi Oct 7, 2020
d4d6fb2
Fix conflicts
nickmisasi Oct 7, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions actions/cloud.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Stripe} from '@stripe/stripe-js';
import {getCode} from 'country-list';

import {Client4} from 'mattermost-redux/client';

import {getConfirmCardSetup} from 'components/payment_form/stripe';

import {StripeSetupIntent, BillingDetails} from 'types/cloud/sku';

// Returns true for success, and false for any error
export function completeStripeAddPaymentMethod(stripe: Stripe, billingDetails: BillingDetails, isDevMode: boolean) {
return async () => {
let paymentSetupIntent: StripeSetupIntent;
try {
paymentSetupIntent = await Client4.createPaymentMethod() as StripeSetupIntent;
} catch (error) {
return error;
}
const cardSetupFunction = getConfirmCardSetup(isDevMode);
const confirmCardSetup = cardSetupFunction(stripe.confirmCardSetup);

const result = await confirmCardSetup(
paymentSetupIntent.client_secret,
{
payment_method: {
card: billingDetails.card,
billing_details: {
name: billingDetails.name,
address: {
line1: billingDetails.address,
line2: billingDetails.address2,
city: billingDetails.city,
state: billingDetails.state,
country: getCode(billingDetails.country),
postal_code: billingDetails.postalCode,
},
},
},
},
);

if (!result) {
return false;
}

const {setupIntent, error: stripeError} = result;

if (stripeError) {
return false;
}

if (setupIntent == null) {
return false;
}

if (setupIntent.status !== 'succeeded') {
return false;
}

try {
await Client4.confirmPaymentMethod(setupIntent.id);
} catch (error) {
return false;
}

return true;
};
}
3 changes: 3 additions & 0 deletions components/announcement_bar/cloud_announcement_bar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {makeGetCategory} from 'mattermost-redux/selectors/entities/preferences';

import {getCurrentUser, isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';

import {openModal} from 'actions/views/modals';

import {GlobalState} from 'types/store';

import {Preferences} from 'utils/constants';
Expand All @@ -36,6 +38,7 @@ function mapDispatchToProps(dispatch: Dispatch<GenericAction>) {
{
savePreferences,
getStandardAnalytics,
openModal,
},
dispatch,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import {AnalyticsRow} from 'mattermost-redux/types/admin';
import {isEmpty} from 'lodash';

import {t} from 'utils/i18n';
import PurchaseModal from 'components/purchase_modal';

import {Preferences, CloudBanners, AnnouncementBarTypes} from 'utils/constants';
import {
Preferences,
CloudBanners,
AnnouncementBarTypes,
ModalIdentifiers,
} from 'utils/constants';

import AnnouncementBar from '../default_announcement_bar';

Expand All @@ -25,6 +31,7 @@ type Props = {
actions: {
savePreferences: (userId: string, preferences: PreferenceType[]) => void;
getStandardAnalytics: () => void;
openModal: (modalData: {modalId: string; dialogType: any; dialogProps?: any}) => void;
};
};

Expand Down Expand Up @@ -95,7 +102,12 @@ export default class UserLimitAnnouncementBar extends React.PureComponent<Props>
type={dismissable ? AnnouncementBarTypes.ADVISOR : AnnouncementBarTypes.CRITICAL_LIGHT}
showCloseButton={dismissable}
handleClose={this.handleClose}
showModal={() => {}}
showModal={() =>
this.props.actions.openModal({
modalId: ModalIdentifiers.CLOUD_PURCHASE,
dialogType: PurchaseModal,
})
}
modalButtonText={t('admin.billing.subscription.upgradeMattermostCloud.upgradeButton')}
modalButtonDefaultText={'Upgrade Mattermost Cloud'}
message={dismissable ? t('upgrade.cloud_banner_reached') : t('upgrade.cloud_banner_over')}
Expand Down
2 changes: 2 additions & 0 deletions components/dropdown_input.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DropdownInput {
z-index: 999999;
&.Input_container {
margin-top: 20px;
}
Expand Down Expand Up @@ -38,6 +39,7 @@
padding: 10px 24px;
line-height: 16px;
cursor: pointer;
z-index: 999999;
}

.DropdownInput__option.selected > div {
Expand Down
10 changes: 10 additions & 0 deletions components/dropdown_input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ const IndicatorsContainer = (props: any) => {
);
};

const Control = (props: any) => {
return (
<div className='DropdownInput__controlContainer'>
<components.Control {...props}/>
</div>
);
};

const Option = (props: any) => {
return (
<div
Expand Down Expand Up @@ -126,8 +134,10 @@ const DropdownInput = <T extends ValueType>(props: Props<T>) => {
components={{
IndicatorsContainer,
Option,
Control,
}}
className={classNames('Input', className, {Input__focus: showLegend})}
classNamePrefix={'DropDown'}
value={value}
onChange={onChange as any} // types are not working correctly for multiselect
styles={{...baseStyles, ...styles}}
Expand Down
5 changes: 0 additions & 5 deletions components/next_steps_view/next_steps_view.scss
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,15 @@
background-color: var(--sidebar-text-active-border);
}
}

.Card.complete {
border-color: transparent;
box-shadow: none;
transition-property: box-shadow, border-color;
background-color: transparent;

&:hover {
border-color: transparent;
box-shadow: none;
}

& + .Card {
margin-top: 12px;
transition-property: box-shadow, border-color, margin;
Expand All @@ -175,7 +172,6 @@
line-height: 26px;
color: var(--online-indicator);
transition: all 0.3s ease-in-out;

&::before {
margin: 0;
}
Expand Down Expand Up @@ -591,7 +587,6 @@
flex: 1 1 100%;
padding: 0 12px;
}

.NextStepsView__nextStepsCards, .NextStepsView__download, .NextStepsView__tipsMobileMessage {
padding: 0 12px;
}
Expand Down
8 changes: 8 additions & 0 deletions components/payment_form/card_image.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.CardImage {
height: auto;
width: auto;
max-height: 30px;
max-width: 30px;
margin-right: 9px;
margin-top: -1px;
}
54 changes: 54 additions & 0 deletions components/payment_form/card_image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import React from 'react';

import amex from 'images/cloud/cards/amex.png';

import dinersclub from 'images/cloud/cards/dinersclub.png';
import discover from 'images/cloud/cards/discover.jpg';
import jcb from 'images/cloud/cards/jcb.png';
import mastercard from 'images/cloud/cards/mastercard.png';
import visa from 'images/cloud/cards/visa.jpg';

import './card_image.css';

type Props = {
brand: string;
}

export default function CardImage(props: Props) {
const {brand} = props;

const cardImageSrc = getCardImage(brand);
if (cardImageSrc) {
return (
<img
className='CardImage'
src={cardImageSrc}
alt={brand}
/>
);
}

return null;
}

function getCardImage(brand: string): string {
switch (brand) {
case 'amex':
nickmisasi marked this conversation as resolved.
Show resolved Hide resolved
return amex;
case 'diners':
return dinersclub;
case 'discover':
return discover;
case 'jcb':
return jcb;
case 'mastercard':
return mastercard;
case 'visa':
return visa;
}

return '';
}
38 changes: 38 additions & 0 deletions components/payment_form/card_input.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.StripeElement {
font-family: 'Open Sans';
font-size: 14px;
position: relative;
padding-top: 8px;
padding-left: 12px;
padding-bottom: 2px !important;
width: 100%;
height: 100%;
font-size: 14px;
line-height: 23px;
color: var(--center-channel-color);
background-color: var(--center-channel-bg);
background-image: none;
border-radius: 4px;
outline: none;
box-shadow: none;
}

.StripeElement--invalid {
color: var(--error-text);
icon-color: var(--error-text);
}

.StripeElement::placeholder {
color: rgba(var(--center-channel-color-rgb), 0.72);
opacity: 0.5;
font-size: 14px;
}

.StripeElement:focus::placeholder {
color: 'transparent';
}

.StripeElement:focus {
border-color: transparent;
box-shadow: 0 0 0 2px var(--button-bg);
}
Loading