Update product editor CES modal to match new designs (#38592)
* Add new fields and copy update to product CES modal * Update styling for product CES modal * Record email in tracks callback if provided * Fix modal header spacing * Fix record callback types * Add optional tag styling * Allow submitting form when a reason has been selected * Fix modal padding bottom * Update modal width to match designs * Add changelog entries * Update margin for legend * Add props to doc comment * Make className prop optional * Update tests for recording score with email
This commit is contained in:
parent
0fc765beb3
commit
90e4ddbf29
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add props to allow passing a classname to the feedback modal
|
|
@ -5,6 +5,7 @@ import { createElement, useState } from '@wordpress/element';
|
|||
import PropTypes from 'prop-types';
|
||||
import { Button, Modal } from '@wordpress/components';
|
||||
import { Text } from '@woocommerce/experimental';
|
||||
import classnames from 'classnames';
|
||||
|
||||
/**
|
||||
* Provides a modal requesting customer feedback.
|
||||
|
@ -20,6 +21,7 @@ import { Text } from '@woocommerce/experimental';
|
|||
* @param {string} props.cancelButtonLabel Label for the cancel button.
|
||||
* @param {Function} props.onModalClose Callback for when user closes modal by clicking cancel.
|
||||
* @param {Function} props.children Children to be rendered.
|
||||
* @param {string} props.className Class name to addd to the modal.
|
||||
*/
|
||||
function FeedbackModal( {
|
||||
onSubmit,
|
||||
|
@ -30,6 +32,7 @@ function FeedbackModal( {
|
|||
isSubmitButtonDisabled,
|
||||
submitButtonLabel,
|
||||
cancelButtonLabel,
|
||||
className,
|
||||
}: {
|
||||
onSubmit: () => void;
|
||||
title: string;
|
||||
|
@ -39,6 +42,7 @@ function FeedbackModal( {
|
|||
isSubmitButtonDisabled?: boolean;
|
||||
submitButtonLabel?: string;
|
||||
cancelButtonLabel?: string;
|
||||
className?: string;
|
||||
} ): JSX.Element | null {
|
||||
const [ isOpen, setOpen ] = useState( true );
|
||||
|
||||
|
@ -55,21 +59,23 @@ function FeedbackModal( {
|
|||
|
||||
return (
|
||||
<Modal
|
||||
className="woocommerce-feedback-modal"
|
||||
className={ classnames( 'woocommerce-feedback-modal', className ) }
|
||||
title={ title }
|
||||
onRequestClose={ closeModal }
|
||||
shouldCloseOnClickOutside={ false }
|
||||
>
|
||||
<Text
|
||||
variant="body"
|
||||
as="p"
|
||||
className="woocommerce-feedback-modal__description"
|
||||
size={ 14 }
|
||||
lineHeight="20px"
|
||||
marginBottom="1.5em"
|
||||
>
|
||||
{ description }
|
||||
</Text>
|
||||
{ description && (
|
||||
<Text
|
||||
variant="body"
|
||||
as="p"
|
||||
className="woocommerce-feedback-modal__description"
|
||||
size={ 14 }
|
||||
lineHeight="20px"
|
||||
marginBottom="1.5em"
|
||||
>
|
||||
{ description }
|
||||
</Text>
|
||||
) }
|
||||
{ children }
|
||||
<div className="woocommerce-feedback-modal__buttons">
|
||||
<Button isTertiary onClick={ closeModal } name="cancel">
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: update
|
||||
|
||||
Update product CES modal design and fields
|
|
@ -41,11 +41,16 @@ export const ProductMVPFeedbackModalContainer: React.FC< {
|
|||
`post-new.php?post_type=product&product_block_editor=0&_feature_nonce=${ _feature_nonce }`
|
||||
);
|
||||
|
||||
const recordScore = ( checked: string[], comments: string ) => {
|
||||
const recordScore = (
|
||||
checked: string[],
|
||||
comments: string,
|
||||
email: string
|
||||
) => {
|
||||
recordEvent( 'product_mvp_feedback', {
|
||||
action: 'disable',
|
||||
checked,
|
||||
comments: comments || '',
|
||||
email,
|
||||
} );
|
||||
hideProductMVPFeedbackModal();
|
||||
window.location.href = `${ classicEditorUrl }&new-product-experience-disabled=true`;
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createElement, Fragment, useState } from '@wordpress/element';
|
||||
import {
|
||||
createElement,
|
||||
createInterpolateElement,
|
||||
Fragment,
|
||||
useState,
|
||||
} from '@wordpress/element';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CheckboxControl, TextareaControl } from '@wordpress/components';
|
||||
import {
|
||||
CheckboxControl,
|
||||
TextareaControl,
|
||||
TextControl,
|
||||
} from '@wordpress/components';
|
||||
import { FeedbackModal } from '@woocommerce/customer-effort-score';
|
||||
import { Text } from '@woocommerce/experimental';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
@ -20,7 +29,11 @@ function ProductMVPFeedbackModal( {
|
|||
recordScoreCallback,
|
||||
onCloseModal,
|
||||
}: {
|
||||
recordScoreCallback: ( checked: string[], comments: string ) => void;
|
||||
recordScoreCallback: (
|
||||
checked: string[],
|
||||
comments: string,
|
||||
email: string
|
||||
) => void;
|
||||
onCloseModal?: () => void;
|
||||
} ): JSX.Element | null {
|
||||
const [ missingFeatures, setMissingFeatures ] = useState( false );
|
||||
|
@ -61,37 +74,33 @@ function ProductMVPFeedbackModal( {
|
|||
},
|
||||
];
|
||||
const [ comments, setComments ] = useState( '' );
|
||||
const [ email, setEmail ] = useState( '' );
|
||||
const checked = checkboxes
|
||||
.filter( ( checkbox ) => checkbox.checked )
|
||||
.map( ( checkbox ) => checkbox.key );
|
||||
|
||||
const onSendFeedback = () => {
|
||||
const checked = checkboxes
|
||||
.filter( ( checkbox ) => checkbox.checked )
|
||||
.map( ( checkbox ) => checkbox.key );
|
||||
recordScoreCallback( checked, comments );
|
||||
recordScoreCallback( checked, comments, email );
|
||||
};
|
||||
|
||||
const isSendButtonDisabled =
|
||||
! comments &&
|
||||
! missingFeatures &&
|
||||
! missingPlugins &&
|
||||
! difficultToUse &&
|
||||
! slowBuggyOrBroken &&
|
||||
! other;
|
||||
const optionalElement = (
|
||||
<span className="woocommerce-product-mvp-feedback-modal__optional">
|
||||
{ __( '(optional)', 'woocommerce' ) }
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<FeedbackModal
|
||||
title={ __(
|
||||
'Thanks for trying out the new product editor!',
|
||||
'woocommerce'
|
||||
) }
|
||||
description={ __(
|
||||
'We’re working on making it better, and your feedback will help improve the experience for thousands of merchants like you.',
|
||||
'Thanks for trying out the new product form!',
|
||||
'woocommerce'
|
||||
) }
|
||||
onSubmit={ onSendFeedback }
|
||||
onModalClose={ onCloseModal }
|
||||
isSubmitButtonDisabled={ isSendButtonDisabled }
|
||||
isSubmitButtonDisabled={ ! checked.length }
|
||||
submitButtonLabel={ __( 'Send feedback', 'woocommerce' ) }
|
||||
cancelButtonLabel={ __( 'Skip', 'woocommerce' ) }
|
||||
className="woocommerce-product-mvp-feedback-modal"
|
||||
>
|
||||
<>
|
||||
<Text
|
||||
|
@ -100,45 +109,63 @@ function ProductMVPFeedbackModal( {
|
|||
weight="600"
|
||||
size="14"
|
||||
lineHeight="20px"
|
||||
>
|
||||
{ __(
|
||||
'What made you switch back to the classic product editor?',
|
||||
'woocommerce'
|
||||
) }
|
||||
</Text>
|
||||
<Text
|
||||
weight="400"
|
||||
size="12"
|
||||
as="p"
|
||||
lineHeight="16px"
|
||||
color="#757575"
|
||||
className="woocommerce-product-mvp-feedback-modal__subtitle"
|
||||
>
|
||||
{ __( '(Check all that apply)', 'woocommerce' ) }
|
||||
</Text>
|
||||
<div className="woocommerce-product-mvp-feedback-modal__checkboxes">
|
||||
{ checkboxes.map( ( checkbox, index ) => (
|
||||
<CheckboxControl
|
||||
key={ index }
|
||||
label={ checkbox.label }
|
||||
name={ checkbox.key }
|
||||
checked={ checkbox.checked }
|
||||
onChange={ checkbox.onChange }
|
||||
/>
|
||||
) ) }
|
||||
</div>
|
||||
<div className="woocommerce-product-mvp-feedback-modal__comments">
|
||||
<TextareaControl
|
||||
label={ __( 'Additional comments', 'woocommerce' ) }
|
||||
value={ comments }
|
||||
placeholder={ __(
|
||||
'Optional, but much apprecated. We love reading your feedback!',
|
||||
></Text>
|
||||
<fieldset className="woocommerce-product-mvp-feedback-modal__reason">
|
||||
<legend>
|
||||
{ __(
|
||||
'What made you turn off the new product form?',
|
||||
'woocommerce'
|
||||
) }
|
||||
</legend>
|
||||
<div className="woocommerce-product-mvp-feedback-modal__checkboxes">
|
||||
{ checkboxes.map( ( checkbox, index ) => (
|
||||
<CheckboxControl
|
||||
key={ index }
|
||||
label={ checkbox.label }
|
||||
name={ checkbox.key }
|
||||
checked={ checkbox.checked }
|
||||
onChange={ checkbox.onChange }
|
||||
/>
|
||||
) ) }
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div className="woocommerce-product-mvp-feedback-modal__comments">
|
||||
<TextareaControl
|
||||
label={ createInterpolateElement(
|
||||
__(
|
||||
'Additional thoughts <optional/>',
|
||||
'woocommerce'
|
||||
),
|
||||
{
|
||||
optional: optionalElement,
|
||||
}
|
||||
) }
|
||||
value={ comments }
|
||||
onChange={ ( value: string ) => setComments( value ) }
|
||||
rows={ 5 }
|
||||
/>
|
||||
</div>
|
||||
<div className="woocommerce-product-mvp-feedback-modal__email">
|
||||
<TextControl
|
||||
label={ createInterpolateElement(
|
||||
__(
|
||||
'Your email address <optional/>',
|
||||
'woocommerce'
|
||||
),
|
||||
{
|
||||
optional: optionalElement,
|
||||
}
|
||||
) }
|
||||
value={ email }
|
||||
onChange={ ( value: string ) => setEmail( value ) }
|
||||
rows={ 5 }
|
||||
help={ __(
|
||||
'In case you want to participate in further discussion and future user research.',
|
||||
'woocommerce'
|
||||
) }
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</FeedbackModal>
|
||||
);
|
||||
|
|
|
@ -1,23 +1,62 @@
|
|||
$modal-header-height: 84px;
|
||||
|
||||
.woocommerce-product-mvp-feedback-modal {
|
||||
width: 600px;
|
||||
|
||||
.components-modal__header {
|
||||
height: $modal-header-height;
|
||||
|
||||
&-heading {
|
||||
font-weight: 500;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.components-modal__content {
|
||||
margin-top: $modal-header-height;
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
legend,
|
||||
label {
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
.woocommerce-product-mvp-feedback-modal__optional {
|
||||
color: $gray-700;
|
||||
}
|
||||
|
||||
legend {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
line-height: 1.4;
|
||||
text-transform: uppercase;
|
||||
display: inline-block;
|
||||
margin-bottom: $gap-small;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&__subtitle {
|
||||
margin-top: $gap-smaller !important;
|
||||
}
|
||||
|
||||
&__checkboxes {
|
||||
margin: $gap-small 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
&__comments {
|
||||
margin-top: 2em;
|
||||
margin-bottom: 1.5em;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
text-transform: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__reason,
|
||||
&__comments,
|
||||
&__email {
|
||||
margin-bottom: $gap-large;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ describe( 'ProductMVPFeedbackModal', () => {
|
|||
fireEvent.click( screen.getByRole( 'checkbox', { name: /other/i } ) );
|
||||
expect( mockRecordScoreCallback ).toHaveBeenCalledWith(
|
||||
[ 'other' ],
|
||||
'',
|
||||
''
|
||||
);
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue