Skip to content

Commit

Permalink
Merge branch 'main' into fix/issue-29049
Browse files Browse the repository at this point in the history
  • Loading branch information
sangar-1028 committed Feb 20, 2024
2 parents 7df8784 + a9d1683 commit d5eee76
Show file tree
Hide file tree
Showing 65 changed files with 1,018 additions and 996 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/reassurePerformanceTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup NodeJS
uses: ./.github/actions/composite/setupNode
Expand All @@ -22,6 +24,22 @@ jobs:
git config --global user.email "[email protected]"
git config --global user.name "Test"
- name: Get common ancestor commit
run: |
git fetch origin main
common_ancestor=$(git merge-base "${{ github.sha }}" origin/main)
echo "COMMIT_HASH=$common_ancestor" >> "$GITHUB_ENV"
- name: Clean up deleted files
run: |
DELETED_FILES=$(git diff --name-only --diff-filter=D "$COMMIT_HASH" "${{ github.sha }}")
for file in $DELETED_FILES; do
if [ -n "$file" ]; then
rm -f "$file"
echo "Deleted file: $file"
fi
done
- name: Run performance testing script
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ For an M1 Mac, read this [SO](https://stackoverflow.com/questions/64901180/how-t
* To run a on a **Development Simulator**: `npm run ios`
* Changes applied to Javascript will be applied automatically, any changes to native code will require a recompile

If you want to run the app on an actual physical iOS device, please follow the instructions [here](https://github.com/Expensify/App/blob/docs/how-to-build-app-on-physcial-device/contributingGuides/HOW_TO_BUILD_APP_ON_PHYSICAL_IOS_DEVICE.md).
If you want to run the app on an actual physical iOS device, please follow the instructions [here](https://github.com/Expensify/App/blob/main/contributingGuides/HOW_TO_BUILD_APP_ON_PHYSICAL_IOS_DEVICE.md).

## Running the Android app 🤖
* Before installing Android dependencies, you need to obtain a token from Mapbox to download their SDKs. Please run `npm run configure-mapbox` and follow the instructions. If you already did this step for iOS, there is no need to repeat this step.
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001044204
versionName "1.4.42-4"
versionCode 1001044302
versionName "1.4.43-2"
}

flavorDimensions "default"
Expand Down
14 changes: 7 additions & 7 deletions desktop/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 desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"electron-context-menu": "^2.3.0",
"electron-log": "^4.4.8",
"electron-serve": "^1.3.0",
"electron-updater": "^6.1.7",
"electron-updater": "^6.1.8",
"node-machine-id": "^1.1.12"
},
"author": "Expensify, Inc.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,16 @@ The card will only appear in the drop-down list for assignment once it’s activ
# Troubleshooting issues assigning company cards

## Why do bank connections break?
Banks often make changes to safeguard your confidential information, and when they do, we need to update the connection between Expensify and the bank. We have a team of engineers that works closely with banks to monitor this and update our software accordingly when this happens.
Banks often make changes to safeguard your confidential information, and when they do, we need to update the connection between Expensify and the bank. We have a team of engineers who work closely with banks to monitor this and update our software accordingly when this happens.
The first step is to check if there have been any changes to your bank information. Have you recently changed your banking password without updating it in Expensify? Has your banking username or card number been updated? Did you update your security questions for your bank?
If you've answered "yes" to any of these questions, a Domain Admins need to update this information in Expensify and manually reestablish the connection by heading to *Settings* > *Domains* > _Domain Name_ > *Company Cards* > *Fix*. The Domain Admin will be prompted to enter the new credentials/updated information and this should reestablish the connection.
If you've answered "yes" to any of these questions, a Domain Admins need to update this information in Expensify and manually re-establish the connection by heading to *Settings* > *Domains* > _Domain Name_ > *Company Cards* > *Fix*. The Domain Admin will be prompted to enter the new credentials/updated information and this should reestablish the connection.

## How do I resolve errors while I’m trying to import my card?*
Make sure you're importing your card in the correct spot in Expensify and selecting the right bank connection. For company cards, use the master administrative credentials to import your set of cards at *Settings* > *Domains* > _Domain Name_ > *Company Cards* > *Import Card*.
Please note there are some things that cannot be bypassed within Expensify, including two-factor authentication being enabled within your bank account. This will prevent the connection from remaining stable and will need to be turned off on the bank side.

## What are the most reliable bank connections in Expensify?*
The most reliable corporate card to use with Expensify is the Expensify Card. We offer daily settlement, unapproved expense limits, and real-time compliance for secure and efficient spending, as well as 2% cash back. Click here to learn more or apply.
The most reliable corporate card to use with Expensify is the Expensify Visa® Commercial Card. We offer daily settlement, unapproved expense limits, and real-time compliance for secure and efficient spending, as well as 2% cash back (_Applies to USD purchases only._) Click here to learn more or apply.
Additionally, we've teamed up with major banks worldwide to ensure a smooth import of credit card transactions into your accounts. Corporate cards from the following banks also offer the most dependable connections in Expensify:
- American Express
- Bank of America
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ As mentioned above, we’ll be able to pull in transactions as they post (daily)
Expensify provides a corporate card with the following features:

- Up to 2% cash back (_Applies to USD purchases only._)
- [SmartLimits]([https://help.expensify.com/articles/expensify-classic/expensify-card/Card-Settings](https://community.expensify.com/discussion/4851/deep-dive-what-are-smart-limits?utm_source=community-search&utm_medium=organic-search&utm_term=smart+limits)) to control what each individual cardholder can spend
- [SmartLimits](https://help.expensify.com/articles/expensify-classic/expensify-card/Cardholder-Settings-and-Features) to control what each individual cardholder can spend
- A stable, unbreakable real-time connection (third-party bank feeds can run into connectivity issues)
- Receipt compliance - informing notifications (e.g. add a receipt!) for users *as soon as the card is swiped*
- Unlimited Virtual Cards - single-purpose cards with a fixed or monthly limit for specific company purchases
Expand Down
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>1.4.42</string>
<string>1.4.43</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand All @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>1.4.42.4</string>
<string>1.4.43.2</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</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>1.4.42</string>
<string>1.4.43</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.4.42.4</string>
<string>1.4.43.2</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>1.4.42</string>
<string>1.4.43</string>
<key>CFBundleVersion</key>
<string>1.4.42.4</string>
<string>1.4.43.2</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": "1.4.42-4",
"version": "1.4.43-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.",
Expand Down
5 changes: 4 additions & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const keyInputRightArrow = KeyCommand?.constants?.keyInputRightArrow ?? 'keyInpu
// describes if a shortcut key can cause navigation
const KEYBOARD_SHORTCUT_NAVIGATION_TYPE = 'NAVIGATION_SHORTCUT';

// Explicit type annotation is required
const cardActiveStates: number[] = [2, 3, 4, 7];

const CONST = {
ANDROID_PACKAGE_NAME,
ANIMATED_TRANSITION: 300,
Expand Down Expand Up @@ -1441,7 +1444,7 @@ const CONST = {
CLOSED: 6,
STATE_SUSPENDED: 7,
},
ACTIVE_STATES: [2, 3, 4, 7],
ACTIVE_STATES: cardActiveStates,
},
AVATAR_ROW_SIZE: {
DEFAULT: 4,
Expand Down
15 changes: 5 additions & 10 deletions src/components/AddPaymentMethodMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import React from 'react';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import useLocalize from '@hooks/useLocalize';
import compose from '@libs/compose';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import iouReportPropTypes from '@pages/iouReportPropTypes';
Expand All @@ -13,7 +12,6 @@ import ONYXKEYS from '@src/ONYXKEYS';
import * as Expensicons from './Icon/Expensicons';
import PopoverMenu from './PopoverMenu';
import refPropTypes from './refPropTypes';
import withWindowDimensions from './withWindowDimensions';

const propTypes = {
/** Should the component be visible? */
Expand Down Expand Up @@ -122,11 +120,8 @@ AddPaymentMethodMenu.propTypes = propTypes;
AddPaymentMethodMenu.defaultProps = defaultProps;
AddPaymentMethodMenu.displayName = 'AddPaymentMethodMenu';

export default compose(
withWindowDimensions,
withOnyx({
session: {
key: ONYXKEYS.SESSION,
},
}),
)(AddPaymentMethodMenu);
export default withOnyx({
session: {
key: ONYXKEYS.SESSION,
},
})(AddPaymentMethodMenu);
2 changes: 1 addition & 1 deletion src/components/Attachments/AttachmentView/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function AttachmentView({
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const [loadComplete, setLoadComplete] = useState(false);
const isVideo = Str.isVideo(source);
const isVideo = typeof source === 'string' && Str.isVideo(source);

useEffect(() => {
if (!isFocused) {
Expand Down
50 changes: 22 additions & 28 deletions src/components/CategoryPicker/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import lodashGet from 'lodash/get';
import React, {useMemo, useState} from 'react';
import React, {useMemo} from 'react';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import OptionsSelector from '@components/OptionsSelector';
import SelectionList from '@components/SelectionList';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as OptionsListUtils from '@libs/OptionsListUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import {defaultProps, propTypes} from './categoryPickerPropTypes';

function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedCategories, onSubmit}) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [searchValue, setSearchValue] = useState('');

const policyCategoriesCount = OptionsListUtils.getEnabledCategoriesCount(_.values(policyCategories));
const isCategoriesCountBelowThreshold = policyCategoriesCount < CONST.CATEGORY_LIST_THRESHOLD;
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');

const selectedOptions = useMemo(() => {
if (!selectedCategory) {
Expand All @@ -28,17 +24,18 @@ function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedC
name: selectedCategory,
enabled: true,
accountID: null,
isSelected: true,
},
];
}, [selectedCategory]);

const sections = useMemo(() => {
const [sections, headerMessage, policyCategoriesCount, shouldShowTextInput] = useMemo(() => {
const validPolicyRecentlyUsedCategories = _.filter(policyRecentlyUsedCategories, (p) => !_.isEmpty(p));
const {categoryOptions} = OptionsListUtils.getFilteredOptions(
{},
{},
[],
searchValue,
debouncedSearchValue,
selectedOptions,
[],
false,
Expand All @@ -49,31 +46,28 @@ function CategoryPicker({selectedCategory, policyCategories, policyRecentlyUsedC
false,
);

return categoryOptions;
}, [policyCategories, policyRecentlyUsedCategories, searchValue, selectedOptions]);
const header = OptionsListUtils.getHeaderMessageForNonUserList(lodashGet(categoryOptions, '[0].data', []).length > 0, debouncedSearchValue);
const policiesCount = OptionsListUtils.getEnabledCategoriesCount(_.values(policyCategories));
const isCategoriesCountBelowThreshold = policyCategoriesCount < CONST.CATEGORY_LIST_THRESHOLD;
const showInput = !isCategoriesCountBelowThreshold;

return [categoryOptions, header, policiesCount, showInput];
}, [policyCategories, policyRecentlyUsedCategories, debouncedSearchValue, selectedOptions]);

const headerMessage = OptionsListUtils.getHeaderMessageForNonUserList(lodashGet(sections, '[0].data.length', 0) > 0, searchValue);
const shouldShowTextInput = !isCategoriesCountBelowThreshold;
const selectedOptionKey = lodashGet(_.filter(lodashGet(sections, '[0].data', []), (category) => category.searchText === selectedCategory)[0], 'keyForList');
const selectedOptionKey = useMemo(
() => lodashGet(_.filter(lodashGet(sections, '[0].data', []), (category) => category.searchText === selectedCategory)[0], 'keyForList'),
[sections, selectedCategory],
);

return (
<OptionsSelector
optionHoveredStyle={styles.hoveredComponentBG}
sectionHeaderStyle={styles.mt5}
<SelectionList
sections={sections}
selectedOptions={selectedOptions}
// Focus the first option when searching
focusedIndex={0}
// Focus the selected option on first load
initiallyFocusedOptionKey={selectedOptionKey}
headerMessage={headerMessage}
shouldShowTextInput={shouldShowTextInput}
textInputLabel={translate('common.search')}
boldStyle
highlightSelectedOptions
isRowMultilineSupported
textInputValue={searchValue}
textInputLabel={shouldShowTextInput && translate('common.search')}
onChangeText={setSearchValue}
onSelectRow={onSubmit}
initiallyFocusedOptionKey={selectedOptionKey}
/>
);
}
Expand Down
11 changes: 9 additions & 2 deletions src/components/EmojiPicker/EmojiSkinToneList.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useCallback, useState} from 'react';
import React, {useCallback, useEffect, useState} from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import * as Emojis from '@assets/emojis';
Expand Down Expand Up @@ -27,11 +27,18 @@ function EmojiSkinToneList() {
* @param {object} skinToneEmoji
*/
function updateSelectedSkinTone(skinToneEmoji) {
toggleIsSkinToneListVisible();
setHighlightedIndex(skinToneEmoji.skinTone);
setPreferredSkinTone(skinToneEmoji.skinTone);
}

useEffect(() => {
if (!isSkinToneListVisible) {
return;
}
toggleIsSkinToneListVisible();
// eslint-disable-next-line react-hooks/exhaustive-deps -- only run when preferredSkinTone updates
}, [preferredSkinTone]);

const currentSkinTone = getSkinToneEmojiFromIndex(preferredSkinTone);
return (
<View style={[styles.flexRow, styles.p3, styles.ph4, styles.emojiPickerContainer]}>
Expand Down
1 change: 0 additions & 1 deletion src/components/KYCWall/BaseKYCWall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ function KYCWall({
return (
<>
<AddPaymentMethodMenu
// @ts-expect-error TODO: Remove this once AddPaymentMethodMenu (https://github.com/Expensify/App/issues/25073) is migrated to TypeScript.
isVisible={shouldShowAddPaymentMenu}
iouReport={iouReport}
onClose={() => setShouldShowAddPaymentMenu(false)}
Expand Down
4 changes: 2 additions & 2 deletions src/components/KYCWall/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type KYCWallProps = {
onSuccessfulKYC: (iouPaymentType?: PaymentMethodType, currentSource?: Source) => void;

/** Children to build the KYC */
children: (continueAction: (event: GestureResponderEvent | KeyboardEvent | undefined, method: PaymentMethodType) => void, anchorRef: RefObject<View>) => void;
children: (continueAction: (event: GestureResponderEvent | KeyboardEvent | undefined, method?: PaymentMethodType) => void, anchorRef: RefObject<View>) => void;
};

export type {AnchorPosition, KYCWallProps, PaymentMethod, DomRect};
export type {AnchorPosition, KYCWallProps, PaymentMethod, DomRect, PaymentMethodType, Source};
Loading

0 comments on commit d5eee76

Please sign in to comment.