Skip to content

Commit 74748f8

Browse files
antonislucas-zimermankrystofwoldrich
authored
Adds feedbackIntegration for configuring the feedback form (#4485)
--------- Co-authored-by: LucasZF <[email protected]> Co-authored-by: Krystof Woldrich <[email protected]>
1 parent eda1cb7 commit 74748f8

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Modal, View } from 'react-native';
55
import { FeedbackForm } from './FeedbackForm';
66
import defaultStyles from './FeedbackForm.styles';
77
import type { FeedbackFormStyles } from './FeedbackForm.types';
8+
import { getFeedbackOptions } from './integration';
89
import { isModalSupported } from './utils';
910

1011
class FeedbackFormManager {
@@ -70,7 +71,7 @@ class FeedbackFormProvider extends React.Component<FeedbackFormProviderProps> {
7071
<View>
7172
<Modal visible={isVisible} transparent animationType="slide" onRequestClose={this._handleClose} testID="feedback-form-modal">
7273
<View style={styles.modalBackground}>
73-
<FeedbackForm
74+
<FeedbackForm {...getFeedbackOptions()}
7475
onFormClose={this._handleClose}
7576
onFormSubmitted={this._handleClose}
7677
/>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { Integration } from '@sentry/core';
2+
3+
import type { FeedbackFormProps } from './FeedbackForm.types';
4+
5+
export const FEEDBACK_FORM_INTEGRATION_NAME = 'MobileFeedback';
6+
7+
type FeedbackIntegration = Integration & {
8+
options: Partial<FeedbackFormProps>;
9+
};
10+
11+
let savedOptions: Partial<FeedbackFormProps> = {};
12+
13+
export const feedbackIntegration = (initOptions: FeedbackFormProps = {}): FeedbackIntegration => {
14+
savedOptions = initOptions;
15+
16+
return {
17+
name: FEEDBACK_FORM_INTEGRATION_NAME,
18+
options: savedOptions,
19+
};
20+
};
21+
22+
export const getFeedbackOptions = (): Partial<FeedbackFormProps> => savedOptions;

packages/core/src/js/integrations/exports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export { viewHierarchyIntegration } from './viewhierarchy';
1313
export { expoContextIntegration } from './expocontext';
1414
export { spotlightIntegration } from './spotlight';
1515
export { mobileReplayIntegration } from '../replay/mobilereplay';
16+
export { feedbackIntegration } from '../feedback/integration';
1617
export { browserReplayIntegration } from '../replay/browserReplay';
1718
export { appStartIntegration } from '../tracing/integrations/appStart';
1819
export { nativeFramesIntegration, createNativeFramesIntegrations } from '../tracing/integrations/nativeFrames';

packages/core/test/feedback/FeedbackFormManager.test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { render } from '@testing-library/react-native';
33
import * as React from 'react';
44
import { Text } from 'react-native';
55

6+
import { defaultConfiguration } from '../../src/js/feedback/defaults';
67
import { FeedbackFormProvider, showFeedbackForm } from '../../src/js/feedback/FeedbackFormManager';
8+
import { feedbackIntegration } from '../../src/js/feedback/integration';
79
import { isModalSupported } from '../../src/js/feedback/utils';
810

911
jest.mock('../../src/js/feedback/utils', () => ({
@@ -53,4 +55,42 @@ describe('FeedbackFormManager', () => {
5355
showFeedbackForm();
5456
}).not.toThrow();
5557
});
58+
59+
it('showFeedbackForm displays the form with the feedbackIntegration options', () => {
60+
mockedIsModalSupported.mockReturnValue(true);
61+
const { getByPlaceholderText, getByText } = render(
62+
<FeedbackFormProvider>
63+
<Text>App Components</Text>
64+
</FeedbackFormProvider>
65+
);
66+
67+
feedbackIntegration({
68+
messagePlaceholder: 'Custom Message Placeholder',
69+
submitButtonLabel: 'Custom Submit Button',
70+
});
71+
72+
showFeedbackForm();
73+
74+
expect(getByPlaceholderText('Custom Message Placeholder')).toBeTruthy();
75+
expect(getByText('Custom Submit Button')).toBeTruthy();
76+
});
77+
78+
it('showFeedbackForm displays the form with the feedbackIntegration options merged with the defaults', () => {
79+
mockedIsModalSupported.mockReturnValue(true);
80+
const { getByPlaceholderText, getByText, queryByText } = render(
81+
<FeedbackFormProvider>
82+
<Text>App Components</Text>
83+
</FeedbackFormProvider>
84+
);
85+
86+
feedbackIntegration({
87+
submitButtonLabel: 'Custom Submit Button',
88+
}),
89+
90+
showFeedbackForm();
91+
92+
expect(queryByText(defaultConfiguration.submitButtonLabel)).toBeFalsy(); // overridden value
93+
expect(getByText('Custom Submit Button')).toBeTruthy(); // overridden value
94+
expect(getByPlaceholderText(defaultConfiguration.messagePlaceholder)).toBeTruthy(); // default configuration value
95+
});
5696
});

samples/react-native/src/App.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ Sentry.init({
106106
? false
107107
: true,
108108
}),
109+
Sentry.feedbackIntegration({
110+
styles:{
111+
submitButton: {
112+
backgroundColor: '#6a1b9a',
113+
paddingVertical: 15,
114+
borderRadius: 5,
115+
alignItems: 'center',
116+
marginBottom: 10,
117+
},
118+
},
119+
namePlaceholder: 'Fullname',
120+
}),
109121
);
110122
return integrations.filter(i => i.name !== 'Dedupe');
111123
},

0 commit comments

Comments
 (0)