Skip to content

Commit 38a6085

Browse files
committed
Save form state for unsubmitted data
1 parent fcbc6c6 commit 38a6085

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

packages/core/src/js/feedback/FeedbackForm.tsx

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
3333
...defaultConfiguration
3434
}
3535

36+
private static _savedState: FeedbackFormState = {
37+
isVisible: false,
38+
name: '',
39+
email: '',
40+
description: '',
41+
filename: undefined,
42+
attachment: undefined,
43+
};
44+
3645
public constructor(props: FeedbackFormProps) {
3746
super(props);
3847

@@ -45,9 +54,11 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
4554

4655
this.state = {
4756
isVisible: true,
48-
name: currentUser.useSentryUser.name,
49-
email: currentUser.useSentryUser.email,
50-
description: '',
57+
name: FeedbackForm._savedState.name || currentUser.useSentryUser.name,
58+
email: FeedbackForm._savedState.email || currentUser.useSentryUser.email,
59+
description: FeedbackForm._savedState.description || '',
60+
filename: FeedbackForm._savedState.filename || undefined,
61+
attachment: FeedbackForm._savedState.attachment || undefined,
5162
};
5263
}
5364

@@ -93,6 +104,7 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
93104
onSubmitSuccess({ name: trimmedName, email: trimmedEmail, message: trimmedDescription, attachments: undefined });
94105
Alert.alert(text.successMessageText);
95106
onFormSubmitted();
107+
this._clearFormState();
96108
} catch (error) {
97109
const errorString = `Feedback form submission failed: ${error}`;
98110
onSubmitError(new Error(errorString));
@@ -129,7 +141,7 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
129141
const imageUri = result.assets[0].uri;
130142
NATIVE.getDataFromUri(imageUri).then((data) => {
131143
if (data != null) {
132-
this.setState({ filename, attachment: data });
144+
this.setState({ filename, attachment: data }, this._saveFormState);
133145
} else {
134146
logger.error('Failed to read image data from uri:', imageUri);
135147
}
@@ -142,11 +154,11 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
142154
// Defaulting to the onAddScreenshot callback
143155
const { onAddScreenshot } = { ...defaultConfiguration, ...this.props };
144156
onAddScreenshot((filename: string, attachement: Uint8Array) => {
145-
this.setState({ filename, attachment: attachement });
157+
this.setState({ filename, attachment: attachement }, this._saveFormState);
146158
});
147159
}
148160
} else {
149-
this.setState({ filename: undefined, attachment: undefined });
161+
this.setState({ filename: undefined, attachment: undefined }, this._saveFormState);
150162
}
151163
}
152164

@@ -199,7 +211,7 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
199211
style={styles.input}
200212
placeholder={text.namePlaceholder}
201213
value={name}
202-
onChangeText={(value) => this.setState({ name: value })}
214+
onChangeText={(value) => this.setState({ name: value }, this._saveFormState)}
203215
/>
204216
</>
205217
)}
@@ -215,7 +227,7 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
215227
placeholder={text.emailPlaceholder}
216228
keyboardType={'email-address' as KeyboardTypeOptions}
217229
value={email}
218-
onChangeText={(value) => this.setState({ email: value })}
230+
onChangeText={(value) => this.setState({ email: value }, this._saveFormState)}
219231
/>
220232
</>
221233
)}
@@ -228,7 +240,7 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
228240
style={[styles.input, styles.textArea]}
229241
placeholder={text.messagePlaceholder}
230242
value={description}
231-
onChangeText={(value) => this.setState({ description: value })}
243+
onChangeText={(value) => this.setState({ description: value }, this._saveFormState)}
232244
multiline
233245
/>
234246
{(config.enableScreenshot || imagePickerConfiguration.imagePicker) && (
@@ -254,4 +266,19 @@ export class FeedbackForm extends React.Component<FeedbackFormProps, FeedbackFor
254266
</SafeAreaView>
255267
);
256268
}
269+
270+
private _saveFormState = (): void => {
271+
FeedbackForm._savedState = { ...this.state };
272+
};
273+
274+
private _clearFormState = (): void => {
275+
FeedbackForm._savedState = {
276+
isVisible: false,
277+
name: '',
278+
email: '',
279+
description: '',
280+
filename: undefined,
281+
attachment: undefined,
282+
};
283+
};
257284
}

packages/core/test/feedback/FeedbackForm.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,34 @@ describe('FeedbackForm', () => {
354354

355355
expect(mockOnFormClose).toHaveBeenCalled();
356356
});
357+
358+
it('onCancel the input is saved and restored when the form reopens', async () => {
359+
const { getByPlaceholderText, getByText } = render(<FeedbackForm {...defaultProps} />);
360+
361+
fireEvent.changeText(getByPlaceholderText(defaultProps.namePlaceholder), 'John Doe');
362+
fireEvent.changeText(getByPlaceholderText(defaultProps.emailPlaceholder), '[email protected]');
363+
fireEvent.changeText(getByPlaceholderText(defaultProps.messagePlaceholder), 'This is a feedback message.');
364+
365+
fireEvent.press(getByText(defaultProps.cancelButtonLabel));
366+
const { queryByPlaceholderText } = render(<FeedbackForm {...defaultProps} />);
367+
368+
expect(queryByPlaceholderText(defaultProps.namePlaceholder).props.value).toBe('John Doe');
369+
expect(queryByPlaceholderText(defaultProps.emailPlaceholder).props.value).toBe('[email protected]');
370+
expect(queryByPlaceholderText(defaultProps.messagePlaceholder).props.value).toBe('This is a feedback message.');
371+
});
372+
373+
it('onSubmit the saved input is cleared and not restored when the form reopens', async () => {
374+
const { getByPlaceholderText, getByText } = render(<FeedbackForm {...defaultProps} />);
375+
376+
fireEvent.changeText(getByPlaceholderText(defaultProps.namePlaceholder), 'John Doe');
377+
fireEvent.changeText(getByPlaceholderText(defaultProps.emailPlaceholder), '[email protected]');
378+
fireEvent.changeText(getByPlaceholderText(defaultProps.messagePlaceholder), 'This is a feedback message.');
379+
380+
fireEvent.press(getByText(defaultProps.submitButtonLabel));
381+
const { queryByPlaceholderText } = render(<FeedbackForm {...defaultProps} />);
382+
383+
expect(queryByPlaceholderText(defaultProps.namePlaceholder).props.value).toBe('Test User');
384+
expect(queryByPlaceholderText(defaultProps.emailPlaceholder).props.value).toBe('[email protected]');
385+
expect(queryByPlaceholderText(defaultProps.messagePlaceholder).props.value).toBe('');
386+
});
357387
});

0 commit comments

Comments
 (0)