Skip to content

Commit 804df09

Browse files
authored
Merge pull request #53969 from callstack-internal/pac-guerreiro/fix/53683-cant-add-new-report-actions-in-debug-mode
Can't add new report actions in Debug mode
2 parents f7ce91f + b4f814f commit 804df09

File tree

8 files changed

+72
-39
lines changed

8 files changed

+72
-39
lines changed

src/libs/actions/Debug.ts

+5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ function setDebugData<TKey extends OnyxKey | `${OnyxCollectionKey}${string}`>(on
1111
Onyx.set(onyxKey, onyxValue);
1212
}
1313

14+
function mergeDebugData<TKey extends OnyxKey | `${OnyxCollectionKey}${string}`>(onyxKey: TKey, onyxValue: OnyxMergeInput<TKey>) {
15+
Onyx.merge(onyxKey, onyxValue);
16+
}
17+
1418
export default {
1519
resetDebugDetailsDraftForm,
1620
setDebugData,
21+
mergeDebugData,
1722
};

src/pages/Debug/DebugDetails.tsx

+12-12
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import useLocalize from '@hooks/useLocalize';
1515
import useThemeStyles from '@hooks/useThemeStyles';
1616
import type {ObjectType, OnyxDataType} from '@libs/DebugUtils';
1717
import DebugUtils from '@libs/DebugUtils';
18-
import * as PolicyUtils from '@libs/PolicyUtils';
19-
import * as TagsOptionsListUtils from '@libs/TagsOptionsListUtils';
2018
import Debug from '@userActions/Debug';
2119
import type CONST from '@src/CONST';
2220
import type {TranslationPaths} from '@src/languages/types';
@@ -34,6 +32,13 @@ type DebugDetailsProps = {
3432
/** The report or report action data to be displayed and editted. */
3533
data: OnyxEntry<Report> | OnyxEntry<ReportAction> | OnyxEntry<Transaction> | OnyxEntry<TransactionViolation>;
3634

35+
/** Whether the provided policy has enabled tags */
36+
policyHasEnabledTags?: boolean;
37+
38+
/** ID of the provided policy */
39+
policyID?: string;
40+
41+
/** Metadata UI */
3742
children?: React.ReactNode;
3843

3944
/** Callback to be called when user saves the debug data. */
@@ -47,13 +52,10 @@ type DebugDetailsProps = {
4752
validate: (key: any, value: string) => void;
4853
};
4954

50-
function DebugDetails({formType, data, children, onSave, onDelete, validate}: DebugDetailsProps) {
55+
function DebugDetails({formType, data, policyHasEnabledTags, policyID, children, onSave, onDelete, validate}: DebugDetailsProps) {
5156
const {translate} = useLocalize();
5257
const styles = useThemeStyles();
5358
const [formDraftData] = useOnyx(ONYXKEYS.FORMS.DEBUG_DETAILS_FORM_DRAFT);
54-
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${(data as OnyxEntry<Transaction>)?.reportID ?? ''}`);
55-
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${report?.policyID}`);
56-
const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]);
5759
const booleanFields = useMemo(
5860
() =>
5961
Object.entries(data ?? {})
@@ -66,13 +68,13 @@ function DebugDetails({formType, data, children, onSave, onDelete, validate}: De
6668
Object.entries(data ?? {})
6769
.filter((entry): entry is [string, string] => {
6870
// Tag picker needs to be hidden when the policy has no tags available to pick
69-
if (entry[0] === TRANSACTION_FORM_INPUT_IDS.TAG && !TagsOptionsListUtils.hasEnabledTags(policyTagLists)) {
71+
if (entry[0] === TRANSACTION_FORM_INPUT_IDS.TAG && !policyHasEnabledTags) {
7072
return false;
7173
}
7274
return DETAILS_CONSTANT_FIELDS[formType].some(({fieldName}) => fieldName === entry[0]);
7375
})
7476
.sort((a, b) => a[0].localeCompare(b[0])),
75-
[data, formType, policyTagLists],
77+
[data, formType, policyHasEnabledTags],
7678
);
7779
const numberFields = useMemo(
7880
() =>
@@ -209,7 +211,7 @@ function DebugDetails({formType, data, children, onSave, onDelete, validate}: De
209211
name={key}
210212
shouldSaveDraft
211213
defaultValue={String(value)}
212-
policyID={report?.policyID}
214+
policyID={policyID}
213215
/>
214216
))}
215217
{constantFields.length === 0 && <Text style={[styles.textNormalThemeText, styles.ph5]}>{translate('debug.none')}</Text>}
@@ -248,9 +250,7 @@ function DebugDetails({formType, data, children, onSave, onDelete, validate}: De
248250
danger
249251
large
250252
text={translate('common.delete')}
251-
onPress={() => {
252-
onDelete();
253-
}}
253+
onPress={onDelete}
254254
/>
255255
</View>
256256
</FormProvider>

src/pages/Debug/Report/DebugReportPage.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ function DebugReportPage({
144144
Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, data);
145145
}}
146146
onDelete={() => {
147-
Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, null);
148147
navigateToConciergeChatAndDeleteReport(reportID, true, true);
149148
}}
150149
validate={DebugUtils.validateReportDraftProperty}

src/pages/Debug/ReportAction/DebugReportActionCreatePage.tsx

+26-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useState} from 'react';
1+
import React, {useCallback, useState} from 'react';
22
import {View} from 'react-native';
33
import type {OnyxEntry} from 'react-native-onyx';
44
import {useOnyx} from 'react-native-onyx';
@@ -51,6 +51,29 @@ function DebugReportActionCreatePage({
5151
const [draftReportAction, setDraftReportAction] = useState<string>(() => getInitialReportAction(reportID, session, personalDetailsList));
5252
const [error, setError] = useState<string>();
5353

54+
const createReportAction = useCallback(() => {
55+
const parsedReportAction = JSON.parse(draftReportAction.replaceAll('\n', '')) as ReportAction;
56+
Debug.mergeDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {
57+
[parsedReportAction.reportActionID]: parsedReportAction,
58+
});
59+
Navigation.navigate(ROUTES.DEBUG_REPORT_TAB_ACTIONS.getRoute(reportID));
60+
}, [draftReportAction, reportID]);
61+
62+
const editJSON = useCallback(
63+
(updatedJSON: string) => {
64+
try {
65+
DebugUtils.validateReportActionJSON(updatedJSON);
66+
setError('');
67+
} catch (e) {
68+
const {cause, message} = e as SyntaxError;
69+
setError(cause ? translate(message as TranslationPaths, cause as never) : message);
70+
} finally {
71+
setDraftReportAction(updatedJSON);
72+
}
73+
},
74+
[translate],
75+
);
76+
5477
return (
5578
<ScreenWrapper
5679
includeSafeAreaPaddingBottom={false}
@@ -74,17 +97,7 @@ function DebugReportActionCreatePage({
7497
numberOfLines={18}
7598
multiline
7699
value={draftReportAction}
77-
onChangeText={(updatedJSON) => {
78-
try {
79-
DebugUtils.validateReportActionJSON(updatedJSON);
80-
setError('');
81-
} catch (e) {
82-
const {cause, message} = e as SyntaxError;
83-
setError(cause ? translate(message as TranslationPaths, cause as never) : message);
84-
} finally {
85-
setDraftReportAction(updatedJSON);
86-
}
87-
}}
100+
onChangeText={editJSON}
88101
textInputContainerStyles={[styles.border, styles.borderBottom, styles.p5]}
89102
/>
90103
</View>
@@ -112,11 +125,7 @@ function DebugReportActionCreatePage({
112125
success
113126
text={translate('common.save')}
114127
isDisabled={!draftReportAction || !!error}
115-
onPress={() => {
116-
const parsedReportAction = JSON.parse(draftReportAction.replaceAll('\n', '')) as ReportAction;
117-
Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {[parsedReportAction.reportActionID]: parsedReportAction});
118-
Navigation.navigate(ROUTES.DEBUG_REPORT_TAB_ACTIONS.getRoute(reportID));
119-
}}
128+
onPress={createReportAction}
120129
/>
121130
</ScrollView>
122131
</View>

src/pages/Debug/ReportAction/DebugReportActionPage.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import {View} from 'react-native';
2+
import {InteractionManager, View} from 'react-native';
33
import {useOnyx} from 'react-native-onyx';
44
import Button from '@components/Button';
55
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -61,11 +61,15 @@ function DebugReportActionPage({
6161
formType={CONST.DEBUG.FORMS.REPORT_ACTION}
6262
data={reportAction}
6363
onSave={(data) => {
64-
Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {[reportActionID]: data});
64+
Debug.mergeDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {[reportActionID]: data});
6565
}}
6666
onDelete={() => {
67-
Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {[reportActionID]: null});
6867
Navigation.goBack();
68+
// We need to wait for navigation animations to finish before deleting an action,
69+
// otherwise the user will see a not found page briefly.
70+
InteractionManager.runAfterInteractions(() => {
71+
Debug.mergeDebugData(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {[reportActionID]: null});
72+
});
6973
}}
7074
validate={DebugUtils.validateReportActionDraftProperty}
7175
>

src/pages/Debug/Transaction/DebugTransactionPage.tsx

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React from 'react';
2-
import {View} from 'react-native';
1+
import React, {useMemo} from 'react';
2+
import {InteractionManager, View} from 'react-native';
33
import {useOnyx} from 'react-native-onyx';
44
import Button from '@components/Button';
55
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -14,6 +14,8 @@ import Navigation from '@libs/Navigation/Navigation';
1414
import OnyxTabNavigator, {TopTab} from '@libs/Navigation/OnyxTabNavigator';
1515
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
1616
import type {DebugParamList} from '@libs/Navigation/types';
17+
import * as PolicyUtils from '@libs/PolicyUtils';
18+
import * as TagsOptionsListUtils from '@libs/TagsOptionsListUtils';
1719
import DebugDetails from '@pages/Debug/DebugDetails';
1820
import DebugJSON from '@pages/Debug/DebugJSON';
1921
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
@@ -32,6 +34,10 @@ function DebugTransactionPage({
3234
}: DebugTransactionPageProps) {
3335
const {translate} = useLocalize();
3436
const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`);
37+
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`);
38+
const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${report?.policyID}`);
39+
const policyTagLists = useMemo(() => PolicyUtils.getTagLists(policyTags), [policyTags]);
40+
3541
const styles = useThemeStyles();
3642

3743
if (!transaction) {
@@ -60,12 +66,18 @@ function DebugTransactionPage({
6066
<DebugDetails
6167
formType={CONST.DEBUG.FORMS.TRANSACTION}
6268
data={transaction}
69+
policyID={report?.policyID}
70+
policyHasEnabledTags={TagsOptionsListUtils.hasEnabledTags(policyTagLists)}
6371
onSave={(data) => {
6472
Debug.setDebugData(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, data);
6573
}}
6674
onDelete={() => {
67-
Debug.setDebugData(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, null);
6875
Navigation.goBack();
76+
// We need to wait for navigation animations to finish before deleting a transaction,
77+
// otherwise the user will see a not found page briefly.
78+
InteractionManager.runAfterInteractions(() => {
79+
Debug.setDebugData(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, null);
80+
});
6981
}}
7082
validate={DebugUtils.validateTransactionDraftProperty}
7183
>

src/pages/Debug/TransactionViolation/DebugTransactionViolationPage.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, {useCallback, useMemo} from 'react';
2-
import {View} from 'react-native';
2+
import {InteractionManager, View} from 'react-native';
33
import {useOnyx} from 'react-native-onyx';
44
import HeaderWithBackButton from '@components/HeaderWithBackButton';
55
import ScreenWrapper from '@components/ScreenWrapper';
@@ -45,8 +45,12 @@ function DebugTransactionViolationPage({
4545
const deleteTransactionViolation = useCallback(() => {
4646
const updatedTransactionViolations = [...(transactionViolations ?? [])];
4747
updatedTransactionViolations.splice(Number(index), 1);
48-
Debug.setDebugData(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, updatedTransactionViolations);
4948
Navigation.goBack();
49+
// We need to wait for navigation animations to finish before deleting a violation,
50+
// otherwise the user will see a not found page briefly.
51+
InteractionManager.runAfterInteractions(() => {
52+
Debug.setDebugData(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, updatedTransactionViolations);
53+
});
5054
}, [index, transactionID, transactionViolations]);
5155

5256
if (!transactionViolation) {

src/pages/home/ReportScreen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro
296296
Navigation.dismissModal();
297297
return;
298298
}
299-
Navigation.goBack(undefined, false, true);
299+
Navigation.goBack(ROUTES.HOME, false, true);
300300
}, [isInNarrowPaneModal]);
301301

302302
let headerView = (

0 commit comments

Comments
 (0)