From 61bb348b4831908ff0f2b9ced4ffc2ce5f920607 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Thu, 8 Aug 2024 19:16:49 +0700 Subject: [PATCH 1/3] add new error message ihn selection page --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../NetSuiteCustomFieldMappingPicker.tsx | 35 ++++++++++++----- .../NetSuiteImportAddCustomSegmentPage.tsx | 6 ++- .../substeps/ChooseSegmentTypeStep.tsx | 39 +++++++++++++++---- 5 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 72df3a16d2a7..f6811742ae0f 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -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', diff --git a/src/languages/es.ts b/src/languages/es.ts index 68ab4276d06c..5d8a2d9e7918 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -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: 'Por favor elige una opción arriba', }, comma: 'la coma', semicolon: 'el punto y coma', diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx index bf4cd65bd981..416633699d86 100644 --- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx +++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx @@ -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]; @@ -27,14 +34,24 @@ function NetSuiteCustomFieldMappingPicker({value, onInputChange}: NetSuiteCustom })) ?? []; return ( - { - onInputChange?.(selected.value); - }} - ListItem={RadioListItem} - initiallyFocusedOptionKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG} - /> + <> + { + onInputChange?.(selected.value); + }} + ListItem={RadioListItem} + initiallyFocusedOptionKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG} + /> + {!!errorText && ( + + + + )} + ); } diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteImportAddCustomSegmentPage.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteImportAddCustomSegmentPage.tsx index 5b570c4444ab..1a24a117ac85 100644 --- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteImportAddCustomSegmentPage.tsx +++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteImportAddCustomSegmentPage.tsx @@ -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; } @@ -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} diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx index 93b0ed183b18..9fd92204c31e 100644 --- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx +++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx @@ -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'; @@ -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 ( <> @@ -35,12 +48,24 @@ function ChooseSegmentTypeStep({onNext, customSegmentType, setCustomSegmentType} { - setCustomSegmentType?.(selected.value); - onNext(); + setSelectedType(selected.value); + setIsError(false); }} - /> + showConfirmButton + confirmButtonText={translate('common.next')} + onConfirm={onConfirm} + > + {isError && ( + + + + )} + ); } From 315c9cbc094d19915746654410b6511eefe01155 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Fri, 9 Aug 2024 15:34:52 +0700 Subject: [PATCH 2/3] adjust spanish text --- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index f6811742ae0f..c9a999b9ed2a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -265,7 +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', + pleaseSelectOne: 'Please select an option above.', }, comma: 'comma', semicolon: 'semicolon', diff --git a/src/languages/es.ts b/src/languages/es.ts index 5d8a2d9e7918..a39e6c3f5a73 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -255,7 +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: 'Por favor elige una opción arriba', + pleaseSelectOne: 'Seleccione una de las opciones.', }, comma: 'la coma', semicolon: 'el punto y coma', From 48a3dae58c0e966fa25367a832d72f6d887001da Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 13 Aug 2024 22:50:48 +0700 Subject: [PATCH 3/3] resolve the highlight bug --- src/components/SelectionList/BaseSelectionList.tsx | 7 ++++++- .../NetSuiteCustomFieldMappingPicker.tsx | 2 ++ .../substeps/ChooseSegmentTypeStep.tsx | 2 ++ .../expensifyCard/WorkspaceEditCardLimitTypePage.tsx | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index e78d3d43d1ec..3b9106a8baed 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -538,7 +538,11 @@ function BaseSelectionList( 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 + ) { return; } // Remove the focus if the search input is empty or selected options length is changed (and allOptions length remains the same) @@ -559,6 +563,7 @@ function BaseSelectionList( updateAndScrollToFocusedIndex, prevSelectedOptionsLength, prevAllOptionsLength, + shouldUpdateFocusedIndex, ]); useEffect( diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx index 416633699d86..b98b8b328b77 100644 --- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx +++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx @@ -42,6 +42,8 @@ function NetSuiteCustomFieldMappingPicker({value, errorText, onInputChange}: Net }} ListItem={RadioListItem} initiallyFocusedOptionKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG} + shouldSingleExecuteRowSelect + shouldUpdateFocusedIndex /> {!!errorText && ( diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx index 9fd92204c31e..a5bbb15a1756 100644 --- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx +++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/substeps/ChooseSegmentTypeStep.tsx @@ -53,6 +53,8 @@ function ChooseSegmentTypeStep({onNext, customSegmentType, setCustomSegmentType} setSelectedType(selected.value); setIsError(false); }} + shouldSingleExecuteRowSelect + shouldUpdateFocusedIndex showConfirmButton confirmButtonText={translate('common.next')} onConfirm={onConfirm} diff --git a/src/pages/workspace/expensifyCard/WorkspaceEditCardLimitTypePage.tsx b/src/pages/workspace/expensifyCard/WorkspaceEditCardLimitTypePage.tsx index 60435cef62f5..441e2e80006b 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceEditCardLimitTypePage.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceEditCardLimitTypePage.tsx @@ -118,6 +118,7 @@ function WorkspaceEditCardLimitTypePage({route}: WorkspaceEditCardLimitTypePageP onSelectRow={({value}) => setTypeSelected(value)} sections={[{data}]} shouldUpdateFocusedIndex + shouldSingleExecuteRowSelect isAlternateTextMultilineSupported initiallyFocusedOptionKey={typeSelected} />