Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libs/CardUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ function hasIssuedExpensifyCard(workspaceAccountID: number, allCardList: OnyxCol
* Check if the Expensify Card is fully set up and a new card can be issued
*/
function isExpensifyCardFullySetUp(policy?: OnyxEntry<Policy>, cardSettings?: OnyxEntry<ExpensifyCardSettings>): boolean {
return !!(policy?.areExpensifyCardsEnabled && cardSettings?.paymentBankAccountID);
return !!(policy?.areExpensifyCardsEnabled && getCardSettings(cardSettings)?.paymentBankAccountID);
}

function getCardSettings(cardSettings: OnyxEntry<ExpensifyCardSettings>, feedCountry?: string): ExpensifyCardSettingsBase | undefined {
Expand Down
10 changes: 10 additions & 0 deletions src/pages/workspace/accounting/PolicyAccountingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import usePermissions from '@hooks/usePermissions';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWorkspaceAccountID from '@hooks/useWorkspaceAccountID';
import useWorkspaceDocumentTitle from '@hooks/useWorkspaceDocumentTitle';
import {isAuthenticationError, isConnectionInProgress, isConnectionUnverified, removePolicyConnection, syncConnection} from '@libs/actions/connections';
import {shouldShowQBOReimbursableExportDestinationAccountError} from '@libs/actions/connections/QuickbooksOnline';
Expand All @@ -53,6 +54,7 @@ import Navigation from '@navigation/Navigation';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import {openOldDotLink} from '@userActions/Link';
import {openPolicyExpensifyCardsPage} from '@userActions/Policy/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand Down Expand Up @@ -92,6 +94,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
const integrationToDisconnect = params?.integrationToDisconnect;
const shouldDisconnectIntegrationBeforeConnecting = params?.shouldDisconnectIntegrationBeforeConnecting;
const policyID = policy?.id;
const workspaceAccountID = useWorkspaceAccountID(policyID);
const allCardSettings = useExpensifyCardFeeds(policyID);
const isSyncInProgress = isConnectionInProgress(connectionSyncProgress, policy);
const icons = useMemoizedLazyExpensifyIcons([
Expand Down Expand Up @@ -210,6 +213,13 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
setDateTimeToRelative('');
}, [getDatetimeToRelative, successfulDate]);

useEffect(() => {
if (!policyID || !policy?.areExpensifyCardsEnabled || !workspaceAccountID) {
return;
}
openPolicyExpensifyCardsPage(policyID, workspaceAccountID);
}, [policyID, policy?.areExpensifyCardsEnabled, workspaceAccountID]);
Comment on lines +217 to +221

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip redundant card-settings reads on accounting page mount

This effect calls openPolicyExpensifyCardsPage on every mount whenever cards are enabled, but it never checks whether the workspace’s card settings have already been loaded (hasOnceLoaded). In practice, revisiting Accounting repeatedly will trigger unnecessary OPEN_POLICY_EXPENSIFY_CARDS_PAGE reads and extra Onyx loading merges for already-cached data, which adds avoidable network/backend load and state churn.

Useful? React with 👍 / 👎.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expensify Cards can be updated from another platform, so we need to refetch to ensure we get the latest data instead of navigating to the Expensify Card page to fetch it.


const integrationSpecificMenuItems = useMemo(() => {
const sageIntacctEntityList = policy?.connections?.intacct?.data?.entities ?? [];
const netSuiteSubsidiaryList = policy?.connections?.netsuite?.options?.data?.subsidiaryList ?? [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import useOnyx from '@hooks/useOnyx';
import useThemeStyles from '@hooks/useThemeStyles';
import {getConnectionNameFromRouteParam} from '@libs/AccountingUtils';
import {openPolicyAccountingPage} from '@libs/actions/PolicyConnections';
import {isExpensifyCardFullySetUp} from '@libs/CardUtils';
import {getCardSettings, isExpensifyCardFullySetUp} from '@libs/CardUtils';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
import Navigation from '@navigation/Navigation';
import type {SettingsNavigatorParamList} from '@navigation/types';
Expand Down Expand Up @@ -74,13 +74,14 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) {
const [currentConnectionName] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${effectiveDomainID}`);
const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);

const paymentBankAccountID = fullySetUpCardSetting.cardSetting?.paymentBankAccountID ?? CONST.DEFAULT_NUMBER_ID;
const resolvedCardSettings = getCardSettings(fullySetUpCardSetting.cardSetting);
const paymentBankAccountID = resolvedCardSettings?.paymentBankAccountID ?? CONST.DEFAULT_NUMBER_ID;
const bankAccountTitle = bankAccountList?.[paymentBankAccountID]?.title ?? '';

const {connection} = route.params;
const connectionName = getConnectionNameFromRouteParam(connection) as ConnectionName;
const autoSync = !!policy?.connections?.[connectionName]?.config?.autoSync?.enabled;
const shouldShow = !!fullySetUpCardSetting.cardSetting?.paymentBankAccountID;
const shouldShow = !!resolvedCardSettings?.paymentBankAccountID;

const handleToggleContinuousReconciliation = (value: boolean) => {
toggleContinuousReconciliation(effectiveDomainID, value, connectionName, currentConnectionName);
Expand Down
Loading