Skip to content

Add new error message in selection pages #47091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 14, 2024
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
7 changes: 6 additions & 1 deletion src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,11 @@ function BaseSelectionList<TItem extends ListItem>(

useEffect(() => {
// Avoid changing focus if the textInputValue remains unchanged.
if ((prevTextInputValue === textInputValue && flattenedSections.selectedOptions.length === prevSelectedOptionsLength) || flattenedSections.allOptions.length === 0) {
if (
(prevTextInputValue === textInputValue && flattenedSections.selectedOptions.length === prevSelectedOptionsLength) ||
flattenedSections.allOptions.length === 0 ||
shouldUpdateFocusedIndex
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If shouldUpdateFocusedIndex is true, we should avoid resetting the focus index to -1 when the length of the selected options changes.

) {
return;
}
// Remove the focus if the search input is empty or selected options length is changed (and allOptions length remains the same)
Expand All @@ -559,6 +563,7 @@ function BaseSelectionList<TItem extends ListItem>(
updateAndScrollToFocusedIndex,
prevSelectedOptionsLength,
prevAllOptionsLength,
shouldUpdateFocusedIndex,
]);

useEffect(
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ export default {
enterDate: 'Enter a date.',
invalidTimeRange: 'Please enter a time using the 12-hour clock format (e.g., 2:30 PM).',
pleaseCompleteForm: 'Please complete the form above to continue.',
pleaseSelectOne: 'Please select an option above.',
},
comma: 'comma',
semicolon: 'semicolon',
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ export default {
enterDate: 'Introduce una fecha.',
invalidTimeRange: 'Por favor, introduce una hora entre 1 y 12 (por ejemplo, 2:30 PM).',
pleaseCompleteForm: 'Por favor complete el formulario de arriba para continuar.',
pleaseSelectOne: 'Seleccione una de las opciones.',
},
comma: 'la coma',
semicolon: 'el punto y coma',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import React from 'react';
import {View} from 'react-native';
import FormHelpMessage from '@components/FormHelpMessage';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';

type NetSuiteCustomListPickerProps = {
/** Selected mapping value */
value?: string;

/** Text to display on error message */
errorText?: string;

/** Callback to fire when mapping is selected */
onInputChange?: (value: string) => void;
};

function NetSuiteCustomFieldMappingPicker({value, onInputChange}: NetSuiteCustomListPickerProps) {
function NetSuiteCustomFieldMappingPicker({value, errorText, onInputChange}: NetSuiteCustomListPickerProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();

const options = [CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD];

Expand All @@ -27,14 +34,26 @@ function NetSuiteCustomFieldMappingPicker({value, onInputChange}: NetSuiteCustom
})) ?? [];

return (
<SelectionList
sections={[{data: selectionData}]}
onSelectRow={(selected) => {
onInputChange?.(selected.value);
}}
ListItem={RadioListItem}
initiallyFocusedOptionKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG}
/>
<>
<SelectionList
sections={[{data: selectionData}]}
onSelectRow={(selected) => {
onInputChange?.(selected.value);
}}
ListItem={RadioListItem}
initiallyFocusedOptionKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG}
shouldSingleExecuteRowSelect
shouldUpdateFocusedIndex
/>
{!!errorText && (
<View style={styles.ph5}>
<FormHelpMessage
isError={!!errorText}
message={errorText}
/>
</View>
)}
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ function NetSuiteImportAddCustomSegmentPage({policy}: WithPolicyConnectionsProps
}
return errors;
case CONST.NETSUITE_CUSTOM_FIELD_SUBSTEP_INDEXES.CUSTOM_SEGMENTS.MAPPING:
return ValidationUtils.getFieldRequiredErrors(values, [INPUT_IDS.MAPPING]);
if (!ValidationUtils.isRequiredFulfilled(values[INPUT_IDS.MAPPING])) {
errors[INPUT_IDS.MAPPING] = translate('common.error.pleaseSelectOne');
}
return errors;
default:
return errors;
}
Expand Down Expand Up @@ -206,6 +209,7 @@ function NetSuiteImportAddCustomSegmentPage({policy}: WithPolicyConnectionsProps
enabledWhenOffline
isSubmitDisabled={!!config?.syncOptions?.pendingFields?.customSegments}
submitFlexEnabled={submitFlexAllowed}
shouldHideFixErrorsAlert={screenIndex === CONST.NETSUITE_CUSTOM_FIELD_SUBSTEP_INDEXES.CUSTOM_SEGMENTS.MAPPING}
>
{renderSubStepContent}
</FormProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React from 'react';
import React, {useState} from 'react';
import {View} from 'react-native';
import FormHelpMessage from '@components/FormHelpMessage';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import Text from '@components/Text';
Expand All @@ -10,22 +12,33 @@ import CONST from '@src/CONST';
function ChooseSegmentTypeStep({onNext, customSegmentType, setCustomSegmentType}: CustomFieldSubStepWithPolicy) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [selectedType, setSelectedType] = useState(customSegmentType);
const [isError, setIsError] = useState(false);

const selectionData = [
{
text: translate(`workspace.netsuite.import.importCustomFields.customSegments.addForm.segmentTitle`),
keyForList: CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_SEGMENT,
isSelected: customSegmentType === CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_SEGMENT,
isSelected: selectedType === CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_SEGMENT,
value: CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_SEGMENT,
},
{
text: translate(`workspace.netsuite.import.importCustomFields.customSegments.addForm.recordTitle`),
keyForList: CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_RECORD,
isSelected: customSegmentType === CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_RECORD,
isSelected: selectedType === CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_RECORD,
value: CONST.NETSUITE_CUSTOM_RECORD_TYPES.CUSTOM_RECORD,
},
];

const onConfirm = () => {
if (!selectedType) {
setIsError(true);
} else {
setCustomSegmentType?.(selectedType);
onNext();
}
};

return (
<>
<Text style={[styles.ph5, styles.textHeadlineLineHeightXXL, styles.mb3]}>
Expand All @@ -35,12 +48,26 @@ function ChooseSegmentTypeStep({onNext, customSegmentType, setCustomSegmentType}
<SelectionList
sections={[{data: selectionData}]}
ListItem={RadioListItem}
initiallyFocusedOptionKey={customSegmentType}
initiallyFocusedOptionKey={selectedType}
onSelectRow={(selected) => {
setCustomSegmentType?.(selected.value);
onNext();
setSelectedType(selected.value);
setIsError(false);
}}
/>
shouldSingleExecuteRowSelect
shouldUpdateFocusedIndex
showConfirmButton
confirmButtonText={translate('common.next')}
onConfirm={onConfirm}
>
{isError && (
<View style={[styles.ph5, styles.mb5]}>
<FormHelpMessage
isError={isError}
message={translate('common.error.pleaseSelectOne')}
/>
</View>
)}
</SelectionList>
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ function WorkspaceEditCardLimitTypePage({route}: WorkspaceEditCardLimitTypePageP
onSelectRow={({value}) => setTypeSelected(value)}
sections={[{data}]}
shouldUpdateFocusedIndex
shouldSingleExecuteRowSelect
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this bug also occurs on this page, the root cause and solution are similar to our issue. Therefore, I will address it here as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

isAlternateTextMultilineSupported
initiallyFocusedOptionKey={typeSelected}
/>
Expand Down
Loading