diff --git a/src/languages/en.ts b/src/languages/en.ts index 543dfbf5e541..918f9e643be0 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -520,6 +520,7 @@ export default { replyInThread: 'Reply in thread', joinThread: 'Join thread', leaveThread: 'Leave thread', + copyOnyxData: 'Copy Onyx data', flagAsOffensive: 'Flag as offensive', menu: 'Menu', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index e7f4faab2725..dbe1fb915acc 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -512,6 +512,7 @@ export default { replyInThread: 'Responder en el hilo', joinThread: 'Unirse al hilo', leaveThread: 'Dejar hilo', + copyOnyxData: 'Copiar datos de Onyx', flagAsOffensive: 'Marcar como ofensivo', menu: 'MenĂº', }, diff --git a/src/libs/Environment/Environment.ts b/src/libs/Environment/Environment.ts index 1f5a391d3b13..c343788bed05 100644 --- a/src/libs/Environment/Environment.ts +++ b/src/libs/Environment/Environment.ts @@ -38,6 +38,13 @@ function isDevelopment(): boolean { return (Config?.ENVIRONMENT ?? CONST.ENVIRONMENT.DEV) === CONST.ENVIRONMENT.DEV; } +/** + * Are we running the app in staging? + */ +function isStaging(): boolean { + return (Config?.ENVIRONMENT ?? CONST.ENVIRONMENT.DEV) === CONST.ENVIRONMENT.STAGING; +} + /** * Are we running the app in production? */ @@ -76,4 +83,4 @@ function getSpotnanaEnvironmentTMCID(): Promise { return getEnvironment().then((environment) => SPOTNANA_ENVIRONMENT_TMC_ID[environment]); } -export {getEnvironment, isInternalTestBuild, isDevelopment, isProduction, getEnvironmentURL, getOldDotEnvironmentURL, getTravelDotEnvironmentURL, getSpotnanaEnvironmentTMCID}; +export {getEnvironment, isInternalTestBuild, isDevelopment, isStaging, isProduction, getEnvironmentURL, getOldDotEnvironmentURL, getTravelDotEnvironmentURL, getSpotnanaEnvironmentTMCID}; diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 218c382fd776..d299c9a8a414 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -22,12 +22,14 @@ import Navigation from '@libs/Navigation/Navigation'; import Parser from '@libs/Parser'; import ReportActionComposeFocusManager from '@libs/ReportActionComposeFocusManager'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import * as TaskUtils from '@libs/TaskUtils'; import * as Download from '@userActions/Download'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; +import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Beta, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; @@ -524,6 +526,20 @@ const ContextMenuActions: ContextMenuAction[] = [ }, getDescription: () => {}, }, + { + isAnonymousAction: true, + textTranslateKey: 'reportActionContextMenu.copyOnyxData', + icon: Expensicons.Copy, + successTextTranslateKey: 'reportActionContextMenu.copied', + successIcon: Expensicons.Checkmark, + shouldShow: (type) => type === CONST.CONTEXT_MENU_TYPES.REPORT && (Environment.isDevelopment() || Environment.isStaging() || Environment.isInternalTestBuild()), + onPress: (closePopover, {reportID}) => { + const report = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + Clipboard.setString(JSON.stringify(report, null, 4)); + hideContextMenu(true, ReportActionComposeFocusManager.focus); + }, + getDescription: () => {}, + }, { isAnonymousAction: false, textTranslateKey: 'reportActionContextMenu.deleteAction',