Address code review comments (styling, clean-up css, re-org imports, math errors, etc).

Этот коммит содержится в:
Conor Macpherson
2023-04-17 14:24:58 -04:00
родитель ecbdd91787
Коммит 5b42689529
10 изменённых файлов: 90 добавлений и 89 удалений

Просмотреть файл

@@ -0,0 +1,26 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {OutlinedInput as MUIOutlineInput, OutlinedInputProps} from '@mui/material';
/**
* A horizontal separator for use in menus.
* @example
* <OutlineInput
* data-testid='my-input'
* size='small|medium
* value=10
* onChange={myChangeHandler}
* error=true
* disabled=false
* />
*/
export function OutlinedInput(props: OutlinedInputProps) {
return (
<MUIOutlineInput
{...props}
/>
);
}

Просмотреть файл

@@ -4,8 +4,8 @@
import React from 'react';
import {FormattedMessage} from 'react-intl';
import {useOpenSelfHostedZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm';
import {useOpenSelfHostedZendeskSupportForm} from 'components/common/hooks/useOpenZendeskForm';
import PaymentFailedSvg from 'components/common/svg_images_components/payment_failed_svg';
import IconMessage from 'components/purchase_modal/icon_message';

Просмотреть файл

@@ -14,7 +14,6 @@
display: block;
margin-bottom: 12px;
color: rgba(var(--sys-denim-center-channel-text-rgb), 0.72);
font-family: 'Open Sans';
font-size: 14px;
font-weight: 600;
text-align: center;
@@ -24,7 +23,6 @@
.seatsInput {
width: 73px;
margin-left: auto;
font-family: 'Open Sans';
font-size: 14px;
font-weight: 400;
@@ -46,7 +44,6 @@
.planName {
color: rgba(var(--sys-denim-center-channel-text-rgb), 0.72);
font-family: 'Metropolis';
font-size: 20px;
font-weight: 400;
text-transform: capitalize;
@@ -54,7 +51,6 @@
.usage {
color: rgba(var(--sys-denim-center-channel-text-rgb), 0.56);
font-family: 'Open Sans';
font-size: 12px;
font-weight: 600;
@@ -78,13 +74,11 @@
grid-template-columns: repeat(2, 1fr);
.costPerUser > span:first-child {
font-family: 'Open Sans';
font-size: 14px;
}
.costPerUser > span:last-child {
color: rgba(var(--sys-denim-center-channel-text-rgb), 0.72);
font-family: 'Open Sans';
font-size: 12px;
}
@@ -94,14 +88,12 @@
.totalCostWarning > span:first-child {
color: var(--sys-denim-center-channel-text);
font-family: 'Open Sans';
font-size: 14px;
font-weight: 700;
}
.totalCostWarning > span:last-child {
color: rgba(var(--sys-denim-center-channel-text-rgb), 0.72);
font-family: 'Open Sans';
font-size: 12px;
}
@@ -119,7 +111,6 @@
height: 35px;
margin-bottom: 15px;
color: var(--dnd-indicator);
font-family: 'Open Sans';
font-size: 12px;
font-weight: 600;
text-align: right;
@@ -134,7 +125,6 @@
&__ChargedTodayDisclaimer {
color: rgba(var(--sys-denim-center-channel-text-rgb), 0.72);
font-family: 'Open Sans';
font-size: 12px;
font-weight: 400;
}

Просмотреть файл

@@ -1,21 +1,22 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {OutlinedInput} from '@mui/material';
import moment from 'moment-timezone';
import React, {Fragment, useState} from 'react';
import {FormattedMessage} from 'react-intl';
import React, {useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {useSelector} from 'react-redux';
import moment from 'moment-timezone';
import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {DocLinks} from 'utils/constants';
import WarningIcon from 'components/widgets/icons/fa_warning_icon';
import useGetSelfHostedProducts from 'components/common/hooks/useGetSelfHostedProducts';
import ExternalLink from 'components/external_link';
import {OutlinedInput} from 'components/outlined_input';
import {DocLinks} from 'utils/constants';
import {findSelfHostedProductBySku} from 'utils/hosted_customer';
import './expansion_card.scss';
import useGetSelfHostedProducts from 'components/common/hooks/useGetSelfHostedProducts';
import {findSelfHostedProductBySku} from 'utils/hosted_customer';
import ExternalLink from 'components/external_link';
const MONTHS_IN_YEAR = 12;
const MAX_TRANSACTION_VALUE = 1_000_000 - 1;
@@ -29,6 +30,7 @@ interface Props {
}
export default function SelfHostedExpansionCard(props: Props) {
const intl = useIntl();
const license = useSelector(getLicense);
const startsAt = moment(parseInt(license.StartsAt, 10)).format('MMM. D, YYYY');
const endsAt = moment(parseInt(license.ExpiresAt, 10)).format('MMM. D, YYYY');
@@ -46,14 +48,11 @@ export default function SelfHostedExpansionCard(props: Props) {
};
const getCostPerUser = () => {
if (isNaN(additionalSeats)) {
return 0;
}
const monthsUntilExpiry = getMonthsUntilExpiry();
return costPerMonth * monthsUntilExpiry;
};
const getTotal = () => {
const getPaymentTotal = () => {
if (isNaN(additionalSeats)) {
return 0;
}
@@ -63,25 +62,29 @@ export default function SelfHostedExpansionCard(props: Props) {
// Finds the maximum number of additional seats that is possible, taking into account
// the stripe transaction limit. The maximum number of seats will follow the formula:
// (StripeTransaction Limit - (Current_Seats * Price Per Seat)) / price_per_seat
// (StripeTransaction Limit - (current_seats * yearly_price_per_seat)) / yearly_price_per_seat
const getMaximumAdditionalSeats = () => {
if (currentProduct === null) {
return 0;
}
const currentPaymentPrice = costPerMonth * props.licensedSeats;
const currentPaymentPrice = costPerMonth * props.licensedSeats * 12;
const remainingTransactionLimit = MAX_TRANSACTION_VALUE - currentPaymentPrice;
const remainingSeats = Math.floor(remainingTransactionLimit / costPerMonth);
const remainingSeats = Math.floor(remainingTransactionLimit / (costPerMonth * 12));
return Math.max(0, remainingSeats);
};
const maxAdditionalSeats = getMaximumAdditionalSeats();
const handleNewSeatsInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setOverMaxSeats(false);
const requestedSeats = parseInt(e.target.value, 10);
if (requestedSeats <= 0) {
e.preventDefault();
return;
}
setOverMaxSeats(false);
const overMaxAdditionalSeats = requestedSeats > maxAdditionalSeats;
setOverMaxSeats(overMaxAdditionalSeats);
@@ -91,6 +94,10 @@ export default function SelfHostedExpansionCard(props: Props) {
props.updateSeats(finalSeatCount);
};
const formatCurrency = (value: number) => {
return intl.formatNumber(value, {style: 'currency', currency: 'USD'});
};
return (
<div className='SelfHostedExpansionRHSCard'>
<div className='SelfHostedExpansionRHSCard__RHSCardTitle'>
@@ -158,16 +165,6 @@ export default function SelfHostedExpansionCard(props: Props) {
}}
/>
}
{maxAdditionalSeats === 0 &&
<FormattedMessage
id='self_hosted_expansion_rhs_card_additional_seats_limit_warning'
defaultMessage='{warningIcon} Transaction amount limit reached.{break}Please contact sales'
values={{
break: <br/>,
warningIcon: <WarningIcon additionalClassName={'SelfHostedExpansionRHSCard__warning'}/>,
}}
/>
}
</div>
<div className='SelfHostedExpansionRHSCard__cost_breakdown'>
<div className='costPerUser'>
@@ -179,15 +176,15 @@ export default function SelfHostedExpansionCard(props: Props) {
<FormattedMessage
id='self_hosted_expansion_rhs_card_cost_per_user_breakdown'
/* eslint-disable no-template-curly-in-string*/
defaultMessage='${costPerUser} x {monthsUntilExpiry} months'
defaultMessage='{costPerUser} x {monthsUntilExpiry} months'
values={{
costPerUser: costPerMonth.toFixed(2),
costPerUser: formatCurrency(costPerMonth),
monthsUntilExpiry: getMonthsUntilExpiry(),
}}
/>
</div>
<div className='costAmount'>
<span>{'$' + getCostPerUser().toFixed(2)}</span>
<span>{formatCurrency(getCostPerUser())}</span>
</div>
<div className='totalCostWarning'>
<FormattedMessage
@@ -201,7 +198,7 @@ export default function SelfHostedExpansionCard(props: Props) {
/>
</div>
<span className='totalCostAmount'>
<span>{'$' + getTotal().toFixed(2)}</span>
<span>{formatCurrency(getPaymentTotal()) }</span>
</span>
</div>
<button

Просмотреть файл

@@ -2,55 +2,51 @@
// See LICENSE.txt for license information.
import React, {useEffect, useRef, useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {useDispatch, useSelector} from 'react-redux';
import classNames from 'classnames';
import {StripeCardElementChangeEvent} from '@stripe/stripe-js';
import {getLicenseConfig} from 'mattermost-redux/actions/general';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {getCurrentUser, getFilteredUsersStats} from 'mattermost-redux/selectors/entities/users';
import {getSelfHostedSignupProgress} from 'mattermost-redux/selectors/entities/hosted_customer';
import {DispatchFunc} from 'mattermost-redux/types/actions';
import {HostedCustomerTypes} from 'mattermost-redux/action_types';
import {Client4} from 'mattermost-redux/client';
import {isDevModeEnabled} from 'selectors/general';
import {closeModal} from 'actions/views/modals';
import {pageVisited} from 'actions/telemetry_actions';
import {confirmSelfHostedExpansion} from 'actions/hosted_customer';
import {ValueOf} from '@mattermost/types/utilities';
import {SelfHostedSignupCustomerResponse, SelfHostedSignupProgress} from '@mattermost/types/hosted_customer';
import UpgradeSvg from 'components/common/svg_images_components/upgrade_svg';
import RootPortal from 'components/root_portal';
import ContactSalesLink from 'components/self_hosted_purchases/contact_sales_link';
import ErrorPage from 'components/self_hosted_purchases/self_hosted_expansion_modal/error_page';
import SuccessPage from 'components/self_hosted_purchases/self_hosted_expansion_modal/success_page';
import Submitting from './submitting';
import useLoadStripe from 'components/common/hooks/useLoadStripe';
import CardInput, {CardInputType} from 'components/payment_form/card_input';
import FullScreenModal from 'components/widgets/modals/full_screen_modal';
import Input from 'components/widgets/inputs/input/input';
import BackgroundSvg from 'components/common/svg_images_components/background_svg';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
import StripeProvider from '../stripe_provider';
import {closeModal} from 'actions/views/modals';
import {ModalIdentifiers, TELEMETRY_CATEGORIES} from 'utils/constants';
import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {getCurrentUser, getFilteredUsersStats} from 'mattermost-redux/selectors/entities/users';
import {pageVisited} from 'actions/telemetry_actions';
import {Client4} from 'mattermost-redux/client';
import {HostedCustomerTypes} from 'mattermost-redux/action_types';
import {getSelfHostedSignupProgress} from 'mattermost-redux/selectors/entities/hosted_customer';
import {inferNames} from 'utils/hosted_customer';
import {SelfHostedSignupCustomerResponse, SelfHostedSignupProgress} from '@mattermost/types/hosted_customer';
import {isDevModeEnabled} from 'selectors/general';
import {getLicenseConfig} from 'mattermost-redux/actions/general';
import {confirmSelfHostedExpansion} from 'actions/hosted_customer';
import {DispatchFunc} from 'mattermost-redux/types/actions';
import {ValueOf} from '@mattermost/types/utilities';
import SelfHostedExpansionCard from './expansion_card';
import './self_hosted_expansion_modal.scss';
import {STORAGE_KEY_EXPANSION_IN_PROGRESS} from '../constants';
import Terms from 'components/self_hosted_purchases/self_hosted_purchase_modal/terms';
import Address from 'components/self_hosted_purchases/address';
import ChooseDifferentShipping from 'components/choose_different_shipping';
import Terms from 'components/self_hosted_purchases/self_hosted_purchase_modal/terms';
import classNames from 'classnames';
import {ModalIdentifiers, TELEMETRY_CATEGORIES} from 'utils/constants';
import {inferNames} from 'utils/hosted_customer';
import Submitting from './submitting';
import StripeProvider from '../stripe_provider';
import {STORAGE_KEY_EXPANSION_IN_PROGRESS} from '../constants';
import SelfHostedExpansionCard from './expansion_card';
import './self_hosted_expansion_modal.scss';
export interface FormState {
cardName: string;
@@ -358,7 +354,7 @@ export default function SelfHostedExpansionModal() {
<div className='center'>
<div
className='form'
data-testid='shpm-form'
data-testid='expansion-modal'
>
<span className='section-title'>
{intl.formatMessage({

Просмотреть файл

@@ -38,14 +38,12 @@
margin-right: 16px;
.DropdownInput {
z-index: 99999;
margin-top: 0;
}
}
.DropdownInput {
position: relative;
z-index: 999999;
height: 36px;
margin-bottom: 24px;
@@ -73,7 +71,6 @@
background: var(--center-channel-bg);
.Input {
height: 32px;
background: inherit;
}

Просмотреть файл

@@ -2,12 +2,11 @@
// See LICENSE.txt for license information.
import React, {useEffect, useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {useSelector} from 'react-redux';
import {getSelfHostedSignupProgress} from 'mattermost-redux/selectors/entities/hosted_customer';
import {SelfHostedSignupProgress} from '@mattermost/types/hosted_customer';
import {ValueOf} from '@mattermost/types/utilities';

Просмотреть файл

@@ -10,7 +10,6 @@
justify-content: center;
padding: 77px 107px;
color: var(--center-channel-color);
font-family: "Open Sans";
font-size: 16px;
font-weight: 600;
}

Просмотреть файл

@@ -3,14 +3,14 @@
import React from 'react';
import {FormattedMessage} from 'react-intl';
import {useHistory} from 'react-router-dom';
import IconMessage from 'components/purchase_modal/icon_message';
import PaymentSuccessStandardSvg from 'components/common/svg_images_components/payment_success_standard_svg';
import {ConsolePages} from 'utils/constants';
import BackgroundSvg from 'components/common/svg_images_components/background_svg';
import {ConsolePages} from 'utils/constants';
import './success_page.scss';
interface Props {
@@ -69,9 +69,7 @@ export default function SelfHostedExpansionSuccessPage(props: Props) {
testId='selfHostedExpansionSuccess'
icon={icon}
formattedButtonText={formattedButtonText}
buttonHandler={() => {
props.onClose();
}}
buttonHandler={props.onClose}
/>
<div className='background-svg'>
<BackgroundSvg/>

Просмотреть файл

@@ -4712,7 +4712,6 @@
"select_team.join.icon": "Join Team Icon",
"select_team.private.icon": "Private Team",
"self_hosted_expansion_rhs_card_add_new_seats": "Add new seats",
"self_hosted_expansion_rhs_card_additional_seats_limit_warning": "{warningIcon} Transaction amount limit reached.{break}Please contact sales",
"self_hosted_expansion_rhs_card_cost_per_user_breakdown": "{costPerUser} x {monthsUntilExpiry} months",
"self_hosted_expansion_rhs_card_cost_per_user_title": "Cost per user",
"self_hosted_expansion_rhs_card_license_date": "{startsAt} - {endsAt}",