From b7a9a4fb56e464a943fc2b82fda9d2b56a3c4422 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Thu, 24 Oct 2024 14:10:45 -0700 Subject: [PATCH 01/52] Conditionally add nvp_onboarding when not invited --- src/libs/actions/IOU.ts | 2 +- src/libs/actions/Report.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 497f43f93317..531f8176021a 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7604,7 +7604,7 @@ function completePaymentOnboarding(paymentSelected: ValueOf, full = true) { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index dce8f2d19559..45fd68df1be7 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3329,6 +3329,7 @@ function completeOnboarding( paymentSelected?: string, companySize?: OnboardingCompanySizeType, userReportedIntegration?: OnboardingAccountingType, + wasInvited = false, ) { const actorAccountID = CONST.ACCOUNT_ID.CONCIERGE; const targetChatReport = ReportUtils.getChatByParticipants([actorAccountID, currentUserAccountID]); @@ -3574,12 +3575,14 @@ function completeOnboarding( key: ONYXKEYS.NVP_INTRO_SELECTED, value: {choice: engagementChoice}, }, - { + ); + if (!wasInvited) { + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ONBOARDING, value: {hasCompletedGuidedSetupFlow: true}, - }, - ); + }); + } const successData: OnyxUpdate[] = [...tasksForSuccessData]; successData.push({ From 45e8f104b299128b7a565da3fbb6bff70a81fb9c Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Thu, 24 Oct 2024 16:15:57 -0700 Subject: [PATCH 02/52] Add undefined params to get pamentSeleted in right place; wasinvited too --- src/libs/actions/IOU.ts | 13 ++++++++++++- src/libs/actions/Report.ts | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 531f8176021a..7d0281a43b21 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7604,7 +7604,18 @@ function completePaymentOnboarding(paymentSelected: ValueOf, full = true) { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 45fd68df1be7..6e5ecf7f53a6 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3329,7 +3329,7 @@ function completeOnboarding( paymentSelected?: string, companySize?: OnboardingCompanySizeType, userReportedIntegration?: OnboardingAccountingType, - wasInvited = false, + wasInvited?: boolean, ) { const actorAccountID = CONST.ACCOUNT_ID.CONCIERGE; const targetChatReport = ReportUtils.getChatByParticipants([actorAccountID, currentUserAccountID]); From 9935cc3d8449f8a71c80522eff09a0defceedcd7 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Thu, 24 Oct 2024 16:27:47 -0700 Subject: [PATCH 03/52] Apply same reasoning to failure data --- src/libs/actions/Report.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 6e5ecf7f53a6..84b438d4a2fa 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3637,6 +3637,9 @@ function completeOnboarding( key: ONYXKEYS.NVP_INTRO_SELECTED, value: {choice: null}, }, + ); + + if (!wasInvited) failureData.push( { onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ONBOARDING, From 38d75c4255ff953f1188061704251bf18fe69749 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Thu, 24 Oct 2024 17:17:21 -0700 Subject: [PATCH 04/52] Fix bad syntax --- src/libs/actions/Report.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 84b438d4a2fa..91eec9df1d77 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3639,13 +3639,13 @@ function completeOnboarding( }, ); - if (!wasInvited) failureData.push( - { + if (!wasInvited) { + failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ONBOARDING, value: {hasCompletedGuidedSetupFlow: false}, - }, - ); + }); + } if (userReportedIntegration) { optimisticData.push({ From 0abb380ce52148fba4eea4d2a64f2a3b0e6e0c61 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 29 Oct 2024 10:51:25 +0700 Subject: [PATCH 05/52] fix: Deleted room is displayed in the 'Assign task' --- .../SidebarScreen/FloatingActionButtonAndPopover.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index a49b474b185e..329066b00a99 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -189,9 +189,10 @@ function FloatingActionButtonAndPopover( const {canUseSpotnanaTravel, canUseCombinedTrackSubmit} = usePermissions(); const canSendInvoice = useMemo(() => PolicyUtils.canSendInvoice(allPolicies as OnyxCollection, session?.email), [allPolicies, session?.email]); + const isValidReport = !(isEmptyObject(quickActionReport) || ReportUtils.isArchivedRoom(quickActionReport, reportNameValuePairs)); const quickActionAvatars = useMemo(() => { - if (quickActionReport) { + if (isValidReport) { const avatars = ReportUtils.getIcons(quickActionReport, personalDetails); return avatars.length <= 1 || ReportUtils.isPolicyExpenseChat(quickActionReport) ? avatars : avatars.filter((avatar) => avatar.id !== session?.accountID); } @@ -223,7 +224,7 @@ function FloatingActionButtonAndPopover( }, [quickAction, translate, quickActionAvatars, quickActionReport]); const hideQABSubtitle = useMemo(() => { - if (isEmptyObject(quickActionReport)) { + if (isValidReport) { return true; } if (quickActionAvatars.length === 0) { @@ -231,7 +232,7 @@ function FloatingActionButtonAndPopover( } const displayName = personalDetails?.[quickActionAvatars.at(0)?.id ?? -1]?.firstName ?? ''; return quickAction?.action === CONST.QUICK_ACTIONS.SEND_MONEY && displayName.length === 0; - }, [personalDetails, quickActionReport, quickAction?.action, quickActionAvatars]); + }, [isValidReport, quickActionAvatars, personalDetails, quickAction?.action]); const navigateToQuickAction = () => { const selectOption = (onSelected: () => void, shouldRestrictAction: boolean) => { @@ -243,7 +244,6 @@ function FloatingActionButtonAndPopover( onSelected(); }; - const isValidReport = !(isEmptyObject(quickActionReport) || ReportUtils.isArchivedRoom(quickActionReport, reportNameValuePairs)); const quickActionReportID = isValidReport ? quickActionReport?.reportID ?? '-1' : ReportUtils.generateReportID(); switch (quickAction?.action) { From 5889c08cc90ef34eb83e6d42b7922db32e4785e4 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 29 Oct 2024 17:29:05 +0700 Subject: [PATCH 06/52] fix eslint --- .../FloatingActionButtonAndPopover.tsx | 86 ++++--------------- 1 file changed, 15 insertions(+), 71 deletions(-) diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index 329066b00a99..b8b76e5a00eb 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -1,10 +1,10 @@ import {useIsFocused as useIsFocusedOriginal, useNavigationState} from '@react-navigation/native'; import type {ImageContentFit} from 'expo-image'; -import type {ForwardedRef, RefAttributes} from 'react'; +import type {ForwardedRef} from 'react'; import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import {useOnyx, withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import type {SvgProps} from 'react-native-svg'; import FloatingActionButton from '@components/FloatingActionButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -39,6 +39,7 @@ import SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type {QuickActionName} from '@src/types/onyx/QuickAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import mapOnyxCollectionItems from '@src/utils/mapOnyxCollectionItems'; // On small screen we hide the search page from central pane to show the search bottom tab page with bottom tab bar. // We need to take this in consideration when checking if the screen is focused. @@ -51,33 +52,7 @@ const useIsFocused = () => { type PolicySelector = Pick; -type FloatingActionButtonAndPopoverOnyxProps = { - /** The list of policies the user has access to. */ - allPolicies: OnyxCollection; - - /** Whether app is in loading state */ - isLoading: OnyxEntry; - - /** Information on the last taken action to display as Quick Action */ - quickAction: OnyxEntry; - - /** The report data of the quick action */ - quickActionReport: OnyxEntry; - - /** The policy data of the quick action */ - quickActionPolicy: OnyxEntry; - - /** The current session */ - session: OnyxEntry; - - /** Personal details of all the users */ - personalDetails: OnyxEntry; - - /** Has user seen track expense training interstitial */ - hasSeenTrackTraining: OnyxEntry; -}; - -type FloatingActionButtonAndPopoverProps = FloatingActionButtonAndPopoverOnyxProps & { +type FloatingActionButtonAndPopoverProps = { /* Callback function when the menu is shown */ onShowCreateMenu?: () => void; @@ -161,23 +136,18 @@ const getQuickActionTitle = (action: QuickActionName): TranslationPaths => { * Responsible for rendering the {@link PopoverMenu}, and the accompanying * FAB that can open or close the menu. */ -function FloatingActionButtonAndPopover( - { - onHideCreateMenu, - onShowCreateMenu, - isLoading = false, - allPolicies, - quickAction, - quickActionReport, - quickActionPolicy, - session, - personalDetails, - hasSeenTrackTraining, - }: FloatingActionButtonAndPopoverProps, - ref: ForwardedRef, -) { +function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: FloatingActionButtonAndPopoverProps, ref: ForwardedRef) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: (c) => mapOnyxCollectionItems(c, policySelector)}); + const [isLoading] = useOnyx(ONYXKEYS.IS_LOADING_APP); + const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE); + const [quickActionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${quickAction?.chatReportID}`); + const [quickActionPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${quickActionReport?.policyID}`); + const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); + const [session] = useOnyx(ONYXKEYS.SESSION); + const [hasSeenTrackTraining] = useOnyx(ONYXKEYS.NVP_HAS_SEEN_TRACK_TRAINING); + const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${quickActionReport?.reportID ?? -1}`); const [isCreateMenuActive, setIsCreateMenuActive] = useState(false); const fabRef = useRef(null); @@ -510,32 +480,6 @@ function FloatingActionButtonAndPopover( FloatingActionButtonAndPopover.displayName = 'FloatingActionButtonAndPopover'; -export default withOnyx, FloatingActionButtonAndPopoverOnyxProps>({ - allPolicies: { - key: ONYXKEYS.COLLECTION.POLICY, - selector: policySelector, - }, - isLoading: { - key: ONYXKEYS.IS_LOADING_APP, - }, - quickAction: { - key: ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, - }, - quickActionReport: { - key: ({quickAction}) => `${ONYXKEYS.COLLECTION.REPORT}${quickAction?.chatReportID}`, - }, - quickActionPolicy: { - key: ({quickActionReport}) => `${ONYXKEYS.COLLECTION.POLICY}${quickActionReport?.policyID}`, - }, - personalDetails: { - key: ONYXKEYS.PERSONAL_DETAILS_LIST, - }, - session: { - key: ONYXKEYS.SESSION, - }, - hasSeenTrackTraining: { - key: ONYXKEYS.NVP_HAS_SEEN_TRACK_TRAINING, - }, -})(forwardRef(FloatingActionButtonAndPopover)); +export default forwardRef(FloatingActionButtonAndPopover); export type {PolicySelector}; From 8206ad0092a999dfd633f5874ec073d042059380 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 30 Oct 2024 17:35:14 +0700 Subject: [PATCH 07/52] fix: sound plays before paying held expense report --- src/components/ProcessMoneyReportHoldMenu.tsx | 2 ++ src/components/SettlementButton/index.tsx | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/ProcessMoneyReportHoldMenu.tsx b/src/components/ProcessMoneyReportHoldMenu.tsx index 3d6ad9006dc5..f1a72cc7fb8e 100644 --- a/src/components/ProcessMoneyReportHoldMenu.tsx +++ b/src/components/ProcessMoneyReportHoldMenu.tsx @@ -4,6 +4,7 @@ import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import Navigation from '@libs/Navigation/Navigation'; import {isLinkedTransactionHeld} from '@libs/ReportActionsUtils'; +import playSound, {SOUNDS} from '@libs/Sound'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -74,6 +75,7 @@ function ProcessMoneyReportHoldMenu({ if (startAnimation) { startAnimation(); } + playSound(SOUNDS.SUCCESS); IOU.payMoneyRequest(paymentType, chatReport, moneyRequestReport, full); } onClose(); diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index 53b09bfcbf31..f98415a5f11a 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -208,7 +208,9 @@ function SettlementButton({ return; } - playSound(SOUNDS.SUCCESS); + if (!ReportUtils.hasHeldExpenses(iouReport?.reportID)) { + playSound(SOUNDS.SUCCESS); + } onPress(iouPaymentType); }; From 83a70f9ab7c2d40e003be64f86118a92e1302cc5 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 1 Nov 2024 15:07:55 +0700 Subject: [PATCH 08/52] fix show QAB subtitle --- .../sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index b8b76e5a00eb..c58b725a6b49 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -194,7 +194,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl }, [quickAction, translate, quickActionAvatars, quickActionReport]); const hideQABSubtitle = useMemo(() => { - if (isValidReport) { + if (!isValidReport) { return true; } if (quickActionAvatars.length === 0) { From 936b5bd45d821e34eecbf852f9627c1cef0f7d45 Mon Sep 17 00:00:00 2001 From: jaydamani Date: Sat, 2 Nov 2024 13:23:30 +0100 Subject: [PATCH 09/52] feature(onboarding): combine category and tag setup task for connections --- src/CONST.ts | 9 +++++++++ src/libs/actions/Report.ts | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index 437ee4e7fd42..b79c831264eb 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4891,6 +4891,15 @@ const CONST = { '\n' + `Chat with the specialist in your [#admins room](${adminsRoomLink}).`, }, + { + type: 'addAccountingIntegration', + autoCompleted: false, + title: 'Set up categories and tags', + description: ({workspaceCategoriesLink, workspaceAccountingLink}) => + '*Set up categories and tags* so your team can code expenses for easy reporting.\n' + + '\n' + + `Import them automatically by [connecting your accounting software](${workspaceAccountingLink}), or set them up manually in your [workspace settings](${workspaceCategoriesLink}).`, + }, { type: 'setupCategories', autoCompleted: false, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 3eac21cd1b18..0333577fff8d 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3439,7 +3439,11 @@ function completeOnboarding( const tasksData = data.tasks .filter((task) => { - if (task.type === 'addAccountingIntegration' && !userReportedIntegration) { + if (['setupCategories', 'setupTags'].includes(task.type) && userReportedIntegration) { + return false; + } + + if (['addAccountingIntegration', 'setupCategoriesAndTags'].includes(task.type) && !userReportedIntegration) { return false; } return true; From 3c8de6dbc3ff0c764b6d4973d664ea7c386c0f16 Mon Sep 17 00:00:00 2001 From: jaydamani Date: Sat, 2 Nov 2024 13:32:05 +0100 Subject: [PATCH 10/52] update task type --- src/CONST.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index b79c831264eb..1ce3b14acc53 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4892,7 +4892,7 @@ const CONST = { `Chat with the specialist in your [#admins room](${adminsRoomLink}).`, }, { - type: 'addAccountingIntegration', + type: 'setupCategoriesAndTags', autoCompleted: false, title: 'Set up categories and tags', description: ({workspaceCategoriesLink, workspaceAccountingLink}) => From 766e05bca88f1fa039404b0e0d6b92cce7452560 Mon Sep 17 00:00:00 2001 From: jaydamani Date: Tue, 5 Nov 2024 19:55:41 +0100 Subject: [PATCH 11/52] update link in setupCategoriesAndTags --- src/CONST.ts | 5 +++-- src/libs/actions/Report.ts | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 1ce3b14acc53..97b8ac45acc7 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -264,6 +264,7 @@ type OnboardingTaskType = { workspaceMembersLink: string; integrationName: string; workspaceAccountingLink: string; + workspaceSettingsLink: string; }>, ) => string); }; @@ -4895,10 +4896,10 @@ const CONST = { type: 'setupCategoriesAndTags', autoCompleted: false, title: 'Set up categories and tags', - description: ({workspaceCategoriesLink, workspaceAccountingLink}) => + description: ({workspaceSettingsLink, workspaceAccountingLink}) => '*Set up categories and tags* so your team can code expenses for easy reporting.\n' + '\n' + - `Import them automatically by [connecting your accounting software](${workspaceAccountingLink}), or set them up manually in your [workspace settings](${workspaceCategoriesLink}).`, + `Import them automatically by [connecting your accounting software](${workspaceAccountingLink}), or set them up manually in your [workspace settings](${workspaceSettingsLink}).`, }, { type: 'setupCategories', diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 0333577fff8d..b560dc244d89 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3458,6 +3458,7 @@ function completeOnboarding( workspaceMoreFeaturesLink: `${environmentURL}/${ROUTES.WORKSPACE_MORE_FEATURES.getRoute(onboardingPolicyID ?? '-1')}`, integrationName, workspaceAccountingLink: `${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(onboardingPolicyID ?? '-1')}`, + workspaceSettingsLink: `${environmentURL}/${ROUTES.WORKSPACE_INITIAL.getRoute(onboardingPolicyID ?? '01')}`, }) : task.description; const taskTitle = From 7888a0d87cc23b53bb95621125322709ab438940 Mon Sep 17 00:00:00 2001 From: daledah Date: Thu, 7 Nov 2024 14:38:09 +0700 Subject: [PATCH 12/52] fix: Not found page appear briefly after updating the first approver --- .../approvals/WorkspaceWorkflowsApprovalsEditPage.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsEditPage.tsx b/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsEditPage.tsx index d67dd564057c..b4f1164c8102 100644 --- a/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsEditPage.tsx +++ b/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsEditPage.tsx @@ -50,8 +50,10 @@ function WorkspaceWorkflowsApprovalsEditPage({policy, isLoadingReportData = true // We need to remove members and approvers that are no longer in the updated workflow const membersToRemove = initialApprovalWorkflow.members.filter((initialMember) => !approvalWorkflow.members.some((member) => member.email === initialMember.email)); const approversToRemove = initialApprovalWorkflow.approvers.filter((initialApprover) => !approvalWorkflow.approvers.some((approver) => approver.email === initialApprover.email)); - Workflow.updateApprovalWorkflow(route.params.policyID, approvalWorkflow, membersToRemove, approversToRemove); Navigation.dismissModal(); + InteractionManager.runAfterInteractions(() => { + Workflow.updateApprovalWorkflow(route.params.policyID, approvalWorkflow, membersToRemove, approversToRemove); + }); }, [approvalWorkflow, initialApprovalWorkflow, route.params.policyID]); const removeApprovalWorkflow = useCallback(() => { From 69f180617e63b1435f984e029ef18a8b4dcc99c1 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 7 Nov 2024 16:24:34 +0700 Subject: [PATCH 13/52] fix lint --- .../sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index c025d668e9a6..fc63f83f09bc 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -453,7 +453,6 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl onSelected: () => interceptAnonymousUser(() => { selectOption(() => { - const isValidReport = !(isEmptyObject(policyChatForActivePolicy) || ReportUtils.isArchivedRoom(policyChatForActivePolicy, reportNameValuePairs)); const quickActionReportID = isValidReport ? policyChatForActivePolicy?.reportID ?? '-1' : ReportUtils.generateReportID(); IOU.startMoneyRequest(CONST.IOU.TYPE.SUBMIT, quickActionReportID ?? '-1', CONST.IOU.REQUEST_TYPE.SCAN, true); }, true); @@ -473,14 +472,14 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl styles.quickActionTooltipWrapper, renderQuickActionTooltip, quickAction?.action, - quickAction?.isFirstQuickAction, + quickAction.isFirstQuickAction, policyChatForActivePolicy, quickActionTitle, hideQABSubtitle, quickActionReport, navigateToQuickAction, selectOption, - reportNameValuePairs, + isValidReport, ]); return ( From 4ea4fcdfa95eb998dcd706010c36f6ea09f2a1ac Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 8 Nov 2024 11:16:02 +0700 Subject: [PATCH 14/52] fix lint --- .../sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index fc63f83f09bc..90b535729f01 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -281,7 +281,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl break; default: } - }, [quickAction, quickActionReport, reportNameValuePairs, selectOption]); + }, [isValidReport, quickAction?.action, quickAction?.targetAccountID, quickActionReport?.reportID, selectOption]); /** * Check if LHN status changed from active to inactive. @@ -472,7 +472,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl styles.quickActionTooltipWrapper, renderQuickActionTooltip, quickAction?.action, - quickAction.isFirstQuickAction, + quickAction?.isFirstQuickAction, policyChatForActivePolicy, quickActionTitle, hideQABSubtitle, From 34325c28fae8608deeb7e0b37d9bb2d7a5233487 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Tue, 12 Nov 2024 14:14:36 +0800 Subject: [PATCH 15/52] make the playback options scrollable --- src/components/VideoPopoverMenu/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/VideoPopoverMenu/index.tsx b/src/components/VideoPopoverMenu/index.tsx index 23f3447cf495..f4f3092df109 100644 --- a/src/components/VideoPopoverMenu/index.tsx +++ b/src/components/VideoPopoverMenu/index.tsx @@ -35,6 +35,7 @@ function VideoPopoverMenu({ anchorPosition={anchorPosition} menuItems={menuItems} anchorRef={videoPlayerMenuRef} + shouldUseScrollView /> ); } From bbbcce993591d78badf4e19f327054edee20f128 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 12 Nov 2024 16:33:10 +0700 Subject: [PATCH 16/52] fix: add test for QAB --- src/libs/ReportUtils.ts | 25 +++++++++++++++++++++++++ tests/unit/ReportUtilsTest.ts | 16 ++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a104b98175c4..c543e33c795e 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -7949,6 +7949,30 @@ function getOptimisticDataForParentReportAction(reportID: string, lastVisibleAct }); } +function getQuickActionDetails( + quickActionReport: Report, + personalDetails: PersonalDetailsList | undefined, + policyChatForActivePolicy: Report | undefined, + reportNameValuePairs: ReportNameValuePairs, +): {quickActionAvatars: Icon[]; hideQABSubtitle: boolean} { + const isValidQuickActionReport = !(isEmptyObject(quickActionReport) || isArchivedRoom(quickActionReport, reportNameValuePairs)); + let hideQABSubtitle = false; + let quickActionAvatars: Icon[] = []; + if (isValidQuickActionReport) { + const avatars = getIcons(quickActionReport, personalDetails); + quickActionAvatars = avatars.length <= 1 || isPolicyExpenseChat(quickActionReport) ? avatars : avatars.filter((avatar) => avatar.id !== currentUserAccountID); + } else { + hideQABSubtitle = true; + } + if (!isEmptyObject(policyChatForActivePolicy)) { + quickActionAvatars = getIcons(policyChatForActivePolicy, personalDetails); + } + return { + quickActionAvatars, + hideQABSubtitle, + }; +} + function canBeAutoReimbursed(report: OnyxInputOrEntry, policy: OnyxInputOrEntry): boolean { if (isEmptyObject(policy)) { return false; @@ -8565,6 +8589,7 @@ export { getInvoicePayerName, getInvoicesChatName, getPayeeName, + getQuickActionDetails, hasActionsWithErrors, hasAutomatedExpensifyAccountIDs, hasExpensifyGuidesEmails, diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 81101b74f4d7..53acb0ae81a4 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -975,6 +975,22 @@ describe('ReportUtils', () => { }); }); + describe('getQuickActionDetails', () => { + it('if the report is archived, the quick action will hide the subtitle and avatar', () => { + const archivedReport: Report = { + reportID: '1', + private_isArchived: DateUtils.getDBTime(), + }; + const reportNameValuePairs = { + type: 'chat', + private_isArchived: true, + }; + const quickActionDetails = ReportUtils.getQuickActionDetails(archivedReport, undefined, undefined, reportNameValuePairs); + expect(quickActionDetails.quickActionAvatars.length).toEqual(0); + expect(quickActionDetails.hideQABSubtitle).toEqual(true); + }); + }); + describe('getChatByParticipants', () => { const userAccountID = 1; const userAccountID2 = 2; From 5c5dcf22e4ad3d639bfe95404b672e76b5a6c5b9 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Tue, 12 Nov 2024 22:44:10 +0700 Subject: [PATCH 17/52] display not found page for invalid magic code --- src/components/ValidateCode/ValidateCodeModal.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/ValidateCode/ValidateCodeModal.tsx b/src/components/ValidateCode/ValidateCodeModal.tsx index 1e42773c2dc2..6ff8d6c0d05d 100644 --- a/src/components/ValidateCode/ValidateCodeModal.tsx +++ b/src/components/ValidateCode/ValidateCodeModal.tsx @@ -10,6 +10,9 @@ import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; +import * as ValidationUtils from '@libs/ValidationUtils'; +import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -33,6 +36,18 @@ function ValidateCodeModal({code, accountID, session = {}}: ValidateCodeModalPro const signInHere = useCallback(() => Session.signInWithValidateCode(accountID, code), [accountID, code]); const {translate} = useLocalize(); + const isInvalidValidateCode = !ValidationUtils.isValidValidateCode(code); + + if (isInvalidValidateCode) { + return ( + { + Navigation.goBack(); + }} + /> + ); + } return ( From b29da7baeaa97bd8e0c445d5d584262054e070e4 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 13 Nov 2024 23:15:25 +0700 Subject: [PATCH 18/52] remove withOnyx --- .../ValidateCode/ValidateCodeModal.tsx | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/components/ValidateCode/ValidateCodeModal.tsx b/src/components/ValidateCode/ValidateCodeModal.tsx index 6ff8d6c0d05d..3216a443d183 100644 --- a/src/components/ValidateCode/ValidateCodeModal.tsx +++ b/src/components/ValidateCode/ValidateCodeModal.tsx @@ -1,7 +1,6 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import * as Illustrations from '@components/Icon/Illustrations'; @@ -16,23 +15,18 @@ import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Session as SessionType} from '@src/types/onyx'; -type ValidateCodeModalOnyxProps = { - /** Session of currently logged in user */ - session: OnyxEntry; -}; - -type ValidateCodeModalProps = ValidateCodeModalOnyxProps & { +type ValidateCodeModalProps = { /** Code to display. */ code: string; /** The ID of the account to which the code belongs. */ accountID: number; }; -function ValidateCodeModal({code, accountID, session = {}}: ValidateCodeModalProps) { +function ValidateCodeModal({code, accountID}: ValidateCodeModalProps) { const theme = useTheme(); const styles = useThemeStyles(); + const [session] = useOnyx(ONYXKEYS.SESSION); const signInHere = useCallback(() => Session.signInWithValidateCode(accountID, code), [accountID, code]); const {translate} = useLocalize(); @@ -88,6 +82,4 @@ function ValidateCodeModal({code, accountID, session = {}}: ValidateCodeModalPro ValidateCodeModal.displayName = 'ValidateCodeModal'; -export default withOnyx({ - session: {key: ONYXKEYS.SESSION}, -})(ValidateCodeModal); +export default ValidateCodeModal; From 635ffc58bab75a4fa74c9260fcc72aab2f3fcd6a Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Wed, 13 Nov 2024 11:23:05 -0800 Subject: [PATCH 19/52] Resolve bad merge conflict --- src/libs/actions/Report.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 63c5959a22ee..7bae11fe06e9 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3896,6 +3896,7 @@ function completeOnboarding( paymentSelected?: string, companySize?: OnboardingCompanySize, userReportedIntegration?: OnboardingAccounting, + wasInvited?: boolean, ) { const {optimisticData, successData, failureData, guidedSetupData, actorAccountID} = prepareOnboardingOptimisticData( engagementChoice, @@ -3903,6 +3904,7 @@ function completeOnboarding( adminsChatReportID, onboardingPolicyID, userReportedIntegration, + wasInvited, ); const parameters: CompleteGuidedSetupParams = { From d3c1b997b0f5f0c32aca3d1ac27fb0e5c2eacaa2 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 14 Nov 2024 15:23:56 +0700 Subject: [PATCH 20/52] add comment context --- tests/unit/ReportUtilsTest.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 53acb0ae81a4..2af8a0777c74 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -977,7 +977,9 @@ describe('ReportUtils', () => { describe('getQuickActionDetails', () => { it('if the report is archived, the quick action will hide the subtitle and avatar', () => { + // Create a fake archived report as quick action report const archivedReport: Report = { + ...LHNTestUtils.getFakeReport(), reportID: '1', private_isArchived: DateUtils.getDBTime(), }; @@ -985,7 +987,11 @@ describe('ReportUtils', () => { type: 'chat', private_isArchived: true, }; + + // Get the quick action detail const quickActionDetails = ReportUtils.getQuickActionDetails(archivedReport, undefined, undefined, reportNameValuePairs); + + // Expect the quickActionAvatars is empty array and hideQABSubtitle is true since the quick action report is archived expect(quickActionDetails.quickActionAvatars.length).toEqual(0); expect(quickActionDetails.hideQABSubtitle).toEqual(true); }); From 784ec89870652c155f494049844243b228056eb9 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 14 Nov 2024 16:00:04 +0700 Subject: [PATCH 21/52] fix test --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 6b26e12f59ae..06fa92649a7c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -7963,7 +7963,7 @@ function getQuickActionDetails( } return { quickActionAvatars, - hideQABSubtitle, + hideQABSubtitle, }; } From 76ce7c858be35140db04b5fc59d564bf5d63d744 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 14 Nov 2024 16:00:16 +0700 Subject: [PATCH 22/52] fix lint --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 06fa92649a7c..6b26e12f59ae 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -7963,7 +7963,7 @@ function getQuickActionDetails( } return { quickActionAvatars, - hideQABSubtitle, + hideQABSubtitle, }; } From d03d4b4fdf5955fc60430bff715e7faa41bef3f5 Mon Sep 17 00:00:00 2001 From: daledah Date: Thu, 14 Nov 2024 17:58:58 +0700 Subject: [PATCH 23/52] fix: approver field flickering --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index b9948466bef9..77aaee13fb9e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,7 +1,7 @@ import {useFocusEffect} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useMemo, useState} from 'react'; -import {ActivityIndicator, View} from 'react-native'; +import {ActivityIndicator, InteractionManager, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import ApprovalWorkflowSection from '@components/ApprovalWorkflowSection'; import ConfirmModal from '@components/ConfirmModal'; @@ -92,7 +92,9 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { useFocusEffect( useCallback(() => { - fetchData(); + InteractionManager.runAfterInteractions(() => { + fetchData(); + }); }, [fetchData]), ); From 022cbdf7294bc5a337c27faf3eb19a72682335ba Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Thu, 14 Nov 2024 23:55:57 +0700 Subject: [PATCH 24/52] use FullPageNotFoundView --- .../ValidateCode/ValidateCodeModal.tsx | 81 +++++++++---------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/src/components/ValidateCode/ValidateCodeModal.tsx b/src/components/ValidateCode/ValidateCodeModal.tsx index 3216a443d183..06b09b7e82ac 100644 --- a/src/components/ValidateCode/ValidateCodeModal.tsx +++ b/src/components/ValidateCode/ValidateCodeModal.tsx @@ -1,6 +1,7 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; +import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import * as Illustrations from '@components/Icon/Illustrations'; @@ -11,7 +12,6 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as ValidationUtils from '@libs/ValidationUtils'; -import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import variables from '@styles/variables'; import * as Session from '@userActions/Session'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -30,53 +30,48 @@ function ValidateCodeModal({code, accountID}: ValidateCodeModalProps) { const signInHere = useCallback(() => Session.signInWithValidateCode(accountID, code), [accountID, code]); const {translate} = useLocalize(); - const isInvalidValidateCode = !ValidationUtils.isValidValidateCode(code); - - if (isInvalidValidateCode) { - return ( - { - Navigation.goBack(); - }} - /> - ); - } return ( - - - + { + Navigation.goBack(); + }} + > + + + + + + {translate('validateCodeModal.title')} + + + {translate('validateCodeModal.description')} + {!session?.authToken && ( + <> + {translate('validateCodeModal.or')} {translate('validateCodeModal.signInHere')} + + )} + . + + + + {code} + + + - {translate('validateCodeModal.title')} - - - {translate('validateCodeModal.description')} - {!session?.authToken && ( - <> - {translate('validateCodeModal.or')} {translate('validateCodeModal.signInHere')} - - )} - . - - - - {code} - - - - - + ); } From 5ab201167b92b493cecf2129a123e8e7818fc4e3 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Fri, 15 Nov 2024 12:07:34 +0700 Subject: [PATCH 25/52] hide back button in wide screen --- src/components/ValidateCode/ValidateCodeModal.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/ValidateCode/ValidateCodeModal.tsx b/src/components/ValidateCode/ValidateCodeModal.tsx index 06b09b7e82ac..089416267b32 100644 --- a/src/components/ValidateCode/ValidateCodeModal.tsx +++ b/src/components/ValidateCode/ValidateCodeModal.tsx @@ -8,6 +8,7 @@ import * as Illustrations from '@components/Icon/Illustrations'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; @@ -29,10 +30,12 @@ function ValidateCodeModal({code, accountID}: ValidateCodeModalProps) { const [session] = useOnyx(ONYXKEYS.SESSION); const signInHere = useCallback(() => Session.signInWithValidateCode(accountID, code), [accountID, code]); const {translate} = useLocalize(); + const {shouldUseNarrowLayout} = useResponsiveLayout(); return ( { Navigation.goBack(); }} From b497db55c304eef3eb0705373523f6c51a23730b Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Fri, 15 Nov 2024 16:53:44 +0100 Subject: [PATCH 26/52] fix: reanimated missing headers --- ...animated+3.16.1+003+include-missing-header.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 patches/react-native-reanimated+3.16.1+003+include-missing-header.patch diff --git a/patches/react-native-reanimated+3.16.1+003+include-missing-header.patch b/patches/react-native-reanimated+3.16.1+003+include-missing-header.patch new file mode 100644 index 000000000000..80244991a890 --- /dev/null +++ b/patches/react-native-reanimated+3.16.1+003+include-missing-header.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp +index 475ec7a..832fb06 100644 +--- a/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp ++++ b/node_modules/react-native-reanimated/Common/cpp/reanimated/NativeModules/NativeReanimatedModule.cpp +@@ -32,6 +32,8 @@ + + #ifdef RCT_NEW_ARCH_ENABLED + #include ++#include ++#include + #endif // RCT_NEW_ARCH_ENABLED + + // Standard `__cplusplus` macro reference: \ No newline at end of file From a3c11f8f9fb1b9fdd34e6859143fa2917ba6cde8 Mon Sep 17 00:00:00 2001 From: Edu Date: Fri, 15 Nov 2024 15:40:37 +0100 Subject: [PATCH 27/52] Validating Report keys and if a change happens in it, it must be highlighted --- src/types/utils/whitelistedReportKeys.ts | 87 ++++++++++++++++++++++++ tests/unit/validateReportKeysTest.ts | 8 +++ 2 files changed, 95 insertions(+) create mode 100644 src/types/utils/whitelistedReportKeys.ts create mode 100644 tests/unit/validateReportKeysTest.ts diff --git a/src/types/utils/whitelistedReportKeys.ts b/src/types/utils/whitelistedReportKeys.ts new file mode 100644 index 000000000000..0c9222a6eb32 --- /dev/null +++ b/src/types/utils/whitelistedReportKeys.ts @@ -0,0 +1,87 @@ +import type {PolicyReportField, Report} from '../onyx'; +import type * as OnyxCommon from '../onyx/OnyxCommon'; + +// List of keys that are allowed on the Report type. These should be the keys that are sent from the server. +// you need confirmation from an internal engineer that this has indeed been added to the report object that is returned as +type WhitelistedReport = OnyxCommon.OnyxValueWithOfflineFeedback< + { + avatarUrl: unknown; + avatarFileName: unknown; + chatType: unknown; + hasOutstandingChildRequest: unknown; + hasOutstandingChildTask: unknown; + isOwnPolicyExpenseChat: unknown; + isPolicyExpenseChat: unknown; + isPinned: unknown; + lastMessageText: unknown; + lastVisibleActionCreated: unknown; + lastReadTime: unknown; + lastReadSequenceNumber: unknown; + lastMentionedTime: unknown; + policyAvatar: unknown; + policyName: unknown; + oldPolicyName: unknown; + hasParentAccess: unknown; + description: unknown; + isDeletedParentAction: unknown; + policyID: unknown; + reportName: unknown; + reportID: string; + reportActionID: unknown; + chatReportID: unknown; + stateNum: unknown; + statusNum: unknown; + writeCapability: unknown; + type: unknown; + visibility: unknown; + cachedTotal: unknown; + invoiceReceiver: unknown; + lastMessageTranslationKey: unknown; + parentReportID: unknown; + parentReportActionID: unknown; + isOptimisticReport: unknown; + managerID: unknown; + lastVisibleActionLastModified: unknown; + displayName: unknown; + lastMessageHtml: unknown; + lastActorAccountID: unknown; + lastActionType: unknown; + ownerAccountID: unknown; + participants: unknown; + total: unknown; + unheldTotal: unknown; + currency: unknown; + errors: unknown; + errorFields: unknown; + isWaitingOnBankAccount: unknown; + isCancelledIOU: unknown; + iouReportID: unknown; + preexistingReportID: unknown; + nonReimbursableTotal: unknown; + isHidden: unknown; + privateNotes: unknown; + isLoadingPrivateNotes: unknown; + pendingChatMembers: unknown; + transactionThreadReportID: unknown; + fieldList: unknown; + permissions: unknown; + tripData: { + startDate: unknown; + endDate: unknown; + tripID: unknown; + }; + // eslint-disable-next-line @typescript-eslint/naming-convention + private_isArchived: unknown; + }, + PolicyReportField['fieldID'] +>; +type ReportKeys = keyof Report; +type WhitelistedReportKeys = keyof WhitelistedReport; + +type ValidateKeys = Exclude extends never ? true : false; + +// TypeScript type-level check intended to ensure that all keys in the Report type are part of the whitelisted keys. +// However, TypeScript doesn't execute code at runtime, so this check is purely for compile-time validation. +// This validation must be always TRUE. +const testReportKeys: ValidateKeys = true; +export default testReportKeys; diff --git a/tests/unit/validateReportKeysTest.ts b/tests/unit/validateReportKeysTest.ts new file mode 100644 index 000000000000..1339b126e41b --- /dev/null +++ b/tests/unit/validateReportKeysTest.ts @@ -0,0 +1,8 @@ +import testReportKeys from '@src/types/utils/whitelistedReportKeys'; + +// This test is mainly to avoid that the testReportKeys is not removed or changed to false +describe('whitelistedReportKeys', () => { + it('testReportKeys must be true', () => { + expect(testReportKeys).toBe(true); + }); +}); From e7d136e38c56194fb3705c9a2be35cd7511e7bd8 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 15 Nov 2024 17:07:05 +0100 Subject: [PATCH 28/52] Updated comment --- src/types/utils/whitelistedReportKeys.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/types/utils/whitelistedReportKeys.ts b/src/types/utils/whitelistedReportKeys.ts index 0c9222a6eb32..2bb6017584b0 100644 --- a/src/types/utils/whitelistedReportKeys.ts +++ b/src/types/utils/whitelistedReportKeys.ts @@ -1,8 +1,9 @@ import type {PolicyReportField, Report} from '../onyx'; import type * as OnyxCommon from '../onyx/OnyxCommon'; -// List of keys that are allowed on the Report type. These should be the keys that are sent from the server. -// you need confirmation from an internal engineer that this has indeed been added to the report object that is returned as +// List of keys that are allowed on the Report type. These should be the keys that are returned from the server in OpenApp. +// Before changing this, you need confirmation from an internal engineer that the new key has been added to the report object that is returned from the back-end in OpenApp +// Any report data that you want to store in Onyx, but isn't returned from the server, should be stored in reportMetaData. type WhitelistedReport = OnyxCommon.OnyxValueWithOfflineFeedback< { avatarUrl: unknown; From 14609302259edb5f1c8a631cd2a54839402040b2 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 15 Nov 2024 17:17:20 +0100 Subject: [PATCH 29/52] fixed imports --- src/types/utils/whitelistedReportKeys.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/utils/whitelistedReportKeys.ts b/src/types/utils/whitelistedReportKeys.ts index 2bb6017584b0..3c566c987526 100644 --- a/src/types/utils/whitelistedReportKeys.ts +++ b/src/types/utils/whitelistedReportKeys.ts @@ -1,5 +1,5 @@ -import type {PolicyReportField, Report} from '../onyx'; -import type * as OnyxCommon from '../onyx/OnyxCommon'; +import type {PolicyReportField, Report} from '@src/types/onyx'; +import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; // List of keys that are allowed on the Report type. These should be the keys that are returned from the server in OpenApp. // Before changing this, you need confirmation from an internal engineer that the new key has been added to the report object that is returned from the back-end in OpenApp From 6dc5507184db3884830e25add289cbe5bd5d00b3 Mon Sep 17 00:00:00 2001 From: jaydamani Date: Fri, 15 Nov 2024 18:22:46 +0100 Subject: [PATCH 30/52] fix default for id --- src/libs/actions/Report.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 5f3aa94dd358..ac598d8fc58d 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3533,7 +3533,7 @@ function prepareOnboardingOptimisticData( navatticURL: getNavatticURL(environment, engagementChoice), integrationName, workspaceAccountingLink: `${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(onboardingPolicyID ?? '-1')}`, - workspaceSettingsLink: `${environmentURL}/${ROUTES.WORKSPACE_INITIAL.getRoute(onboardingPolicyID ?? '01')}`, + workspaceSettingsLink: `${environmentURL}/${ROUTES.WORKSPACE_INITIAL.getRoute(onboardingPolicyID ?? '-1')}`, }) : task.description; const taskTitle = From 5e49de6ae838e33ec19b96eb40285d14ff3957e2 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Fri, 15 Nov 2024 17:48:26 +0000 Subject: [PATCH 31/52] Update version to 9.0.63-2 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index f0c404612d45..458dff08605a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009006301 - versionName "9.0.63-1" + versionCode 1009006302 + versionName "9.0.63-2" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index b6eec7bf2d62..67868734116e 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.63.1 + 9.0.63.2 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index e70000341bed..4eb3c8bc116f 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 9.0.63.1 + 9.0.63.2 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 7d62bc205114..e9b60076f29c 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.0.63 CFBundleVersion - 9.0.63.1 + 9.0.63.2 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 40e9249e0197..b55b187bb8ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.63-1", + "version": "9.0.63-2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.63-1", + "version": "9.0.63-2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 73d1120fe0b9..936e34b1e727 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.63-1", + "version": "9.0.63-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 3c01987c2f9c6b64b7b0b31669ed5b62bced5bce Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Fri, 15 Nov 2024 11:21:24 -0700 Subject: [PATCH 32/52] Allow Android Rollout Bumper to be run manually and add key to fix error --- .github/workflows/androidBump.yml | 1 + fastlane/Fastfile | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/androidBump.yml b/.github/workflows/androidBump.yml index 8a4f7d514208..b2276551852f 100644 --- a/.github/workflows/androidBump.yml +++ b/.github/workflows/androidBump.yml @@ -1,6 +1,7 @@ name: Android Rollout Bumper on: + workflow_dispatch: schedule: # Runs at midnight every day - cron: '0 0 * * *' diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 1c8b62cfb579..31738835b1dc 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -283,7 +283,10 @@ platform :android do desc "Update HybridApp rollout percentage on Google Play" lane :update_hybrid_rollout do |options| - productionVersionCode = google_play_track_version_codes(track: 'production') + productionVersionCode = google_play_track_version_codes( + track: 'production', + json_key: './android/app/android-fastlane-json-key.json', + ) upload_to_play_store( package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', From 7c7d1ccdc021fcafb5fdc314d229dc7dcf46e40e Mon Sep 17 00:00:00 2001 From: Jack Nam <30609178+thienlnam@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:45:17 -0800 Subject: [PATCH 33/52] Revert "Fix blank space is shown on iOS safari when magic code screen show" --- src/pages/signin/SignInPage.tsx | 54 ++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/pages/signin/SignInPage.tsx b/src/pages/signin/SignInPage.tsx index 5f00be36c018..1068cf97197e 100644 --- a/src/pages/signin/SignInPage.tsx +++ b/src/pages/signin/SignInPage.tsx @@ -1,7 +1,7 @@ import {Str} from 'expensify-common'; import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} from 'react'; -import type {ForwardedRef} from 'react'; -import {useOnyx} from 'react-native-onyx'; +import type {ForwardedRef, RefAttributes} from 'react'; +import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import ColorSchemeWrapper from '@components/ColorSchemeWrapper'; import CustomStatusBarAndBackground from '@components/CustomStatusBarAndBackground'; @@ -24,7 +24,7 @@ import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Account, Credentials} from '@src/types/onyx'; +import type {Account, Credentials, Locale} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import ChooseSSOOrMagicCode from './ChooseSSOOrMagicCode'; import EmailDeliveryFailurePage from './EmailDeliveryFailurePage'; @@ -37,7 +37,21 @@ import UnlinkLoginForm from './UnlinkLoginForm'; import ValidateCodeForm from './ValidateCodeForm'; import type {BaseValidateCodeFormRef} from './ValidateCodeForm/BaseValidateCodeForm'; -type SignInPageInnerProps = { +type SignInPageInnerOnyxProps = { + /** The details about the account that the user is signing in with */ + account: OnyxEntry; + + /** The credentials of the person signing in */ + credentials: OnyxEntry; + + /** Active Clients connected to ONYX Database */ + activeClients: OnyxEntry; + + /** The user's preferred locale */ + preferredLocale: OnyxEntry; +}; + +type SignInPageInnerProps = SignInPageInnerOnyxProps & { shouldEnableMaxHeight?: boolean; }; @@ -132,18 +146,8 @@ function getRenderOptions({ shouldShouldSignUpWelcomeForm, }; } -function SignInPage({shouldEnableMaxHeight = true}: SignInPageInnerProps, ref: ForwardedRef) { - const [credentials] = useOnyx(ONYXKEYS.CREDENTIALS); - const [account] = useOnyx(ONYXKEYS.ACCOUNT); - /** - This variable is only added to make sure the component is re-rendered - whenever the activeClients change, so that we call the - ActiveClientManager.isClientTheLeader function - everytime the leader client changes. - We use that function to prevent repeating code that checks which client is the leader. - */ - const [activeClients] = useOnyx(ONYXKEYS.ACTIVE_CLIENTS); - const [preferredLocale] = useOnyx(ONYXKEYS.NVP_PREFERRED_LOCALE); + +function SignInPage({credentials, account, activeClients = [], preferredLocale, shouldEnableMaxHeight = true}: SignInPageInnerProps, ref: ForwardedRef) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {translate, formatPhoneNumber} = useLocalize(); @@ -291,6 +295,7 @@ function SignInPage({shouldEnableMaxHeight = true}: SignInPageInnerProps, ref: F @@ -335,6 +340,7 @@ function SignInPage({shouldEnableMaxHeight = true}: SignInPageInnerProps, ref: F } type SignInPageProps = SignInPageInnerProps; +type SignInPageOnyxProps = SignInPageInnerOnyxProps; const SignInPageWithRef = forwardRef(SignInPage); function SignInPageThemeWrapper(props: SignInPageProps, ref: ForwardedRef) { @@ -356,6 +362,20 @@ function SignInPageThemeWrapper(props: SignInPageProps, ref: ForwardedRef, SignInPageOnyxProps>({ + account: {key: ONYXKEYS.ACCOUNT}, + credentials: {key: ONYXKEYS.CREDENTIALS}, + /** + This variable is only added to make sure the component is re-rendered + whenever the activeClients change, so that we call the + ActiveClientManager.isClientTheLeader function + everytime the leader client changes. + We use that function to prevent repeating code that checks which client is the leader. + */ + activeClients: {key: ONYXKEYS.ACTIVE_CLIENTS}, + preferredLocale: { + key: ONYXKEYS.NVP_PREFERRED_LOCALE, + }, +})(forwardRef(SignInPageThemeWrapper)); export type {SignInPageRef}; From 2bd77436568b2538e843483b10ea6e3eb60a9be5 Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Fri, 15 Nov 2024 11:46:51 -0700 Subject: [PATCH 34/52] Update with `package_name` and even better debug --- .github/workflows/androidBump.yml | 3 +++ fastlane/Fastfile | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/androidBump.yml b/.github/workflows/androidBump.yml index b2276551852f..04a27fd6cf3b 100644 --- a/.github/workflows/androidBump.yml +++ b/.github/workflows/androidBump.yml @@ -5,6 +5,9 @@ on: schedule: # Runs at midnight every day - cron: '0 0 * * *' + push: + branches: + - andrew-android-bump-fixes-2 jobs: android_bump: diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 31738835b1dc..df917e9cf424 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -265,7 +265,11 @@ platform :android do desc "Submit HybridApp to 100% rollout on Google Play" lane :complete_hybrid_rollout do - productionVersionCode = google_play_track_version_codes(track: 'production') + productionVersionCode = google_play_track_version_codes( + track: 'production', + package_name: "org.me.mobiexpensifyg", + json_key: './android/app/android-fastlane-json-key.json', + ) upload_to_play_store( package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', @@ -285,6 +289,7 @@ platform :android do lane :update_hybrid_rollout do |options| productionVersionCode = google_play_track_version_codes( track: 'production', + package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', ) upload_to_play_store( From 497a61f974e5453fe1373419dac46a0ac240dd7e Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Fri, 15 Nov 2024 11:53:53 -0700 Subject: [PATCH 35/52] Sort and grab last version code --- fastlane/Fastfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index df917e9cf424..fd0956ea18b5 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -265,7 +265,7 @@ platform :android do desc "Submit HybridApp to 100% rollout on Google Play" lane :complete_hybrid_rollout do - productionVersionCode = google_play_track_version_codes( + productionVersionCodes = google_play_track_version_codes( track: 'production', package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', @@ -273,7 +273,7 @@ platform :android do upload_to_play_store( package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', - version_code: productionVersionCode, + version_code: productionVersionCodes.sort.last, # Get the latest version code track: 'production', rollout: '1', skip_upload_apk: true, @@ -287,7 +287,7 @@ platform :android do desc "Update HybridApp rollout percentage on Google Play" lane :update_hybrid_rollout do |options| - productionVersionCode = google_play_track_version_codes( + productionVersionCodes = google_play_track_version_codes( track: 'production', package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', @@ -295,7 +295,7 @@ platform :android do upload_to_play_store( package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', - version_code: productionVersionCode, + version_code: productionVersionCode.sort.last, # Get the latest version code track: 'production', rollout: options[:rollout], skip_upload_apk: true, From 4ef3090b419cb7c312e4a66500f9bcb89ddd072e Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Fri, 15 Nov 2024 11:55:19 -0700 Subject: [PATCH 36/52] Add s --- fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index fd0956ea18b5..dcf7c9f238a6 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -295,7 +295,7 @@ platform :android do upload_to_play_store( package_name: "org.me.mobiexpensifyg", json_key: './android/app/android-fastlane-json-key.json', - version_code: productionVersionCode.sort.last, # Get the latest version code + version_code: productionVersionCodes.sort.last, # Get the latest version code track: 'production', rollout: options[:rollout], skip_upload_apk: true, From 686f62096de13424124214cd06e63f890e21faae Mon Sep 17 00:00:00 2001 From: Andrew Gable Date: Fri, 15 Nov 2024 12:00:00 -0700 Subject: [PATCH 37/52] Remove debug trigger --- .github/workflows/androidBump.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/androidBump.yml b/.github/workflows/androidBump.yml index 04a27fd6cf3b..b2276551852f 100644 --- a/.github/workflows/androidBump.yml +++ b/.github/workflows/androidBump.yml @@ -5,9 +5,6 @@ on: schedule: # Runs at midnight every day - cron: '0 0 * * *' - push: - branches: - - andrew-android-bump-fixes-2 jobs: android_bump: From 992e5d455a700ec78f739c054e5ab66d0a4ed6d8 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Fri, 15 Nov 2024 19:23:34 +0000 Subject: [PATCH 38/52] Update version to 9.0.63-3 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 458dff08605a..5fd9f28f0732 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009006302 - versionName "9.0.63-2" + versionCode 1009006303 + versionName "9.0.63-3" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 67868734116e..d2577911d8e8 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.63.2 + 9.0.63.3 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 4eb3c8bc116f..3b6df8fa0017 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 9.0.63.2 + 9.0.63.3 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index e9b60076f29c..47515260d65c 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.0.63 CFBundleVersion - 9.0.63.2 + 9.0.63.3 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index b55b187bb8ac..4caba424161e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.63-2", + "version": "9.0.63-3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.63-2", + "version": "9.0.63-3", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 936e34b1e727..766126a91393 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.63-2", + "version": "9.0.63-3", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 538b9ecf86150bb2e818db92aca6b9ab12fa0d30 Mon Sep 17 00:00:00 2001 From: Scott Deeter Date: Fri, 15 Nov 2024 14:52:27 -0800 Subject: [PATCH 39/52] Don't complete onboarding if not an invited user --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index e0c2fb339f52..58888eb291d8 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7349,7 +7349,7 @@ function cancelPayment(expenseReport: OnyxEntry, chatReport: O function completePaymentOnboarding(paymentSelected: ValueOf) { const isInviteOnboardingComplete = introSelected?.isInviteOnboardingComplete ?? false; - if (isInviteOnboardingComplete || !introSelected?.choice) { + if (isInviteOnboardingComplete || !introSelected?.choice || !introSelected?.inviteType) { return; } From 40f47d7612359e040b07c036332c826f7088c3d8 Mon Sep 17 00:00:00 2001 From: David Barrett Date: Sat, 16 Nov 2024 20:16:29 -0800 Subject: [PATCH 40/52] Updating mobile layout --- help/_includes/search.html | 8 ++-- help/_layouts/default.html | 80 +++++++++++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/help/_includes/search.html b/help/_includes/search.html index 7b024ba8ec33..91abb56ad60b 100644 --- a/help/_includes/search.html +++ b/help/_includes/search.html @@ -27,14 +27,14 @@
+
+
+
+
+
@@ -237,11 +300,11 @@ Invoice Billpay + {% include search.html %}
- - {% include search.html %} -