Skip to content

Commit b735261

Browse files
authored
Merge branch 'Expensify:main' into krishna2323/issue/87460
2 parents 4989538 + 50270ae commit b735261

383 files changed

Lines changed: 7362 additions & 3943 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Is Contributor+
2+
description: Check whether a GitHub user is a member of the Expensify/contributor-plus team. Sets IS_CPLUS=true when the user is a member, IS_CPLUS=false otherwise.
3+
4+
inputs:
5+
USERNAME:
6+
description: The GitHub login of the user to check.
7+
required: true
8+
OS_BOTIFY_TOKEN:
9+
description: OSBotify token. Needed to read team memberships (the default GITHUB_TOKEN lacks the read:org scope).
10+
required: true
11+
12+
outputs:
13+
IS_CPLUS:
14+
description: "'true' if the user is a member of Expensify/contributor-plus, 'false' otherwise."
15+
value: ${{ steps.check.outputs.IS_CPLUS }}
16+
17+
runs:
18+
using: composite
19+
steps:
20+
- name: Check Contributor+ membership
21+
id: check
22+
shell: bash
23+
env:
24+
GH_TOKEN: ${{ inputs.OS_BOTIFY_TOKEN }}
25+
USERNAME: ${{ inputs.USERNAME }}
26+
run: |
27+
if gh api "/orgs/Expensify/teams/contributor-plus/memberships/$USERNAME" --silent; then
28+
echo "::notice::✅ $USERNAME is a Contributor+ member"
29+
echo "IS_CPLUS=true" >> "$GITHUB_OUTPUT"
30+
else
31+
echo "::notice::$USERNAME is not a Contributor+ member"
32+
echo "IS_CPLUS=false" >> "$GITHUB_OUTPUT"
33+
fi

.github/workflows/claude-review.yml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,50 @@ permissions:
77
on:
88
pull_request_target:
99
types: [opened, ready_for_review]
10+
pull_request_review:
11+
types: [submitted]
1012

1113
concurrency:
1214
group: claude-review-${{ github.event.pull_request.html_url }}
1315
cancel-in-progress: true
1416

1517
jobs:
1618
validate:
19+
if: github.event_name == 'pull_request_target'
1720
uses: ./.github/workflows/contributorValidationGate.yml
1821
with:
1922
PR_NUMBER: ${{ github.event.pull_request.number }}
2023
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
2124
AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }}
2225

26+
checkCPlusApproval:
27+
if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved'
28+
runs-on: blacksmith-2vcpu-ubuntu-2404
29+
outputs:
30+
IS_CPLUS: ${{ steps.check.outputs.IS_CPLUS }}
31+
steps:
32+
- name: Checkout repository
33+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
34+
with:
35+
fetch-depth: 1
36+
37+
- name: Check Contributor+ membership
38+
id: check
39+
uses: ./.github/actions/composite/isContributorPlus
40+
with:
41+
USERNAME: ${{ github.event.review.user.login }}
42+
OS_BOTIFY_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }}
43+
2344
review:
24-
needs: [validate]
45+
needs: [validate, checkCPlusApproval]
2546
if: |
26-
needs.validate.outputs.IS_AUTHORIZED == 'true'
47+
!cancelled()
2748
&& github.event.pull_request.draft != true
2849
&& !contains(github.event.pull_request.title, 'Revert')
50+
&& (
51+
(github.event_name == 'pull_request_target' && needs.validate.outputs.IS_AUTHORIZED == 'true')
52+
|| (github.event_name == 'pull_request_review' && needs.checkCPlusApproval.outputs.IS_CPLUS == 'true')
53+
)
2954
runs-on: blacksmith-2vcpu-ubuntu-2404
3055
env:
3156
PR_NUMBER: ${{ github.event.pull_request.number }}

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ android {
111111
minSdkVersion rootProject.ext.minSdkVersion
112112
targetSdkVersion rootProject.ext.targetSdkVersion
113113
multiDexEnabled rootProject.ext.multiDexEnabled
114-
versionCode 1009036103
115-
versionName "9.3.61-3"
114+
versionCode 1009036201
115+
versionName "9.3.62-1"
116116
// Supported language variants must be declared here to avoid from being removed during the compilation.
117117
// This also helps us to not include unnecessary language variants in the APK.
118118
resConfigs "en", "es"
Lines changed: 1 addition & 0 deletions
Loading

babel.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ const metro = {
130130
production: {
131131
plugins: [['transform-remove-console', {exclude: ['error', 'warn']}]],
132132
},
133+
test: {
134+
plugins: ['@babel/plugin-transform-dynamic-import'],
135+
},
133136
},
134137
};
135138

contributingGuides/PERFORMANCE.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ Since our codebase is very complex, it results in a large DOM tree rendered for
282282

283283
One of the most common issues is related to modals, popovers, and tooltips — elements that may appear on the screen. The problem is that they are usually present in the DOM tree even when initially invisible. Because of this, the initial render time of a screen may increase, ultimately slowing down the app.
284284

285-
The solution is better control of invisible elements, making sure they are not included in the first render. This can be done, e.g., by a simple `return null`, smart usage of `lazy loading`, the `useTransition` hook, or the `<Deferred />` component.
285+
The solution is better control of invisible elements, making sure they are not included in the first render. This can be done, e.g., by a simple `return null`, smart usage of `lazy loading`, the `useTransition` hook, or the [`<NavigationDeferredMount />`](/src/components/NavigationDeferredMount.tsx) component. `<NavigationDeferredMount />` gates a heavy subtree behind navigation transition completion via `TransitionTracker`, rendering a cheap `placeholder` until the nav animation has finished, then mounting its `children` inside `startTransition` — ideal for heavy subtrees (e.g. report headers, page-level secondary actions) mounted during navigation transitions that pull many `useOnyx` subscriptions or heavy hooks but don't need to be interactive on first render.
286286

287287
Another issue worth mentioning is unnecessary code execution, especially for elements that are never shown on a specific platform. In theory, we separate the logic between platforms by using index.tsx/index.native.tsx files, but sometimes platform-specific logic may slip in, causing unnecessary execution. For example, this may happen when logic specific to a wide layout (applicable only for web) is included.
288288

@@ -294,6 +294,7 @@ Examples:
294294
- [PopoverWithMeasuredContent optimization for mobile](https://github.com/Expensify/App/pull/68223) - returns early to avoid unnecessary calculations
295295
- [Reduce confirm modal initial render count](https://github.com/Expensify/App/pull/67518) - returns early to reduce first load cost
296296
- [Do not render PopoverMenu until it gets opened](https://github.com/Expensify/App/pull/67877) - adds a wrapper to control if `PopoverMenu` should be rendered
297+
- [Defer mount of MoneyReportHeaderSecondaryActions](https://github.com/Expensify/App/pull/88522) - introduces `NavigationDeferredMount` and uses it to defer the "More" dropdown subtree (20+ `useOnyx` subscriptions) until the navigation transition completes
297298

298299
# Proposing Performance Improvements
299300

contributingGuides/STYLE.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,7 @@ When you change the function id argument type to allow `undefined`, check if it
571571
572572
```diff
573573
function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = false, updatedTransaction, isFromReviewDuplicates = false}: MoneyRequestViewProps) {
574-
const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, {
575-
canEvict: false,
576-
});
574+
const [parentReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`);
577575
- const parentReportAction = parentReportActions?.[report?.parentReportActionID ?? '-1'];
578576
+ const parentReportAction = parentReportActions?.[report?.parentReportActionID];
579577
```

contributingGuides/philosophies/ONYX-DATA-MANAGEMENT.md

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,7 @@ Different platforms come with varying storage capacities and Onyx has a way to g
3535

3636
**To flag a key as safe for removal:**
3737
- Add the key to the `evictableKeys` option in `Onyx.init(options)`
38-
- Implement `canEvict` in the Onyx config for each component subscribing to a key
39-
- The key will only be deleted when all subscribers return `true` for `canEvict`
40-
41-
Example:
42-
```js
43-
Onyx.init({
44-
evictableKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
45-
});
46-
47-
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canEvict: !isActiveReport});
48-
```
38+
- A least recently accessed key will only be deleted when an Onyx operation retries after failing.
4939

5040
## Onyx Derived Values
5141

docs/Hidden/UK-and-EU-Expensify-Card.md

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ REMOVE noindex: true AND sitemap: false FROM YAML HEADER BEFORE PUBLISHING!
1313

1414
# Set up the Expensify Card in the UK and EU
1515

16-
The Expensify Card is available for companies in the United Kingdom and select European countries. This guide walks you through eligibility and how to set up and start using the card in GBP or EUR.
16+
The Expensify Card is available for companies in the United Kingdom and select European countries. This guide walks you through eligibility and how to set up and start using the card in GBP or EUR.
1717

1818
Workspace Admins can issue virtual Expensify Cards to members and manage spending in GBP or EUR. Physical cards will be available soon.
1919

@@ -33,34 +33,27 @@ If your company hasn’t yet connected a GBP or EUR business bank account, [foll
3333

3434
The Expensify Card can be used **anywhere Visa is accepted**.
3535

36-
However, only companies registered in the following 20 UK and EU countries can enable the Expensify Card for their Workspace:
37-
38-
- Belgium
39-
- Denmark
40-
- Estonia
41-
- Finland
42-
- Gibraltar
43-
- Greece
44-
- Ireland
45-
- Latvia
46-
- Liechtenstein
47-
- Lithuania
48-
- Luxembourg
49-
- Malta
50-
- Netherlands
51-
- Poland
52-
- Romania
53-
- Slovakia
54-
- Slovenia
55-
- Spain
56-
- Sweden
36+
Companies registered in the following countries can enable the Expensify Card for their Workspaces:
37+
38+
- Belgium
39+
- Denmark
40+
- Finland
41+
- Gibraltar
42+
- Ireland
43+
- Latvia
44+
- Lithuania
45+
- Luxembourg
46+
- Netherlands
47+
- Poland
48+
- Spain
49+
- Sweden
5750
- United Kingdom
5851

5952
## What are the pre-requisites to set up the Expensify Card in the UK and EU
6053

61-
To set up the Expensify Card in the UK and EU, you must:
54+
To set up the Expensify Card in the UK and EU, you must:
6255

63-
1. Have a GBP or EUR bank account connected. To connect one, [Enable Global Reimbursement](https://help.expensify.com/articles/new-expensify/wallet-and-payments/Enable-Global-Reimbursement).
56+
1. Have a GBP or EUR bank account connected. To connect one, [Enable Global Reimbursement](https://help.expensify.com/articles/new-expensify/wallet-and-payments/Enable-Global-Reimbursement).
6457
2. Complete the **[Know Your Customer (KYC)](https://launch-workflow.trulioo.com/68223577c5dae52a6ec9347f)** and **[Know Your Business (KYB)](https://launch-workflow.trulioo.com/681a7cc4e65d2e48f19de9c3)** forms.
6558
3. Share the last 90 days of statements from your connected GBP or EUR bank account with Concierge so they can assess your eligible limit
6659

@@ -70,9 +63,9 @@ To set up the Expensify Card in the UK and EU, you must:
7063

7164
1. From navigation tabs (on the left on Web, on the bottom on Mobile), choose **Workspaces > [Workspace Name] > More features**.
7265
2. In the **Spend** section, enable **Expensify Card**.
73-
3. So that we can assess your request, reach out to Concierge and provide the last 90 days of statements from the connected UK or EU bank account
66+
3. So that we can assess your request, reach out to Concierge and provide the last 90 days of statements from the connected UK or EU bank account
7467

75-
Once enabled, **Expensify Card** will appear in the navigation tabs.
68+
Once enabled, **Expensify Card** will appear in the navigation tabs.
7669

7770
---
7871

@@ -88,7 +81,7 @@ Once enabled, **Expensify Card** will appear in the navigation tabs.
8881

8982
1. From navigation tabs (on the left on Web, on the bottom on Mobile), choose **Workspaces > [Workspace Name] > Expensify Card**
9083
2. Click **Issue new card**.
91-
3. Select the employee the card should be issued to.
84+
3. Select the employee the card should be issued to.
9285
4. Choose **Virtual**.
9386
5. Pick a limit type:
9487
- **Smart limit** – Spend up to a threshold before needing approval
@@ -110,7 +103,7 @@ We use the [Visa FX calculator](https://www.visa.co.uk/support/consumer/travel-s
110103

111104
## Does the Expensify Card support Visa Secure for online transactions?
112105

113-
Yes, the Expensify Card protects online transactions with Visa Secure. Please review the [Visa Secure FAQs]({{site.url}}/assets/Files/Visa-secure-faq-expensify.pdf) for more information.
106+
Yes, the Expensify Card protects online transactions with Visa Secure. Please review the [Visa Secure FAQs]({{site.url}}/assets/Files/Visa-secure-faq-expensify.pdf) for more information.
114107

115108
## How do I get help with the Expensify Card in the UK and EU?
116109

0 commit comments

Comments
 (0)