Add additional question to CES modal (#35680)
This commit is contained in:
parent
cfffb27c45
commit
4db5c0d8cd
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: major
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Updating to accept two questions to display in CES modal.
|
|
@ -14,8 +14,14 @@ import { CustomerFeedbackModal } from './customer-feedback-modal';
|
||||||
const noop = () => {};
|
const noop = () => {};
|
||||||
|
|
||||||
type CustomerEffortScoreProps = {
|
type CustomerEffortScoreProps = {
|
||||||
recordScoreCallback: ( score: number, comments: string ) => void;
|
recordScoreCallback: (
|
||||||
label: string;
|
score: number,
|
||||||
|
secondScore: number,
|
||||||
|
comments: string
|
||||||
|
) => void;
|
||||||
|
title: string;
|
||||||
|
firstQuestion: string;
|
||||||
|
secondQuestion: string;
|
||||||
onNoticeShownCallback?: () => void;
|
onNoticeShownCallback?: () => void;
|
||||||
onNoticeDismissedCallback?: () => void;
|
onNoticeDismissedCallback?: () => void;
|
||||||
onModalShownCallback?: () => void;
|
onModalShownCallback?: () => void;
|
||||||
|
@ -30,7 +36,9 @@ type CustomerEffortScoreProps = {
|
||||||
*
|
*
|
||||||
* @param {Object} props Component props.
|
* @param {Object} props Component props.
|
||||||
* @param {Function} props.recordScoreCallback Function to call when the score should be recorded.
|
* @param {Function} props.recordScoreCallback Function to call when the score should be recorded.
|
||||||
* @param {string} props.label The label displayed in the modal.
|
* @param {string} props.title The title displayed in the modal.
|
||||||
|
* @param {string} props.firstQuestion The first survey question.
|
||||||
|
* @param {string} props.secondQuestion The second survey question.
|
||||||
* @param {Function} props.onNoticeShownCallback Function to call when the notice is shown.
|
* @param {Function} props.onNoticeShownCallback Function to call when the notice is shown.
|
||||||
* @param {Function} props.onNoticeDismissedCallback Function to call when the notice is dismissed.
|
* @param {Function} props.onNoticeDismissedCallback Function to call when the notice is dismissed.
|
||||||
* @param {Function} props.onModalShownCallback Function to call when the modal is shown.
|
* @param {Function} props.onModalShownCallback Function to call when the modal is shown.
|
||||||
|
@ -38,7 +46,9 @@ type CustomerEffortScoreProps = {
|
||||||
*/
|
*/
|
||||||
const CustomerEffortScore: React.VFC< CustomerEffortScoreProps > = ( {
|
const CustomerEffortScore: React.VFC< CustomerEffortScoreProps > = ( {
|
||||||
recordScoreCallback,
|
recordScoreCallback,
|
||||||
label,
|
title,
|
||||||
|
firstQuestion,
|
||||||
|
secondQuestion,
|
||||||
onNoticeShownCallback = noop,
|
onNoticeShownCallback = noop,
|
||||||
onNoticeDismissedCallback = noop,
|
onNoticeDismissedCallback = noop,
|
||||||
onModalShownCallback = noop,
|
onModalShownCallback = noop,
|
||||||
|
@ -53,7 +63,7 @@ const CustomerEffortScore: React.VFC< CustomerEffortScoreProps > = ( {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
createNotice( 'success', label, {
|
createNotice( 'success', title, {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
label: __( 'Give feedback', 'woocommerce' ),
|
label: __( 'Give feedback', 'woocommerce' ),
|
||||||
|
@ -83,7 +93,9 @@ const CustomerEffortScore: React.VFC< CustomerEffortScoreProps > = ( {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CustomerFeedbackModal
|
<CustomerFeedbackModal
|
||||||
label={ label }
|
title={ title }
|
||||||
|
firstQuestion={ firstQuestion }
|
||||||
|
secondQuestion={ secondQuestion }
|
||||||
recordScoreCallback={ recordScoreCallback }
|
recordScoreCallback={ recordScoreCallback }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -95,9 +107,9 @@ CustomerEffortScore.propTypes = {
|
||||||
*/
|
*/
|
||||||
recordScoreCallback: PropTypes.func.isRequired,
|
recordScoreCallback: PropTypes.func.isRequired,
|
||||||
/**
|
/**
|
||||||
* The label displayed in the modal.
|
* The title displayed in the modal.
|
||||||
*/
|
*/
|
||||||
label: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
/**
|
/**
|
||||||
* The function to call when the notice is shown.
|
* The function to call when the notice is shown.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,18 +25,28 @@ import { __ } from '@wordpress/i18n';
|
||||||
*
|
*
|
||||||
* @param {Object} props Component props.
|
* @param {Object} props Component props.
|
||||||
* @param {Function} props.recordScoreCallback Function to call when the results are sent.
|
* @param {Function} props.recordScoreCallback Function to call when the results are sent.
|
||||||
* @param {string} props.label Question to ask the customer.
|
* @param {string} props.title Title displayed in the modal.
|
||||||
|
* @param {string} props.firstQuestion The first survey question.
|
||||||
|
* @param {string} props.secondQuestion The second survey question.
|
||||||
* @param {string} props.defaultScore Default score.
|
* @param {string} props.defaultScore Default score.
|
||||||
* @param {Function} props.onCloseModal Callback for when user closes modal by clicking cancel.
|
* @param {Function} props.onCloseModal Callback for when user closes modal by clicking cancel.
|
||||||
*/
|
*/
|
||||||
function CustomerFeedbackModal( {
|
function CustomerFeedbackModal( {
|
||||||
recordScoreCallback,
|
recordScoreCallback,
|
||||||
label,
|
title,
|
||||||
|
firstQuestion,
|
||||||
|
secondQuestion,
|
||||||
defaultScore = NaN,
|
defaultScore = NaN,
|
||||||
onCloseModal,
|
onCloseModal,
|
||||||
}: {
|
}: {
|
||||||
recordScoreCallback: ( score: number, comments: string ) => void;
|
recordScoreCallback: (
|
||||||
label: string;
|
score: number,
|
||||||
|
secondScore: number,
|
||||||
|
comments: string
|
||||||
|
) => void;
|
||||||
|
title: string;
|
||||||
|
firstQuestion: string;
|
||||||
|
secondQuestion: string;
|
||||||
defaultScore?: number;
|
defaultScore?: number;
|
||||||
onCloseModal?: () => void;
|
onCloseModal?: () => void;
|
||||||
} ): JSX.Element | null {
|
} ): JSX.Element | null {
|
||||||
|
@ -63,7 +73,12 @@ function CustomerFeedbackModal( {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const [ score, setScore ] = useState( defaultScore || NaN );
|
const [ firstQuestionScore, setFirstQuestionScore ] = useState(
|
||||||
|
defaultScore || NaN
|
||||||
|
);
|
||||||
|
const [ secondQuestionScore, setSecondQuestionScore ] = useState(
|
||||||
|
defaultScore || NaN
|
||||||
|
);
|
||||||
const [ comments, setComments ] = useState( '' );
|
const [ comments, setComments ] = useState( '' );
|
||||||
const [ showNoScoreMessage, setShowNoScoreMessage ] = useState( false );
|
const [ showNoScoreMessage, setShowNoScoreMessage ] = useState( false );
|
||||||
const [ isOpen, setOpen ] = useState( true );
|
const [ isOpen, setOpen ] = useState( true );
|
||||||
|
@ -75,19 +90,31 @@ function CustomerFeedbackModal( {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRadioControlChange = ( value: string ) => {
|
const onRadioControlChange = (
|
||||||
|
value: string,
|
||||||
|
setter: ( val: number ) => void
|
||||||
|
) => {
|
||||||
const valueAsInt = parseInt( value, 10 );
|
const valueAsInt = parseInt( value, 10 );
|
||||||
setScore( valueAsInt );
|
setter( valueAsInt );
|
||||||
setShowNoScoreMessage( ! Number.isInteger( valueAsInt ) );
|
setShowNoScoreMessage( ! Number.isInteger( valueAsInt ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendScore = () => {
|
const sendScore = () => {
|
||||||
if ( ! Number.isInteger( score ) ) {
|
if (
|
||||||
|
! (
|
||||||
|
Number.isInteger( firstQuestionScore ) &&
|
||||||
|
Number.isInteger( secondQuestionScore )
|
||||||
|
)
|
||||||
|
) {
|
||||||
setShowNoScoreMessage( true );
|
setShowNoScoreMessage( true );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setOpen( false );
|
setOpen( false );
|
||||||
recordScoreCallback( score, comments );
|
recordScoreCallback(
|
||||||
|
firstQuestionScore,
|
||||||
|
secondQuestionScore,
|
||||||
|
comments
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( ! isOpen ) {
|
if ( ! isOpen ) {
|
||||||
|
@ -97,10 +124,24 @@ function CustomerFeedbackModal( {
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
className="woocommerce-customer-effort-score"
|
className="woocommerce-customer-effort-score"
|
||||||
title={ __( 'Please share your feedback', 'woocommerce' ) }
|
title={ title }
|
||||||
onRequestClose={ closeModal }
|
onRequestClose={ closeModal }
|
||||||
shouldCloseOnClickOutside={ false }
|
shouldCloseOnClickOutside={ false }
|
||||||
>
|
>
|
||||||
|
<Text
|
||||||
|
variant="body"
|
||||||
|
as="p"
|
||||||
|
className="woocommerce-customer-effort-score__intro"
|
||||||
|
size={ 14 }
|
||||||
|
lineHeight="20px"
|
||||||
|
marginBottom="1.5em"
|
||||||
|
>
|
||||||
|
{ __(
|
||||||
|
'Your feedback will help create a better experience for thousands of merchants like you. Please tell us to what extent you agree or disagree with the statements below.',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
</Text>
|
||||||
|
|
||||||
<Text
|
<Text
|
||||||
variant="subtitle.small"
|
variant="subtitle.small"
|
||||||
as="p"
|
as="p"
|
||||||
|
@ -108,26 +149,63 @@ function CustomerFeedbackModal( {
|
||||||
size="14"
|
size="14"
|
||||||
lineHeight="20px"
|
lineHeight="20px"
|
||||||
>
|
>
|
||||||
{ label }
|
{ firstQuestion }
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<div className="woocommerce-customer-effort-score__selection">
|
<div className="woocommerce-customer-effort-score__selection">
|
||||||
<RadioControl
|
<RadioControl
|
||||||
selected={ score.toString( 10 ) }
|
selected={ firstQuestionScore.toString( 10 ) }
|
||||||
options={ options }
|
options={ options }
|
||||||
onChange={ onRadioControlChange }
|
onChange={ ( value ) =>
|
||||||
|
onRadioControlChange(
|
||||||
|
value as string,
|
||||||
|
setFirstQuestionScore
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ ( score === 1 || score === 2 ) && (
|
<Text
|
||||||
|
variant="subtitle.small"
|
||||||
|
as="p"
|
||||||
|
weight="600"
|
||||||
|
size="14"
|
||||||
|
lineHeight="20px"
|
||||||
|
>
|
||||||
|
{ secondQuestion }
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<div className="woocommerce-customer-effort-score__selection">
|
||||||
|
<RadioControl
|
||||||
|
selected={ secondQuestionScore.toString( 10 ) }
|
||||||
|
options={ options }
|
||||||
|
onChange={ ( value ) =>
|
||||||
|
onRadioControlChange(
|
||||||
|
value as string,
|
||||||
|
setSecondQuestionScore
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ [ firstQuestionScore, secondQuestionScore ].some(
|
||||||
|
( score ) => score === 1 || score === 2
|
||||||
|
) && (
|
||||||
<div className="woocommerce-customer-effort-score__comments">
|
<div className="woocommerce-customer-effort-score__comments">
|
||||||
<TextareaControl
|
<TextareaControl
|
||||||
label={ __( 'Comments (optional)', 'woocommerce' ) }
|
label={ __(
|
||||||
|
'How is that screen useful to you? What features would you add or change?',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
help={ __(
|
help={ __(
|
||||||
'Your feedback will go to the WooCommerce development team',
|
'Your feedback will go to the WooCommerce development team',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
) }
|
) }
|
||||||
value={ comments }
|
value={ comments }
|
||||||
|
placeholder={ __(
|
||||||
|
'Optional, but much apprecated. We love reading your feedback!',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
onChange={ ( value: string ) => setComments( value ) }
|
onChange={ ( value: string ) => setComments( value ) }
|
||||||
rows={ 5 }
|
rows={ 5 }
|
||||||
/>
|
/>
|
||||||
|
@ -153,7 +231,7 @@ function CustomerFeedbackModal( {
|
||||||
{ __( 'Cancel', 'woocommerce' ) }
|
{ __( 'Cancel', 'woocommerce' ) }
|
||||||
</Button>
|
</Button>
|
||||||
<Button isPrimary onClick={ sendScore } name="send">
|
<Button isPrimary onClick={ sendScore } name="send">
|
||||||
{ __( 'Send', 'woocommerce' ) }
|
{ __( 'Share', 'woocommerce' ) }
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -162,7 +240,9 @@ function CustomerFeedbackModal( {
|
||||||
|
|
||||||
CustomerFeedbackModal.propTypes = {
|
CustomerFeedbackModal.propTypes = {
|
||||||
recordScoreCallback: PropTypes.func.isRequired,
|
recordScoreCallback: PropTypes.func.isRequired,
|
||||||
label: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
|
firstQuestion: PropTypes.string.isRequired,
|
||||||
|
secondQuestion: PropTypes.string.isRequired,
|
||||||
defaultScore: PropTypes.number,
|
defaultScore: PropTypes.number,
|
||||||
onCloseModal: PropTypes.func,
|
onCloseModal: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,9 @@ describe( 'CustomerFeedbackModal', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerFeedbackModal
|
<CustomerFeedbackModal
|
||||||
recordScoreCallback={ mockRecordScoreCallback }
|
recordScoreCallback={ mockRecordScoreCallback }
|
||||||
label="Testing"
|
title="Testing"
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -33,13 +35,15 @@ describe( 'CustomerFeedbackModal', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerFeedbackModal
|
<CustomerFeedbackModal
|
||||||
recordScoreCallback={ mockRecordScoreCallback }
|
recordScoreCallback={ mockRecordScoreCallback }
|
||||||
label="Testing"
|
title="Testing"
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
await screen.findByRole( 'dialog' ); // Wait for the modal to render.
|
await screen.findByRole( 'dialog' ); // Wait for the modal to render.
|
||||||
|
|
||||||
fireEvent.click( screen.getByRole( 'button', { name: /send/i } ) ); // Press send button.
|
fireEvent.click( screen.getByRole( 'button', { name: /share/i } ) ); // Press send button.
|
||||||
|
|
||||||
// Wait for error message.
|
// Wait for error message.
|
||||||
await screen.findByRole( 'alert' );
|
await screen.findByRole( 'alert' );
|
||||||
|
@ -51,7 +55,9 @@ describe( 'CustomerFeedbackModal', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerFeedbackModal
|
<CustomerFeedbackModal
|
||||||
recordScoreCallback={ mockRecordScoreCallback }
|
recordScoreCallback={ mockRecordScoreCallback }
|
||||||
label="Testing"
|
title="Testing"
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -59,7 +65,9 @@ describe( 'CustomerFeedbackModal', () => {
|
||||||
await screen.findByRole( 'dialog' );
|
await screen.findByRole( 'dialog' );
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen.queryByLabelText( 'Comments (optional)' )
|
screen.queryByLabelText(
|
||||||
|
'How is that screen useful to you? What features would you add or change?'
|
||||||
|
)
|
||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -69,7 +77,9 @@ describe( 'CustomerFeedbackModal', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerFeedbackModal
|
<CustomerFeedbackModal
|
||||||
recordScoreCallback={ mockRecordScoreCallback }
|
recordScoreCallback={ mockRecordScoreCallback }
|
||||||
label="Testing"
|
title="Testing"
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -77,18 +87,22 @@ describe( 'CustomerFeedbackModal', () => {
|
||||||
await screen.findByRole( 'dialog' );
|
await screen.findByRole( 'dialog' );
|
||||||
|
|
||||||
// Select the option.
|
// Select the option.
|
||||||
fireEvent.click( screen.getByLabelText( labelText ) );
|
fireEvent.click( screen.getAllByLabelText( labelText )[ 0 ] );
|
||||||
|
|
||||||
// Wait for comments field to show.
|
// Wait for comments field to show.
|
||||||
await screen.findByLabelText( 'Comments (optional)' );
|
await screen.findByLabelText(
|
||||||
|
'How is that screen useful to you? What features would you add or change?'
|
||||||
|
);
|
||||||
|
|
||||||
// Select neutral score.
|
// Select neutral score.
|
||||||
fireEvent.click( screen.getByLabelText( 'Neutral' ) );
|
fireEvent.click( screen.getAllByLabelText( 'Neutral' )[ 0 ] );
|
||||||
|
|
||||||
// Wait for comments field to hide.
|
// Wait for comments field to hide.
|
||||||
await waitFor( () => {
|
await waitFor( () => {
|
||||||
expect(
|
expect(
|
||||||
screen.queryByLabelText( 'Comments (optional)' )
|
screen.queryByLabelText(
|
||||||
|
'How is that screen useful to you? What features would you add or change?'
|
||||||
|
)
|
||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@import 'customer-feedback-simple/customer-feedback-simple.scss';
|
@import 'customer-feedback-simple/customer-feedback-simple.scss';
|
||||||
|
|
||||||
.woocommerce-customer-effort-score__selection {
|
.woocommerce-customer-effort-score__selection {
|
||||||
margin: 1em 0;
|
margin: 1em 0 1.5em 0;
|
||||||
|
|
||||||
.components-base-control__field {
|
.components-base-control__field {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -91,10 +91,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-customer-effort-score__comments {
|
.woocommerce-customer-effort-score__comments {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
display: block;
|
display: block;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
text-transform: none;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
|
@ -109,3 +113,8 @@
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.woocommerce-customer-effort-score .woocommerce-customer-effort-score__intro {
|
||||||
|
max-width: 550px;
|
||||||
|
margin: 0 0 1.5em 0;
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,9 @@ describe( 'CustomerEffortScore', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerEffortScore
|
<CustomerEffortScore
|
||||||
recordScoreCallback={ noop }
|
recordScoreCallback={ noop }
|
||||||
label={ 'label' }
|
title={ 'title' }
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
onNoticeDismissedCallback={ noop }
|
onNoticeDismissedCallback={ noop }
|
||||||
icon={ icon }
|
icon={ icon }
|
||||||
/>
|
/>
|
||||||
|
@ -45,7 +47,7 @@ describe( 'CustomerEffortScore', () => {
|
||||||
// Notice status.
|
// Notice status.
|
||||||
expect.any( String ),
|
expect.any( String ),
|
||||||
// Notice message.
|
// Notice message.
|
||||||
'label',
|
'title',
|
||||||
// Notice options.
|
// Notice options.
|
||||||
expect.objectContaining( {
|
expect.objectContaining( {
|
||||||
icon,
|
icon,
|
||||||
|
@ -63,7 +65,9 @@ describe( 'CustomerEffortScore', () => {
|
||||||
const { rerender } = render(
|
const { rerender } = render(
|
||||||
<CustomerEffortScore
|
<CustomerEffortScore
|
||||||
recordScoreCallback={ noop }
|
recordScoreCallback={ noop }
|
||||||
label={ 'label' }
|
title={ 'title' }
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -71,7 +75,9 @@ describe( 'CustomerEffortScore', () => {
|
||||||
rerender(
|
rerender(
|
||||||
<CustomerEffortScore
|
<CustomerEffortScore
|
||||||
recordScoreCallback={ noop }
|
recordScoreCallback={ noop }
|
||||||
label={ 'label2' }
|
title={ 'title2' }
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -82,7 +88,9 @@ describe( 'CustomerEffortScore', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerEffortScore
|
<CustomerEffortScore
|
||||||
recordScoreCallback={ noop }
|
recordScoreCallback={ noop }
|
||||||
label={ 'label' }
|
title={ 'title' }
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -121,7 +129,9 @@ describe( 'CustomerEffortScore', () => {
|
||||||
render(
|
render(
|
||||||
<CustomerEffortScore
|
<CustomerEffortScore
|
||||||
recordScoreCallback={ noop }
|
recordScoreCallback={ noop }
|
||||||
label={ 'label' }
|
title={ 'title' }
|
||||||
|
firstQuestion="First question"
|
||||||
|
secondQuestion="Second question"
|
||||||
onModalShownCallback={ mockOnModalShownCallback }
|
onModalShownCallback={ mockOnModalShownCallback }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -49,7 +49,9 @@ function CustomerEffortScoreTracksContainer( {
|
||||||
<CustomerEffortScoreTracks
|
<CustomerEffortScoreTracks
|
||||||
key={ index }
|
key={ index }
|
||||||
action={ item.action }
|
action={ item.action }
|
||||||
label={ item.label }
|
firstQuestion={ item.firstQuestion }
|
||||||
|
secondQuestion={ item.secondQuestion }
|
||||||
|
title={ item.title }
|
||||||
onSubmitLabel={ item.onsubmit_label }
|
onSubmitLabel={ item.onsubmit_label }
|
||||||
trackProps={ item.props || {} }
|
trackProps={ item.props || {} }
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -22,7 +22,9 @@ const ALLOW_TRACKING_OPTION_NAME = 'woocommerce_allow_tracking';
|
||||||
* @param {Object} props Component props.
|
* @param {Object} props Component props.
|
||||||
* @param {string} props.action The action name sent to Tracks.
|
* @param {string} props.action The action name sent to Tracks.
|
||||||
* @param {Object} props.trackProps Additional props sent to Tracks.
|
* @param {Object} props.trackProps Additional props sent to Tracks.
|
||||||
* @param {string} props.label The label displayed in the modal.
|
* @param {string} props.title The title displayed in the modal.
|
||||||
|
* @param {string} props.firstQuestion The first survey question.
|
||||||
|
* @param {string} props.secondQuestion The second survey question.
|
||||||
* @param {string} props.onSubmitLabel The label displayed upon survey submission.
|
* @param {string} props.onSubmitLabel The label displayed upon survey submission.
|
||||||
* @param {Array} props.cesShownForActions The array of actions that the CES modal has been shown for.
|
* @param {Array} props.cesShownForActions The array of actions that the CES modal has been shown for.
|
||||||
* @param {boolean} props.allowTracking Whether tracking is allowed or not.
|
* @param {boolean} props.allowTracking Whether tracking is allowed or not.
|
||||||
|
@ -34,7 +36,9 @@ const ALLOW_TRACKING_OPTION_NAME = 'woocommerce_allow_tracking';
|
||||||
function CustomerEffortScoreTracks( {
|
function CustomerEffortScoreTracks( {
|
||||||
action,
|
action,
|
||||||
trackProps,
|
trackProps,
|
||||||
label,
|
title,
|
||||||
|
firstQuestion,
|
||||||
|
secondQuestion,
|
||||||
onSubmitLabel = __( 'Thank you for your feedback!', 'woocommerce' ),
|
onSubmitLabel = __( 'Thank you for your feedback!', 'woocommerce' ),
|
||||||
cesShownForActions,
|
cesShownForActions,
|
||||||
allowTracking,
|
allowTracking,
|
||||||
|
@ -104,10 +108,12 @@ function CustomerEffortScoreTracks( {
|
||||||
addActionToShownOption();
|
addActionToShownOption();
|
||||||
};
|
};
|
||||||
|
|
||||||
const recordScore = ( score, comments ) => {
|
const recordScore = ( score, secondScore, comments ) => {
|
||||||
recordEvent( 'ces_feedback', {
|
recordEvent( 'ces_feedback', {
|
||||||
action,
|
action,
|
||||||
score,
|
score,
|
||||||
|
score_second_question: secondScore,
|
||||||
|
score_combined: score + secondScore,
|
||||||
comments: comments || '',
|
comments: comments || '',
|
||||||
store_age: storeAgeInWeeks,
|
store_age: storeAgeInWeeks,
|
||||||
...trackProps,
|
...trackProps,
|
||||||
|
@ -118,7 +124,9 @@ function CustomerEffortScoreTracks( {
|
||||||
return (
|
return (
|
||||||
<CustomerEffortScore
|
<CustomerEffortScore
|
||||||
recordScoreCallback={ recordScore }
|
recordScoreCallback={ recordScore }
|
||||||
label={ label }
|
title={ title }
|
||||||
|
firstQuestion={ firstQuestion }
|
||||||
|
secondQuestion={ secondQuestion }
|
||||||
onNoticeShownCallback={ onNoticeShown }
|
onNoticeShownCallback={ onNoticeShown }
|
||||||
onNoticeDismissedCallback={ onNoticeDismissed }
|
onNoticeDismissedCallback={ onNoticeDismissed }
|
||||||
onModalShownCallback={ onModalShown }
|
onModalShownCallback={ onModalShown }
|
||||||
|
|
|
@ -23,25 +23,32 @@ export function setCesSurveyQueue( queue ) {
|
||||||
/**
|
/**
|
||||||
* Add a new CES track to the state.
|
* Add a new CES track to the state.
|
||||||
*
|
*
|
||||||
* @param {string} action action name for the survey
|
* @param {Object} args All arguments.
|
||||||
* @param {string} label label for the snackback
|
* @param {string} args.action action name for the survey
|
||||||
* @param {string} pageNow value of window.pagenow
|
* @param {string} args.title title for the snackback
|
||||||
* @param {string} adminPage value of window.adminpage
|
* @param {string} args.firstQuestion first question for modal survey
|
||||||
* @param {string} onsubmitLabel label for the snackback onsubmit
|
* @param {string} args.secondQuestion second question for modal survey
|
||||||
* @param {Object} props object for optional props
|
* @param {string} args.pageNow value of window.pagenow
|
||||||
|
* @param {string} args.adminPage value of window.adminpage
|
||||||
|
* @param {string} args.onsubmitLabel label for the snackback onsubmit
|
||||||
|
* @param {Object} args.props object for optional props
|
||||||
*/
|
*/
|
||||||
export function addCesSurvey(
|
export function addCesSurvey( {
|
||||||
action,
|
action,
|
||||||
label,
|
title,
|
||||||
|
firstQuestion,
|
||||||
|
secondQuestion,
|
||||||
pageNow = window.pagenow,
|
pageNow = window.pagenow,
|
||||||
adminPage = window.adminpage,
|
adminPage = window.adminpage,
|
||||||
onsubmitLabel = undefined,
|
onsubmitLabel = undefined,
|
||||||
props = {}
|
props = {},
|
||||||
) {
|
} ) {
|
||||||
return {
|
return {
|
||||||
type: TYPES.ADD_CES_SURVEY,
|
type: TYPES.ADD_CES_SURVEY,
|
||||||
action,
|
action,
|
||||||
label,
|
title,
|
||||||
|
firstQuestion,
|
||||||
|
secondQuestion,
|
||||||
pageNow,
|
pageNow,
|
||||||
adminPage,
|
adminPage,
|
||||||
onsubmit_label: onsubmitLabel,
|
onsubmit_label: onsubmitLabel,
|
||||||
|
@ -53,26 +60,45 @@ export function addCesSurvey(
|
||||||
* Add a new CES survey track for the pages in Analytics menu
|
* Add a new CES survey track for the pages in Analytics menu
|
||||||
*/
|
*/
|
||||||
export function addCesSurveyForAnalytics() {
|
export function addCesSurveyForAnalytics() {
|
||||||
return addCesSurvey(
|
return addCesSurvey( {
|
||||||
'analytics_filtered',
|
action: 'analytics_filtered',
|
||||||
__( 'How easy was it to filter your store analytics?', 'woocommerce' ),
|
title: __(
|
||||||
'woocommerce_page_wc-admin',
|
'How easy was it to filter your store analytics?',
|
||||||
'woocommerce_page_wc-admin'
|
'woocommerce'
|
||||||
);
|
),
|
||||||
|
firstQuestion: __(
|
||||||
|
'The filters in the analytics screen are easy to use.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
secondQuestion: __(
|
||||||
|
`The filters' functionality meets my needs.`,
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
pageNow: 'woocommerce_page_wc-admin',
|
||||||
|
adminPage: 'woocommerce_page_wc-admin',
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new CES survey track on searching customers.
|
* Add a new CES survey track on searching customers.
|
||||||
*/
|
*/
|
||||||
export function addCesSurveyForCustomerSearch() {
|
export function addCesSurveyForCustomerSearch() {
|
||||||
return addCesSurvey(
|
return addCesSurvey( {
|
||||||
'ces_search',
|
action: 'ces_search',
|
||||||
__( 'How easy was it to use search?', 'woocommerce' ),
|
title: __( 'How easy was it to use search?', 'woocommerce' ),
|
||||||
'woocommerce_page_wc-admin',
|
firstQuestion: __(
|
||||||
'woocommerce_page_wc-admin',
|
'The search feature in WooCommerce is easy to use.',
|
||||||
undefined,
|
'woocommerce'
|
||||||
{
|
),
|
||||||
|
secondQuestion: __(
|
||||||
|
`The search's functionality meets my needs.`,
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
pageNow: 'woocommerce_page_wc-admin',
|
||||||
|
adminPage: 'woocommerce_page_wc-admin',
|
||||||
|
onsubmit_label: undefined,
|
||||||
|
props: {
|
||||||
search_area: 'customer',
|
search_area: 'customer',
|
||||||
}
|
},
|
||||||
);
|
} );
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ const reducer = ( state = DEFAULT_STATE, action ) => {
|
||||||
}
|
}
|
||||||
const newTrack = {
|
const newTrack = {
|
||||||
action: action.action,
|
action: action.action,
|
||||||
label: action.label,
|
title: action.title,
|
||||||
|
firstQuestion: action.firstQuestion,
|
||||||
|
secondQuestion: action.secondQuestion,
|
||||||
pagenow: action.pageNow,
|
pagenow: action.pageNow,
|
||||||
adminpage: action.adminPage,
|
adminpage: action.adminPage,
|
||||||
onSubmitLabel: action.onSubmitLabel,
|
onSubmitLabel: action.onSubmitLabel,
|
||||||
|
|
|
@ -97,10 +97,20 @@ export const TaskListCompletedHeader: React.FC<
|
||||||
}
|
}
|
||||||
}, [ hasSubmittedScore ] );
|
}, [ hasSubmittedScore ] );
|
||||||
|
|
||||||
const submitScore = ( recordedScore: number, comments?: string ) => {
|
const submitScore = ( {
|
||||||
|
firstScore,
|
||||||
|
secondScore,
|
||||||
|
comments,
|
||||||
|
}: {
|
||||||
|
firstScore: number;
|
||||||
|
secondScore?: number;
|
||||||
|
comments?: string;
|
||||||
|
} ) => {
|
||||||
recordEvent( 'ces_feedback', {
|
recordEvent( 'ces_feedback', {
|
||||||
action: CUSTOMER_EFFORT_SCORE_ACTION,
|
action: CUSTOMER_EFFORT_SCORE_ACTION,
|
||||||
score: recordedScore,
|
score: firstScore,
|
||||||
|
score_second_question: secondScore ?? null,
|
||||||
|
score_combined: firstScore + ( secondScore ?? 0 ),
|
||||||
comments: comments || '',
|
comments: comments || '',
|
||||||
store_age: storeAgeInWeeks,
|
store_age: storeAgeInWeeks,
|
||||||
} );
|
} );
|
||||||
|
@ -116,7 +126,7 @@ export const TaskListCompletedHeader: React.FC<
|
||||||
const recordScore = ( recordedScore: number ) => {
|
const recordScore = ( recordedScore: number ) => {
|
||||||
if ( recordedScore > 2 ) {
|
if ( recordedScore > 2 ) {
|
||||||
setScore( recordedScore );
|
setScore( recordedScore );
|
||||||
submitScore( recordedScore );
|
submitScore( { firstScore: recordedScore } );
|
||||||
} else {
|
} else {
|
||||||
setScore( recordedScore );
|
setScore( recordedScore );
|
||||||
setShowCesModal( true );
|
setShowCesModal( true );
|
||||||
|
@ -127,9 +137,13 @@ export const TaskListCompletedHeader: React.FC<
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const recordModalScore = ( recordedScore: number, comments: string ) => {
|
const recordModalScore = (
|
||||||
|
firstScore: number,
|
||||||
|
secondScore: number,
|
||||||
|
comments: string
|
||||||
|
) => {
|
||||||
setShowCesModal( false );
|
setShowCesModal( false );
|
||||||
submitScore( recordedScore, comments );
|
submitScore( { firstScore, secondScore, comments } );
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -230,7 +244,15 @@ export const TaskListCompletedHeader: React.FC<
|
||||||
</div>
|
</div>
|
||||||
{ showCesModal ? (
|
{ showCesModal ? (
|
||||||
<CustomerFeedbackModal
|
<CustomerFeedbackModal
|
||||||
label={ __( 'How was your experience?', 'woocommerce' ) }
|
title={ __( 'How was your experience?', 'woocommerce' ) }
|
||||||
|
firstQuestion={ __(
|
||||||
|
'The store setup is easy to complete.',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
secondQuestion={ __(
|
||||||
|
'The store setup process meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
defaultScore={ score }
|
defaultScore={ score }
|
||||||
recordScoreCallback={ recordModalScore }
|
recordScoreCallback={ recordModalScore }
|
||||||
onCloseModal={ () => {
|
onCloseModal={ () => {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Updating all CES events to support two questions in modal.
|
|
@ -142,11 +142,13 @@ class CustomerEffortScoreTracks {
|
||||||
* an increase of the number of rows in tags table
|
* an increase of the number of rows in tags table
|
||||||
*
|
*
|
||||||
* @param string $action Action name for the survey.
|
* @param string $action Action name for the survey.
|
||||||
* @param string $label Label for the snackbar.
|
* @param string $title Title for the snackbar.
|
||||||
|
* @param string $first_question The text for the first question.
|
||||||
|
* @param string $second_question The text for the second question.
|
||||||
*
|
*
|
||||||
* @return string Generated JavaScript to append to page.
|
* @return string Generated JavaScript to append to page.
|
||||||
*/
|
*/
|
||||||
private function get_script_track_edit_php( $action, $label ) {
|
private function get_script_track_edit_php( $action, $title, $first_question, $second_question ) {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
"(function( $ ) {
|
"(function( $ ) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -158,7 +160,7 @@ class CustomerEffortScoreTracks {
|
||||||
if ( $('.tags tbody > tr').length > initialCount ) {
|
if ( $('.tags tbody > tr').length > initialCount ) {
|
||||||
// New tag detected.
|
// New tag detected.
|
||||||
clearInterval( interval );
|
clearInterval( interval );
|
||||||
wp.data.dispatch('wc/customer-effort-score').addCesSurvey( '%s', '%s', window.pagenow, window.adminpage, '%s' );
|
wp.data.dispatch('wc/customer-effort-score').addCesSurvey({ action: '%s', title: '%s', firstQuestion: '%s', secondQuestion: '%s', onsubmitLabel: '%s' });
|
||||||
} else {
|
} else {
|
||||||
// Form is no longer loading, most likely failed.
|
// Form is no longer loading, most likely failed.
|
||||||
if ( $( '#addtag .submit .spinner.is-active' ).length < 1 ) {
|
if ( $( '#addtag .submit .spinner.is-active' ).length < 1 ) {
|
||||||
|
@ -169,7 +171,9 @@ class CustomerEffortScoreTracks {
|
||||||
});
|
});
|
||||||
})( jQuery );",
|
})( jQuery );",
|
||||||
esc_js( $action ),
|
esc_js( $action ),
|
||||||
esc_js( $label ),
|
esc_js( $title ),
|
||||||
|
esc_js( $first_question ),
|
||||||
|
esc_js( $second_question ),
|
||||||
esc_js( $this->onsubmit_label )
|
esc_js( $this->onsubmit_label )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -271,10 +275,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::SEARCH_ACTION_NAME,
|
'action' => self::SEARCH_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to use search?',
|
'How easy was it to use search?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'The search feature in WooCommerce is easy to use.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'The search\'s functionality meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => $page_now,
|
'pagenow' => $page_now,
|
||||||
'adminpage' => $admin_page,
|
'adminpage' => $admin_page,
|
||||||
|
@ -337,10 +349,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::PRODUCT_ADD_PUBLISH_ACTION_NAME,
|
'action' => self::PRODUCT_ADD_PUBLISH_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to add a product?',
|
'How easy was it to add a product?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'The product creation screen is easy to use.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'The product creation screen\'s functionality meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => 'product',
|
'pagenow' => 'product',
|
||||||
'adminpage' => 'post-php',
|
'adminpage' => 'post-php',
|
||||||
|
@ -362,10 +382,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::PRODUCT_UPDATE_ACTION_NAME,
|
'action' => self::PRODUCT_UPDATE_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to edit your product?',
|
'How easy was it to edit your product?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'The product update process is easy to complete.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'The product update process meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => 'product',
|
'pagenow' => 'product',
|
||||||
'adminpage' => 'post-php',
|
'adminpage' => 'post-php',
|
||||||
|
@ -387,10 +415,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::SHOP_ORDER_UPDATE_ACTION_NAME,
|
'action' => self::SHOP_ORDER_UPDATE_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to update an order?',
|
'How easy was it to update an order?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'The order details screen is easy to use.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'The order details screen\'s functionality meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => 'shop_order',
|
'pagenow' => 'shop_order',
|
||||||
'adminpage' => 'post-php',
|
'adminpage' => 'post-php',
|
||||||
|
@ -447,7 +483,9 @@ class CustomerEffortScoreTracks {
|
||||||
wc_enqueue_js(
|
wc_enqueue_js(
|
||||||
$this->get_script_track_edit_php(
|
$this->get_script_track_edit_php(
|
||||||
self::ADD_PRODUCT_CATEGORIES_ACTION_NAME,
|
self::ADD_PRODUCT_CATEGORIES_ACTION_NAME,
|
||||||
__( 'How easy was it to add product category?', 'woocommerce' )
|
__( 'How easy was it to add product category?', 'woocommerce' ),
|
||||||
|
__( 'The product category details screen is easy to use.', 'woocommerce' ),
|
||||||
|
__( "The product category details screen's functionality meets my needs.", 'woocommerce' )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -463,7 +501,9 @@ class CustomerEffortScoreTracks {
|
||||||
wc_enqueue_js(
|
wc_enqueue_js(
|
||||||
$this->get_script_track_edit_php(
|
$this->get_script_track_edit_php(
|
||||||
self::ADD_PRODUCT_TAGS_ACTION_NAME,
|
self::ADD_PRODUCT_TAGS_ACTION_NAME,
|
||||||
__( 'How easy was it to add a product tag?', 'woocommerce' )
|
__( 'How easy was it to add a product tag?', 'woocommerce' ),
|
||||||
|
__( 'The product tag details screen is easy to use.', 'woocommerce' ),
|
||||||
|
__( "The product tag details screen's functionality meets my needs.", 'woocommerce' )
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -484,10 +524,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::IMPORT_PRODUCTS_ACTION_NAME,
|
'action' => self::IMPORT_PRODUCTS_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to import products?',
|
'How easy was it to import products?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'The product import process is easy to complete.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'The product import process meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => 'product_page_product_importer',
|
'pagenow' => 'product_page_product_importer',
|
||||||
'adminpage' => 'product_page_product_importer',
|
'adminpage' => 'product_page_product_importer',
|
||||||
|
@ -519,10 +567,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::SETTINGS_CHANGE_ACTION_NAME,
|
'action' => self::SETTINGS_CHANGE_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to update your settings?',
|
'How easy was it to update your settings?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'The settings screen is easy to use.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'The settings screen\'s functionality meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => 'woocommerce_page_wc-settings',
|
'pagenow' => 'woocommerce_page_wc-settings',
|
||||||
'adminpage' => 'woocommerce_page_wc-settings',
|
'adminpage' => 'woocommerce_page_wc-settings',
|
||||||
|
@ -542,10 +598,18 @@ class CustomerEffortScoreTracks {
|
||||||
$this->enqueue_to_ces_tracks(
|
$this->enqueue_to_ces_tracks(
|
||||||
array(
|
array(
|
||||||
'action' => self::ADD_PRODUCT_ATTRIBUTES_ACTION_NAME,
|
'action' => self::ADD_PRODUCT_ATTRIBUTES_ACTION_NAME,
|
||||||
'label' => __(
|
'title' => __(
|
||||||
'How easy was it to add a product attribute?',
|
'How easy was it to add a product attribute?',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
),
|
),
|
||||||
|
'firstQuestion' => __(
|
||||||
|
'Product attributes are easy to use.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
|
'secondQuestion' => __(
|
||||||
|
'Product attributes\' functionality meets my needs.',
|
||||||
|
'woocommerce'
|
||||||
|
),
|
||||||
'onsubmit_label' => $this->onsubmit_label,
|
'onsubmit_label' => $this->onsubmit_label,
|
||||||
'pagenow' => 'product_page_product_attributes',
|
'pagenow' => 'product_page_product_attributes',
|
||||||
'adminpage' => 'product_page_product_attributes',
|
'adminpage' => 'product_page_product_attributes',
|
||||||
|
|
Loading…
Reference in New Issue