Skip to content

Commit

Permalink
Merge pull request #47223 from mkzie2/mkzie2-issue-47005
Browse files Browse the repository at this point in the history
fix: request early cancellation form does not save draft
  • Loading branch information
stitesExpensify authored Aug 16, 2024
2 parents c7d4c5f + 1fe7806 commit 98bcc23
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 41 deletions.
6 changes: 6 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,10 @@ const ONYXKEYS = {
REIMBURSEMENT_ACCOUNT_FORM_DRAFT: 'reimbursementAccountDraft',
PERSONAL_BANK_ACCOUNT_FORM: 'personalBankAccount',
PERSONAL_BANK_ACCOUNT_FORM_DRAFT: 'personalBankAccountDraft',
DISABLE_AUTO_RENEW_SURVEY_FORM: 'disableAutoRenewSurveyForm',
DISABLE_AUTO_RENEW_SURVEY_FORM_DRAFT: 'disableAutoRenewSurveyFormDraft',
REQUEST_EARLY_CANCELLATION_FORM: 'requestEarlyCancellationForm',
REQUEST_EARLY_CANCELLATION_FORM_DRAFT: 'requestEarlyCancellationFormDraft',
EXIT_SURVEY_REASON_FORM: 'exitSurveyReasonForm',
EXIT_SURVEY_REASON_FORM_DRAFT: 'exitSurveyReasonFormDraft',
EXIT_SURVEY_RESPONSE_FORM: 'exitSurveyResponseForm',
Expand Down Expand Up @@ -647,6 +651,8 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.ROOM_SETTINGS_FORM]: FormTypes.RoomSettingsForm;
[ONYXKEYS.FORMS.NEW_TASK_FORM]: FormTypes.NewTaskForm;
[ONYXKEYS.FORMS.EDIT_TASK_FORM]: FormTypes.EditTaskForm;
[ONYXKEYS.FORMS.DISABLE_AUTO_RENEW_SURVEY_FORM]: FormTypes.FeedbackSurveyForm;
[ONYXKEYS.FORMS.REQUEST_EARLY_CANCELLATION_FORM]: FormTypes.FeedbackSurveyForm;
[ONYXKEYS.FORMS.EXIT_SURVEY_REASON_FORM]: FormTypes.ExitSurveyReasonForm;
[ONYXKEYS.FORMS.EXIT_SURVEY_RESPONSE_FORM]: FormTypes.ExitSurveyResponseForm;
[ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM]: FormTypes.MoneyRequestDescriptionForm;
Expand Down
108 changes: 67 additions & 41 deletions src/components/FeedbackSurvey.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import React, {useState} from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import * as FormActions from '@libs/actions/FormActions';
import CONST from '@src/CONST';
import type {FeedbackSurveyOptionID} from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type ONYXKEYS from '@src/ONYXKEYS';
import INPUT_IDS from '@src/types/form/FeedbackSurveyForm';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
import FixedFooter from './FixedFooter';
import FormProvider from './Form/FormProvider';
import InputWrapper from './Form/InputWrapper';
import FormAlertWithSubmitButton from './FormAlertWithSubmitButton';
import SingleOptionSelector from './SingleOptionSelector';
import RadioButtons from './RadioButtons';
import type {Choice} from './RadioButtons';
import Text from './Text';
import TextInput from './TextInput';

type FeedbackSurveyProps = {
/** A unique Onyx key identifying the form */
formID: typeof ONYXKEYS.FORMS.DISABLE_AUTO_RENEW_SURVEY_FORM | typeof ONYXKEYS.FORMS.REQUEST_EARLY_CANCELLATION_FORM;

/** Title of the survey */
title: string;

Expand All @@ -36,71 +45,88 @@ type FeedbackSurveyProps = {
isLoading?: boolean;
};

type Option = {
key: FeedbackSurveyOptionID;
label: TranslationPaths;
};

const OPTIONS: Option[] = [
{key: CONST.FEEDBACK_SURVEY_OPTIONS.TOO_LIMITED.ID, label: CONST.FEEDBACK_SURVEY_OPTIONS.TOO_LIMITED.TRANSLATION_KEY},
{key: CONST.FEEDBACK_SURVEY_OPTIONS.TOO_EXPENSIVE.ID, label: CONST.FEEDBACK_SURVEY_OPTIONS.TOO_EXPENSIVE.TRANSLATION_KEY},
{key: CONST.FEEDBACK_SURVEY_OPTIONS.INADEQUATE_SUPPORT.ID, label: CONST.FEEDBACK_SURVEY_OPTIONS.INADEQUATE_SUPPORT.TRANSLATION_KEY},
{key: CONST.FEEDBACK_SURVEY_OPTIONS.BUSINESS_CLOSING.ID, label: CONST.FEEDBACK_SURVEY_OPTIONS.BUSINESS_CLOSING.TRANSLATION_KEY},
];

function FeedbackSurvey({title, description, onSubmit, optionRowStyles, footerText, isNoteRequired, isLoading}: FeedbackSurveyProps) {
function FeedbackSurvey({title, description, onSubmit, optionRowStyles, footerText, isNoteRequired, isLoading, formID}: FeedbackSurveyProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const theme = useTheme();

const selectCircleStyles: StyleProp<ViewStyle> = {borderColor: theme.border};
const [reason, setReason] = useState<Option>();
const [note, setNote] = useState('');
const [draft, draftResults] = useOnyx(`${formID}Draft`);
const [reason, setReason] = useState<string | undefined>(draft?.reason);
const [shouldShowReasonError, setShouldShowReasonError] = useState(false);

const handleOptionSelect = (option: Option) => {
const isLoadingDraft = isLoadingOnyxValue(draftResults);

const options = useMemo<Choice[]>(
() => [
{value: CONST.FEEDBACK_SURVEY_OPTIONS.TOO_LIMITED.ID, label: translate(CONST.FEEDBACK_SURVEY_OPTIONS.TOO_LIMITED.TRANSLATION_KEY)},
{value: CONST.FEEDBACK_SURVEY_OPTIONS.TOO_EXPENSIVE.ID, label: translate(CONST.FEEDBACK_SURVEY_OPTIONS.TOO_EXPENSIVE.TRANSLATION_KEY)},
{value: CONST.FEEDBACK_SURVEY_OPTIONS.INADEQUATE_SUPPORT.ID, label: translate(CONST.FEEDBACK_SURVEY_OPTIONS.INADEQUATE_SUPPORT.TRANSLATION_KEY)},
{value: CONST.FEEDBACK_SURVEY_OPTIONS.BUSINESS_CLOSING.ID, label: translate(CONST.FEEDBACK_SURVEY_OPTIONS.BUSINESS_CLOSING.TRANSLATION_KEY)},
],
[translate],
);

useEffect(() => {
if (!draft?.reason || isLoadingDraft) {
return;
}

setReason(draft.reason);
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps -- only sync with draft data when it is loaded
}, [isLoadingDraft]);

const handleOptionSelect = (value: string) => {
setReason(value);
setShouldShowReasonError(false);
setReason(option);
};

const handleSubmit = () => {
if (!reason || (isNoteRequired && !note.trim())) {
if (!draft?.reason || (isNoteRequired && !draft.note?.trim())) {
setShouldShowReasonError(true);
return;
}

onSubmit(reason.key, note.trim());
onSubmit(draft.reason, draft.note?.trim());
FormActions.clearDraftValues(formID);
};

const handleSetNote = (text: string) => {
setNote(text);

if (isNoteRequired && shouldShowReasonError) {
setShouldShowReasonError(false);
const handleSetNote = () => {
if (!isNoteRequired || !shouldShowReasonError) {
return;
}

setShouldShowReasonError(false);
};

return (
<View style={[styles.flexGrow1, styles.justifyContentBetween]}>
<FormProvider
formID={formID}
style={[styles.flexGrow1, styles.justifyContentBetween]}
onSubmit={handleSubmit}
submitButtonText={translate('common.submit')}
isSubmitButtonVisible={false}
enabledWhenOffline
>
<View style={styles.mh5}>
<Text style={styles.textHeadline}>{title}</Text>
<Text style={[styles.mt1, styles.mb3, styles.textNormalThemeText]}>{description}</Text>
<SingleOptionSelector
options={OPTIONS}
optionRowStyles={[styles.mb7, optionRowStyles]}
selectCircleStyles={selectCircleStyles}
selectedOptionKey={reason?.key}
onSelectOption={handleOptionSelect}
<InputWrapper
InputComponent={RadioButtons}
inputID={INPUT_IDS.REASON}
items={options}
radioButtonStyle={[styles.mb7, optionRowStyles]}
onPress={handleOptionSelect}
shouldSaveDraft
/>
{!!reason && (
<>
<Text style={[styles.textNormalThemeText, styles.mb3]}>{translate('feedbackSurvey.additionalInfoTitle')}</Text>
<TextInput
<InputWrapper
InputComponent={TextInput}
inputID={INPUT_IDS.NOTE}
label={translate('feedbackSurvey.additionalInfoInputLabel')}
accessibilityLabel={translate('feedbackSurvey.additionalInfoInputLabel')}
role={CONST.ROLE.PRESENTATION}
onChangeText={handleSetNote}
value={note}
shouldSaveDraft
/>
</>
)}
Expand All @@ -117,7 +143,7 @@ function FeedbackSurvey({title, description, onSubmit, optionRowStyles, footerTe
isLoading={isLoading}
/>
</FixedFooter>
</View>
</FormProvider>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import * as Subscription from '@userActions/Subscription';
import type {FeedbackSurveyOptionID} from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

function DisableAutoRenewSurveyPage() {
const {translate} = useLocalize();
Expand All @@ -31,6 +32,7 @@ function DisableAutoRenewSurveyPage() {
/>
<ScrollView contentContainerStyle={[styles.flexGrow1, styles.pt3]}>
<FeedbackSurvey
formID={ONYXKEYS.FORMS.DISABLE_AUTO_RENEW_SURVEY_FORM}
title={translate('subscription.subscriptionSettings.helpUsImprove')}
description={translate('subscription.subscriptionSettings.whatsMainReason')}
onSubmit={handleSubmit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as Report from '@userActions/Report';
import * as Subscription from '@userActions/Subscription';
import type {CancellationType, FeedbackSurveyOptionID} from '@src/CONST';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';

function RequestEarlyCancellationPage() {
Expand Down Expand Up @@ -98,6 +99,7 @@ function RequestEarlyCancellationPage() {
const surveyContent = useMemo(
() => (
<FeedbackSurvey
formID={ONYXKEYS.FORMS.REQUEST_EARLY_CANCELLATION_FORM}
title={translate('subscription.subscriptionSettings.helpUsImprove')}
description={translate('subscription.requestEarlyCancellation.subtitle')}
onSubmit={handleSubmit}
Expand Down
19 changes: 19 additions & 0 deletions src/types/form/FeedbackSurveyForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type {ValueOf} from 'type-fest';
import type {FeedbackSurveyOptionID} from '@src/CONST';
import type Form from './Form';

const INPUT_IDS = {
REASON: 'reason',
NOTE: 'note',
} as const;

type FeedbackSurveyForm = Form<
ValueOf<typeof INPUT_IDS>,
{
[INPUT_IDS.REASON]: FeedbackSurveyOptionID;
[INPUT_IDS.NOTE]: string;
}
>;

export type {FeedbackSurveyForm};
export default INPUT_IDS;
1 change: 1 addition & 0 deletions src/types/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type {DisplayNameForm} from './DisplayNameForm';
export type {EditTaskForm} from './EditTaskForm';
export type {ExitSurveyReasonForm} from './ExitSurveyReasonForm';
export type {ExitSurveyResponseForm} from './ExitSurveyResponseForm';
export type {FeedbackSurveyForm} from './FeedbackSurveyForm';
export type {GetPhysicalCardForm} from './GetPhysicalCardForm';
export type {HomeAddressForm} from './HomeAddressForm';
export type {IKnowTeacherForm} from './IKnowTeacherForm';
Expand Down

0 comments on commit 98bcc23

Please sign in to comment.