Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-13498-fixed-1782319675458.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

Marketplace Fixes: Improved texts and tooltips. Changed submit enable behavior in contact sales form ([#13498](https://github.com/linode/manager/pull/13498))
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export interface MultipeIPInputProps {
/**
* Text displayed on the button.
*/
buttonText?: string;
buttonText?: React.ReactNode;

/**
* Whether the first input field can be removed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export const MarketplaceLanding = () => {
}}
/>
<Grid container mb={3} spacing={2}>
<Grid size={{ xs: 12, sm: 12, md: 7 }}>
<Grid size={{ xs: 12, sm: 12, md: 6 }}>
<DebouncedSearchTextField
clearable
debounceTime={250}
Expand All @@ -218,16 +218,24 @@ export const MarketplaceLanding = () => {
value={searchQuery ?? ''}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 2.5 }}>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<Autocomplete
data-pendo-id="Cloud Marketplace Catalog-Category"
label="Category"
noOptionsText="No categories match your search"
onChange={(_, selected) =>
updateSearchParam('category', selected?.label)
}
options={categoryOptions}
placeholder="Category"
renderOption={renderAutocompleteOption('category')}
slotProps={{
listbox: {
sx: {
maxHeight: '50vh',
},
},
}}
textFieldProps={{
hideLabel: true,
}}
Expand All @@ -236,10 +244,11 @@ export const MarketplaceLanding = () => {
}
/>
</Grid>
<Grid size={{ xs: 12, sm: 6, md: 2.5 }}>
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
<Autocomplete
data-pendo-id="Cloud Marketplace Catalog-Type"
label="Type"
noOptionsText="No types match your search"
onChange={(_, selected) =>
updateSearchParam('type', selected?.label)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
const noOfEmails = getAllByTestId('domain-transfer-input').length;
if (noOfEmails < 2) {
const addEmailButton = getByText(
'Add a second, additional email address'
'Click to add a second, additional email address'

Check warning on line 86 in packages/manager/src/features/Marketplace/ProductDetails/ContactSalesDrawer.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":86,"column":9,"nodeType":"Literal","endLine":86,"endColumn":58}
);
expect(addEmailButton).toBeVisible();
}
Expand All @@ -94,7 +94,9 @@
<ContactSalesDrawer {...mockProps} />
);

const addEmailButton = getByText('Add a second, additional email address');
const addEmailButton = getByText(
'Click to add a second, additional email address'
);
fireEvent.click(addEmailButton);

expect(getAllByTestId('domain-transfer-input')).toHaveLength(2);
Expand All @@ -105,7 +107,9 @@
<ContactSalesDrawer {...mockProps} />
);

const addEmailButton = getByText('Add a second, additional email address');
const addEmailButton = getByText(
'Click to add a second, additional email address'
);
fireEvent.click(addEmailButton);

let additionalEmailInputs = queryAllByTestId('domain-transfer-input');
Expand Down Expand Up @@ -176,18 +180,17 @@
expect(selectedRegion).toHaveValue('United States Of America');
});

it('shows an error message if a region is not selected on form submission', async () => {
const { getByText, queryByText } = renderWithTheme(
it('shows an error message if a region is not selected on blur', async () => {
const { getByTestId, queryByText } = renderWithTheme(
<ContactSalesDrawer {...mockProps} />
);

const tc_consentCheckbox = screen
.getByTestId('tc-consent-checkbox')
.querySelector('input') as HTMLInputElement;
fireEvent.click(tc_consentCheckbox);
const regionInput = getByTestId('region-autocomplete').querySelector(

Check warning on line 188 in packages/manager/src/features/Marketplace/ProductDetails/ContactSalesDrawer.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Avoid direct Node access. Prefer using the methods from Testing Library. Raw Output: {"ruleId":"testing-library/no-node-access","severity":1,"message":"Avoid direct Node access. Prefer using the methods from Testing Library.","line":188,"column":60,"nodeType":"MemberExpression","messageId":"noNodeAccess"}

Check warning on line 188 in packages/manager/src/features/Marketplace/ProductDetails/ContactSalesDrawer.test.tsx

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Avoid direct Node access. Prefer using the methods from Testing Library. Raw Output: {"ruleId":"testing-library/no-node-access","severity":1,"message":"Avoid direct Node access. Prefer using the methods from Testing Library.","line":188,"column":60,"nodeType":"MemberExpression","messageId":"noNodeAccess"}
'input'
) as HTMLInputElement;

const submitButton = getByText('Submit');
fireEvent.click(submitButton);
fireEvent.focus(regionInput);
fireEvent.blur(regionInput);

await waitFor(() => {
expect(queryByText('Please select your region')).toBeVisible();
Expand Down Expand Up @@ -316,7 +319,8 @@

fireEvent.click(consentCheckbox);

expect(getByText('Submit')).toBeEnabled();
// Submit should still be disabled because required fields (region, phone) are not filled
expect(getByText('Submit')).toBeDisabled();
});

it('expands the terms and conditions when the "Show details" button is clicked', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
InputAdornment,
LinkButton,
Notice,
PlusSignIcon,
Stack,
TextField,
Typography,
Expand Down Expand Up @@ -124,6 +125,17 @@ export const ContactSalesDrawer = (props: ContactSalesDrawerProps) => {
});

const tcConsent = watch('tc_consent_given');
const countryCode = watch('country_code');
const phone = watch('phone');

const isSubmitDisabled =
isSubmitting ||
!tcConsent ||
!countryCode ||
!phone ||
!!errors.country_code ||
!!errors.phone ||
!!errors.phone_country_code;

const dialingCodeFilterOptions = createFilterOptions({
ignoreCase: true,
Expand All @@ -138,6 +150,7 @@ export const ContactSalesDrawer = (props: ContactSalesDrawerProps) => {
const handleFormReset = () => {
reset();
setSelectedCountry(null);
setSelectedPhoneCountry(defaultCountry);
};

const onSubmit = handleSubmit(async (values) => {
Expand Down Expand Up @@ -212,7 +225,16 @@ export const ContactSalesDrawer = (props: ContactSalesDrawerProps) => {
return (
// Using MultipleIPInput component for additional emails since it allows for easy addition and removal of multiple entries, and it can display individual error messages for each email address.
<MultipleIPInput
buttonText="Add a second, additional email address"
buttonText={
<>
<PlusSignIcon
height={12}
style={{ marginRight: 4 }}
width={12}
/>
Click to add a second, additional email address
</>
}
className={
field.value?.length === MAX_ADDITIONAL_EMAILS
? classes.hideAddEmailButton
Expand Down Expand Up @@ -265,6 +287,7 @@ export const ContactSalesDrawer = (props: ContactSalesDrawerProps) => {
}
keepSearchEnabledOnMobile
label="Region"
noOptionsText="No regions match your search"
onBlur={field.onBlur}
onChange={(_event, country) => {
setSelectedCountry(country);
Expand Down Expand Up @@ -337,6 +360,7 @@ export const ContactSalesDrawer = (props: ContactSalesDrawerProps) => {
option.label === value.label
}
label="Phone Number"
noOptionsText="No country codes match your search"
onBlur={field.onBlur}
onChange={(_, country) => {
setSelectedPhoneCountry(country);
Expand Down Expand Up @@ -625,11 +649,11 @@ export const ContactSalesDrawer = (props: ContactSalesDrawerProps) => {
primaryButtonProps={{
'data-pendo-id': 'Cloud Marketplace Contact Sales-Submit',
label: 'Submit',
disabled: isSubmitting || !tcConsent,
disabled: isSubmitDisabled,
type: 'submit',
tooltipText:
'Please agree to share your information with the partner to proceed.',
alwaysShowTooltip: !tcConsent,
'Please complete all required fields and agree to share your information with the partner to proceed',
alwaysShowTooltip: isSubmitDisabled,
}}
secondaryButtonProps={{
'data-pendo-id': 'Cloud Marketplace Contact Sales-Cancel',
Expand Down
Loading