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 React from 'react';
import {FormattedMessage} from 'react-intl'; 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 PaymentFailedSvg from 'components/common/svg_images_components/payment_failed_svg';
import IconMessage from 'components/purchase_modal/icon_message'; import IconMessage from 'components/purchase_modal/icon_message';

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

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

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

@@ -1,21 +1,22 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import {OutlinedInput} from '@mui/material'; import React, {useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import moment from 'moment-timezone';
import React, {Fragment, useState} from 'react';
import {FormattedMessage} from 'react-intl';
import {useSelector} from 'react-redux'; import {useSelector} from 'react-redux';
import moment from 'moment-timezone';
import {getLicense} from 'mattermost-redux/selectors/entities/general'; import {getLicense} from 'mattermost-redux/selectors/entities/general';
import {DocLinks} from 'utils/constants';
import WarningIcon from 'components/widgets/icons/fa_warning_icon'; 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 './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 MONTHS_IN_YEAR = 12;
const MAX_TRANSACTION_VALUE = 1_000_000 - 1; const MAX_TRANSACTION_VALUE = 1_000_000 - 1;
@@ -29,6 +30,7 @@ interface Props {
} }
export default function SelfHostedExpansionCard(props: Props) { export default function SelfHostedExpansionCard(props: Props) {
const intl = useIntl();
const license = useSelector(getLicense); const license = useSelector(getLicense);
const startsAt = moment(parseInt(license.StartsAt, 10)).format('MMM. D, YYYY'); const startsAt = moment(parseInt(license.StartsAt, 10)).format('MMM. D, YYYY');
const endsAt = moment(parseInt(license.ExpiresAt, 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 = () => { const getCostPerUser = () => {
if (isNaN(additionalSeats)) {
return 0;
}
const monthsUntilExpiry = getMonthsUntilExpiry(); const monthsUntilExpiry = getMonthsUntilExpiry();
return costPerMonth * monthsUntilExpiry; return costPerMonth * monthsUntilExpiry;
}; };
const getTotal = () => { const getPaymentTotal = () => {
if (isNaN(additionalSeats)) { if (isNaN(additionalSeats)) {
return 0; 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 // 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: // 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 = () => { const getMaximumAdditionalSeats = () => {
if (currentProduct === null) { if (currentProduct === null) {
return 0; return 0;
} }
const currentPaymentPrice = costPerMonth * props.licensedSeats; const currentPaymentPrice = costPerMonth * props.licensedSeats * 12;
const remainingTransactionLimit = MAX_TRANSACTION_VALUE - currentPaymentPrice; const remainingTransactionLimit = MAX_TRANSACTION_VALUE - currentPaymentPrice;
const remainingSeats = Math.floor(remainingTransactionLimit / costPerMonth); const remainingSeats = Math.floor(remainingTransactionLimit / (costPerMonth * 12));
return Math.max(0, remainingSeats); return Math.max(0, remainingSeats);
}; };
const maxAdditionalSeats = getMaximumAdditionalSeats(); const maxAdditionalSeats = getMaximumAdditionalSeats();
const handleNewSeatsInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleNewSeatsInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setOverMaxSeats(false);
const requestedSeats = parseInt(e.target.value, 10); const requestedSeats = parseInt(e.target.value, 10);
if (requestedSeats <= 0) {
e.preventDefault();
return;
}
setOverMaxSeats(false);
const overMaxAdditionalSeats = requestedSeats > maxAdditionalSeats; const overMaxAdditionalSeats = requestedSeats > maxAdditionalSeats;
setOverMaxSeats(overMaxAdditionalSeats); setOverMaxSeats(overMaxAdditionalSeats);
@@ -91,6 +94,10 @@ export default function SelfHostedExpansionCard(props: Props) {
props.updateSeats(finalSeatCount); props.updateSeats(finalSeatCount);
}; };
const formatCurrency = (value: number) => {
return intl.formatNumber(value, {style: 'currency', currency: 'USD'});
};
return ( return (
<div className='SelfHostedExpansionRHSCard'> <div className='SelfHostedExpansionRHSCard'>
<div className='SelfHostedExpansionRHSCard__RHSCardTitle'> <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>
<div className='SelfHostedExpansionRHSCard__cost_breakdown'> <div className='SelfHostedExpansionRHSCard__cost_breakdown'>
<div className='costPerUser'> <div className='costPerUser'>
@@ -179,15 +176,15 @@ export default function SelfHostedExpansionCard(props: Props) {
<FormattedMessage <FormattedMessage
id='self_hosted_expansion_rhs_card_cost_per_user_breakdown' id='self_hosted_expansion_rhs_card_cost_per_user_breakdown'
/* eslint-disable no-template-curly-in-string*/ /* eslint-disable no-template-curly-in-string*/
defaultMessage='${costPerUser} x {monthsUntilExpiry} months' defaultMessage='{costPerUser} x {monthsUntilExpiry} months'
values={{ values={{
costPerUser: costPerMonth.toFixed(2), costPerUser: formatCurrency(costPerMonth),
monthsUntilExpiry: getMonthsUntilExpiry(), monthsUntilExpiry: getMonthsUntilExpiry(),
}} }}
/> />
</div> </div>
<div className='costAmount'> <div className='costAmount'>
<span>{'$' + getCostPerUser().toFixed(2)}</span> <span>{formatCurrency(getCostPerUser())}</span>
</div> </div>
<div className='totalCostWarning'> <div className='totalCostWarning'>
<FormattedMessage <FormattedMessage
@@ -201,7 +198,7 @@ export default function SelfHostedExpansionCard(props: Props) {
/> />
</div> </div>
<span className='totalCostAmount'> <span className='totalCostAmount'>
<span>{'$' + getTotal().toFixed(2)}</span> <span>{formatCurrency(getPaymentTotal()) }</span>
</span> </span>
</div> </div>
<button <button

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

@@ -2,55 +2,51 @@
// See LICENSE.txt for license information. // See LICENSE.txt for license information.
import React, {useEffect, useRef, useState} from 'react'; import React, {useEffect, useRef, useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl'; import {FormattedMessage, useIntl} from 'react-intl';
import {useDispatch, useSelector} from 'react-redux'; import {useDispatch, useSelector} from 'react-redux';
import classNames from 'classnames';
import {StripeCardElementChangeEvent} from '@stripe/stripe-js'; 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 UpgradeSvg from 'components/common/svg_images_components/upgrade_svg';
import RootPortal from 'components/root_portal'; import RootPortal from 'components/root_portal';
import ContactSalesLink from 'components/self_hosted_purchases/contact_sales_link'; import ContactSalesLink from 'components/self_hosted_purchases/contact_sales_link';
import ErrorPage from 'components/self_hosted_purchases/self_hosted_expansion_modal/error_page'; 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 SuccessPage from 'components/self_hosted_purchases/self_hosted_expansion_modal/success_page';
import Submitting from './submitting';
import useLoadStripe from 'components/common/hooks/useLoadStripe'; import useLoadStripe from 'components/common/hooks/useLoadStripe';
import CardInput, {CardInputType} from 'components/payment_form/card_input'; import CardInput, {CardInputType} from 'components/payment_form/card_input';
import FullScreenModal from 'components/widgets/modals/full_screen_modal'; import FullScreenModal from 'components/widgets/modals/full_screen_modal';
import Input from 'components/widgets/inputs/input/input'; import Input from 'components/widgets/inputs/input/input';
import BackgroundSvg from 'components/common/svg_images_components/background_svg'; import BackgroundSvg from 'components/common/svg_images_components/background_svg';
import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; import Terms from 'components/self_hosted_purchases/self_hosted_purchase_modal/terms';
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 Address from 'components/self_hosted_purchases/address'; import Address from 'components/self_hosted_purchases/address';
import ChooseDifferentShipping from 'components/choose_different_shipping'; 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 { export interface FormState {
cardName: string; cardName: string;
@@ -358,7 +354,7 @@ export default function SelfHostedExpansionModal() {
<div className='center'> <div className='center'>
<div <div
className='form' className='form'
data-testid='shpm-form' data-testid='expansion-modal'
> >
<span className='section-title'> <span className='section-title'>
{intl.formatMessage({ {intl.formatMessage({

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

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

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

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

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

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

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

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

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

@@ -4712,7 +4712,6 @@
"select_team.join.icon": "Join Team Icon", "select_team.join.icon": "Join Team Icon",
"select_team.private.icon": "Private Team", "select_team.private.icon": "Private Team",
"self_hosted_expansion_rhs_card_add_new_seats": "Add new seats", "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_breakdown": "{costPerUser} x {monthsUntilExpiry} months",
"self_hosted_expansion_rhs_card_cost_per_user_title": "Cost per user", "self_hosted_expansion_rhs_card_cost_per_user_title": "Cost per user",
"self_hosted_expansion_rhs_card_license_date": "{startsAt} - {endsAt}", "self_hosted_expansion_rhs_card_license_date": "{startsAt} - {endsAt}",