Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Expensify/App into fix/excesive-sug…
Browse files Browse the repository at this point in the history
…gestion-updates-maimum-update-depth-exceeded
  • Loading branch information
hannojg committed Aug 6, 2024
2 parents dce2589 + f7e265a commit 0ed014d
Show file tree
Hide file tree
Showing 109 changed files with 1,610 additions and 699 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1009001604
versionName "9.0.16-4"
versionCode 1009001700
versionName "9.0.17-0"
// 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"
Expand Down
9 changes: 9 additions & 0 deletions assets/images/user-check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: Manage Expensify Cards
description: How to manage the Expensify Card
---
<div id="new-expensify" markdown="1">

Once your Expensify Cards have been issued, you can monitor them and check your card’s current balance, remaining limit, and earned cash back.

1. Click your profile image or icon in the bottom left menu.
2. Scroll down and click **Workspaces** in the left menu.
3. Select the workspace that contains the desired Expensify Cards.
4. Click **Expensify Card** in the left menu. Here, you’ll see a list of all of the issued cards.
5. To view a card’s details or adjust the card limit, limit type, name, or deactivate it, click the card row.
6. To adjust the settlement account that resolves the card’s expenses or to change the settlement frequency, click **Settings** in the top right.

![Click Expensify Card in the left menu to see a list of cards]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_05.png){:width="100%"}

![Click the card row to view the card details and make settings adjustments]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_06.png){:width="100%"}

![Click Settings to adjust the settlement account or frequency]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_07.png){:width="100%"}

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
title: Set up the Expensify Card
description: How to set up the Expensify Card on your workspace
---
<div id="new-expensify" markdown="1">

{% include info.html %}
You must be a Workspace Admin to complete this process.
{% include end-info.html %}

The Expensify Visa® Commercial Card is available on all USD workspaces. It provides tools to manage employee spending, including:

- Unlimited virtual cards
- Controlled spending amounts on virtual cards to manage subscriptions
- Tighter controls for managing spend across employees and merchants
- Fixed or monthly spend limits for each card
- Unique naming for each virtual card for simplified expense categorization

To enable and issue Expensify Cards for your workspace, complete the steps below.

# Step 1: Enable Expensify Cards

1. Click your profile image or icon in the bottom left menu.
2. Scroll down and click **Workspaces** in the left menu.
3. Select the workspace you want to enable Expensify Cards for.
4. Click **More features** in the left menu.
5. Under the **Spend** section, enable the Expensify Card toggle.

![Click the toggle next to Expensify Card]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_01.png){:width="100%"}

# Step 2: Select a bank account

Before you can issue your Expensify Cards, you must connect your cards with the bank account that will be used to pay balances on the cards.

1. Click **Expensify Card** in the left menu.
2. Click **Issue new card**.
3. Select an existing bank account from the list, or follow the steps to add a new one.

![Click the issue card button]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_02.png){:width="100%"}

# Step 3: Issue cards

You can issue an unlimited amount of physical and/or virtual cards to employees.

1. Click **Issue card** in the top right.
2. Select the employee that you want to issue the card to.
3. Select whether you want to issue a physical or virtual card.
4. Pick a smart, monthly, or fixed limit:
- Smart limits allow spending up to a certain amount before requiring approval.
- Monthly limits allow spending up to a certain amount per month.
- Fixed limits allow spending up to a certain amount before the card is terminated.
5. Enter the limit amount.
6. Add a card name.
7. Click **Issue card** to confirm and issue the card.

![Click the issue card button in the top right]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_03.png){:width="100%"}

![Click issue card to confirm and issue the card]({{site.url}}/assets/images/ExpensifyHelp-WorkspaceFeeds_04.png){:width="100%"}

{% include faq-begin.md %}
**Do you need a specific type of bank account to use the Expensify Card?**

At this time, the Expensify Card requires a US business bank account opened in the name of a business incorporated in the US.

**Can I use the Expensify Card across multiple workspaces?**

You can use the Expensify Card on every workspace you create. However, a settlement account can only be used with the Expensify Card on one workspace. For example, if you’re using the Expensify Card on three workspaces, you need three settlement accounts.

**Can I issue multiple cards to the same employee?**

You can issue an unlimited number of both physical and virtual cards to employees. This supports a wide variety of different use cases, ranging from each employee only having one card, to employees having numerous cards for things like individual trips, specific purchases, etc.
{% include faq-end.md %}

</div>
Binary file added docs/assets/images/Duty-of-care.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/Export-Expenses.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/images/Travel-Analytics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>9.0.16</string>
<string>9.0.17</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>9.0.16.4</string>
<string>9.0.17.0</string>
<key>FullStory</key>
<dict>
<key>OrgId</key>
Expand Down
4 changes: 2 additions & 2 deletions ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>9.0.16</string>
<string>9.0.17</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>9.0.16.4</string>
<string>9.0.17.0</string>
</dict>
</plist>
4 changes: 2 additions & 2 deletions ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundleShortVersionString</key>
<string>9.0.16</string>
<string>9.0.17</string>
<key>CFBundleVersion</key>
<string>9.0.16.4</string>
<string>9.0.17.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "9.0.16-4",
"version": "9.0.17-0",
"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.",
Expand Down
71 changes: 71 additions & 0 deletions patches/expo-image-manipulator+11.8.0.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
diff --git a/node_modules/expo-image-manipulator/build/ExpoImageManipulator.web.js b/node_modules/expo-image-manipulator/build/ExpoImageManipulator.web.js
index 5b77ad6..a3ecdb0 100644
--- a/node_modules/expo-image-manipulator/build/ExpoImageManipulator.web.js
+++ b/node_modules/expo-image-manipulator/build/ExpoImageManipulator.web.js
@@ -1,5 +1,13 @@
import { crop, extent, flip, resize, rotate } from './actions/index.web';
import { getContext } from './utils/getContext.web';
+
+const SAFARI_MOBILE_CANVAS_LIMIT = 4096;
+
+const isMobileIOS = () => {
+ const userAgent = navigator.userAgent;
+ return /iP(ad|od|hone)/i.test(userAgent) && /(WebKit|CriOS|FxiOS|OPiOS|mercury)/i.test(userAgent);
+};
+
function getResults(canvas, options) {
let uri;
if (options) {
@@ -21,16 +29,49 @@ function getResults(canvas, options) {
base64: uri.replace(/^data:image\/\w+;base64,/, ''),
};
}
+
+function getAdjustedCanvasSize(originalWidth, originalHeight) {
+ if(!isMobileIOS()) return { width: originalWidth, height: originalHeight };
+
+ const aspectRatio = originalWidth / originalHeight;
+ let newWidth;
+ let newHeight;
+
+ if (originalWidth <= SAFARI_MOBILE_CANVAS_LIMIT && originalHeight <= SAFARI_MOBILE_CANVAS_LIMIT) {
+ return { width: originalWidth, height: originalHeight };
+ }
+
+ if (aspectRatio > 1) {
+ newWidth = SAFARI_MOBILE_CANVAS_LIMIT;
+ newHeight = Math.round(newWidth / aspectRatio);
+ } else {
+ newHeight = SAFARI_MOBILE_CANVAS_LIMIT;
+ newWidth = Math.round(newHeight * aspectRatio);
+ }
+
+ if (newWidth > SAFARI_MOBILE_CANVAS_LIMIT) {
+ newWidth = SAFARI_MOBILE_CANVAS_LIMIT;
+ newHeight = Math.round(newWidth / aspectRatio);
+ } else if (newHeight > SAFARI_MOBILE_CANVAS_LIMIT) {
+ newHeight = SAFARI_MOBILE_CANVAS_LIMIT;
+ newWidth = Math.round(newHeight * aspectRatio);
+ }
+
+ return { width: newWidth, height: newHeight };
+}
+
function loadImageAsync(uri) {
return new Promise((resolve, reject) => {
const imageSource = new Image();
imageSource.crossOrigin = 'anonymous';
const canvas = document.createElement('canvas');
imageSource.onload = () => {
- canvas.width = imageSource.naturalWidth;
- canvas.height = imageSource.naturalHeight;
+ const adjudstedCanvasSize = getAdjustedCanvasSize(imageSource.naturalWidth, imageSource.naturalHeight);
+
+ canvas.width = adjudstedCanvasSize.width;
+ canvas.height = adjudstedCanvasSize.height;
const context = getContext(canvas);
- context.drawImage(imageSource, 0, 0, imageSource.naturalWidth, imageSource.naturalHeight);
+ context.drawImage(imageSource, 0, 0, adjudstedCanvasSize.width, adjudstedCanvasSize.height);
resolve(canvas);
};
imageSource.onerror = () => reject(canvas);
11 changes: 11 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {Unit} from './types/onyx/Policy';
type RateAndUnit = {
unit: Unit;
rate: number;
currency: string;
};
type CurrencyDefaultMileageRate = Record<string, RateAndUnit>;

Expand Down Expand Up @@ -102,6 +103,7 @@ const CONST = {
BACKGROUND_IMAGE_TRANSITION_DURATION: 1000,
SCREEN_TRANSITION_END_TIMEOUT: 1000,
ARROW_HIDE_DELAY: 3000,
MAX_IMAGE_CANVAS_AREA: 16777216,

API_ATTACHMENT_VALIDATIONS: {
// 24 megabytes in bytes, this is limit set on servers, do not update without wider internal discussion
Expand Down Expand Up @@ -143,6 +145,8 @@ const CONST = {

LOGO_MAX_SCALE: 1.5,

MAX_IMAGE_DIMENSION: 2400,

BREADCRUMB_TYPE: {
ROOT: 'root',
STRONG: 'strong',
Expand Down Expand Up @@ -974,6 +978,7 @@ const CONST = {
SEARCH_OPTION_LIST_DEBOUNCE_TIME: 300,
RESIZE_DEBOUNCE_TIME: 100,
UNREAD_UPDATE_DEBOUNCE_TIME: 300,
SEARCH_FILTER_OPTIONS: 'search_filter_options',
},
PRIORITY_MODE: {
GSD: 'gsd',
Expand Down Expand Up @@ -1119,6 +1124,11 @@ const CONST = {
// It's copied here so that the same regex pattern can be used in form validations to be consistent with the server.
VALIDATE_FOR_HTML_TAG_REGEX: /<([^>\s]+)(?:[^>]*?)>/g,

// The regex below is used to remove dots only from the local part of the user email (local-part@domain)
// so when we are using search, we can match emails that have dots without explicitly writing the dots (e.g: fistlast@domain will match first.last@domain)
// More info https://github.com/Expensify/App/issues/8007
EMAIL_SEARCH_REGEX: /\.(?=[^\s@]*@)/g,

VALIDATE_FOR_LEADINGSPACES_HTML_TAG_REGEX: /<([\s]+.+[\s]*)>/g,

WHITELISTED_TAGS: [/<>/, /< >/, /<->/, /<-->/, /<br>/, /<br\/>/],
Expand Down Expand Up @@ -2507,6 +2517,7 @@ const CONST = {
CATEGORY: 'category',
RECEIPT: 'receipt',
DISTANCE: 'distance',
DISTANCE_RATE: 'distanceRate',
TAG: 'tag',
TAX_RATE: 'taxRate',
TAX_AMOUNT: 'taxAmount',
Expand Down
3 changes: 3 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ const ONYXKEYS = {
SAGE_INTACCT_DIMENSION_TYPE_FORM_DRAFT: 'sageIntacctDimensionTypeFormDraft',
SEARCH_ADVANCED_FILTERS_FORM: 'searchAdvancedFiltersForm',
SEARCH_ADVANCED_FILTERS_FORM_DRAFT: 'searchAdvancedFiltersFormDraft',
TEXT_PICKER_MODAL_FORM: 'textPickerModalForm',
TEXT_PICKER_MODAL_FORM_DRAFT: 'textPickerModalFormDraft',
},
} as const;

Expand Down Expand Up @@ -681,6 +683,7 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.NETSUITE_CUSTOM_FORM_ID_FORM]: FormTypes.NetSuiteCustomFormIDForm;
[ONYXKEYS.FORMS.SAGE_INTACCT_DIMENSION_TYPE_FORM]: FormTypes.SageIntacctDimensionForm;
[ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM]: FormTypes.SearchAdvancedFiltersForm;
[ONYXKEYS.FORMS.TEXT_PICKER_MODAL_FORM]: FormTypes.TextPickerModalForm;
};

type OnyxFormDraftValuesMapping = {
Expand Down
3 changes: 3 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ const ROUTES = {

SEARCH_ADVANCED_FILTERS_STATUS: 'search/filters/status',

SEARCH_ADVANCED_FILTERS_CURRENCY: 'search/filters/currency',

SEARCH_ADVANCED_FILTERS_MERCHANT: 'search/filters/merchant',

SEARCH_ADVANCED_FILTERS_DESCRIPTION: 'search/filters/description',

SEARCH_ADVANCED_FILTERS_REPORT_ID: 'search/filters/reportID',

SEARCH_ADVANCED_FILTERS_CATEGORY: 'search/filters/category',
SEARCH_ADVANCED_FILTERS_CARD: 'search/filters/card',

SEARCH_REPORT: {
route: 'search/view/:reportID',
Expand Down
2 changes: 2 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ const SCREENS = {
ADVANCED_FILTERS_DATE_RHP: 'Search_Advanced_Filters_Date_RHP',
ADVANCED_FILTERS_TYPE_RHP: 'Search_Advanced_Filters_Type_RHP',
ADVANCED_FILTERS_STATUS_RHP: 'Search_Advanced_Filters_Status_RHP',
ADVANCED_FILTERS_CURRENCY_RHP: 'Search_Advanced_Filters_Currency_RHP',
ADVANCED_FILTERS_DESCRIPTION_RHP: 'Search_Advanced_Filters_Description_RHP',
ADVANCED_FILTERS_MERCHANT_RHP: 'Search_Advanced_Filters_Merchant_RHP',
ADVANCED_FILTERS_REPORT_ID_RHP: 'Search_Advanced_Filters_ReportID_RHP',
ADVANCED_FILTERS_CATEGORY_RHP: 'Search_Advanced_Filters_Category_RHP',
ADVANCED_FILTERS_CARD_RHP: 'Search_Advanced_Filters_Card_RHP',
TRANSACTION_HOLD_REASON_RHP: 'Search_Transaction_Hold_Reason_RHP',
BOTTOM_TAB: 'Search_Bottom_Tab',
},
Expand Down
Loading

0 comments on commit 0ed014d

Please sign in to comment.