Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into ts-migration/assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
BrtqKr committed Mar 26, 2024
2 parents e7eb08b + c5f1a97 commit 431dc3f
Show file tree
Hide file tree
Showing 40 changed files with 401 additions and 231 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ There are three ways you can change the report layout under the Details section

# How to retract your report (Undo Submit)

As long as the report is still in a Processing state, you can retract this submission to put the report back to Draft status to make corrections and re-submit.
You can edit expenses on a report in a **Processing** state so long as it hasn't been approved yet. If a report has been through a level of approval and is still in the **Processing** state, you can retract this submission to put the report back to Draft status to make corrections and re-submit.

To retract a **Processing** report on the web app, click the Undo Submit button at the upper left-hand corner of the report.

Expand Down
1 change: 0 additions & 1 deletion package-lock.json

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

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
"@expensify/react-native-live-markdown": "0.1.5",
"@expo/metro-runtime": "~3.1.1",
"@formatjs/intl-datetimeformat": "^6.10.0",
"@formatjs/intl-getcanonicallocales": "^2.2.0",
"@formatjs/intl-listformat": "^7.2.2",
"@formatjs/intl-locale": "^3.3.0",
"@formatjs/intl-numberformat": "^8.5.0",
Expand Down Expand Up @@ -155,8 +154,8 @@
"react-native-plaid-link-sdk": "10.8.0",
"react-native-qrcode-svg": "^6.2.0",
"react-native-quick-sqlite": "^8.0.0-beta.2",
"react-native-release-profiler": "^0.1.6",
"react-native-reanimated": "^3.7.2",
"react-native-release-profiler": "^0.1.6",
"react-native-render-html": "6.3.1",
"react-native-safe-area-context": "4.8.2",
"react-native-screens": "3.29.0",
Expand Down
2 changes: 1 addition & 1 deletion src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2974,7 +2974,7 @@ const CONST = {
CURRENCY: 'XAF',
FORMAT: 'symbol',
SAMPLE_INPUT: '123456.789',
EXPECTED_OUTPUT: 'FCFA 123,457',
EXPECTED_OUTPUT: 'FCFA 123,457',
},

PATHS_TO_TREAT_AS_EXTERNAL: ['NewExpensify.dmg', 'docs/index.html'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,75 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import type {RefObject} from 'react';
import React from 'react';
import type {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import useLocalize from '@hooks/useLocalize';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import iouReportPropTypes from '@pages/iouReportPropTypes';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {AnchorPosition} from '@src/styles';
import type {Report, Session} from '@src/types/onyx';
import type AnchorAlignment from '@src/types/utils/AnchorAlignment';
import type {EmptyObject} from '@src/types/utils/EmptyObject';
import * as Expensicons from './Icon/Expensicons';
import type {PaymentMethod} from './KYCWall/types';
import PopoverMenu from './PopoverMenu';
import refPropTypes from './refPropTypes';

const propTypes = {
type AddPaymentMethodMenuOnyxProps = {
/** Session info for the currently logged-in user. */
session: OnyxEntry<Session>;
};

type AddPaymentMethodMenuProps = AddPaymentMethodMenuOnyxProps & {
/** Should the component be visible? */
isVisible: PropTypes.bool.isRequired,
isVisible: boolean;

/** Callback to execute when the component closes. */
onClose: PropTypes.func.isRequired,
onClose: () => void;

/** Callback to execute when the payment method is selected. */
onItemSelected: PropTypes.func.isRequired,
onItemSelected: (paymentMethod: PaymentMethod) => void;

/** The IOU/Expense report we are paying */
iouReport: iouReportPropTypes,
iouReport?: OnyxEntry<Report> | EmptyObject;

/** Anchor position for the AddPaymentMenu. */
anchorPosition: PropTypes.shape({
horizontal: PropTypes.number,
vertical: PropTypes.number,
}),
anchorPosition: AnchorPosition;

/** Where the popover should be positioned relative to the anchor points. */
anchorAlignment: PropTypes.shape({
horizontal: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL)),
vertical: PropTypes.oneOf(_.values(CONST.MODAL.ANCHOR_ORIGIN_VERTICAL)),
}),
anchorAlignment?: AnchorAlignment;

/** Popover anchor ref */
anchorRef: refPropTypes,

/** Session info for the currently logged in user. */
session: PropTypes.shape({
/** Currently logged in user accountID */
accountID: PropTypes.number,
}),
anchorRef: RefObject<View | HTMLDivElement>;

/** Whether the personal bank account option should be shown */
shouldShowPersonalBankAccountOption: PropTypes.bool,
shouldShowPersonalBankAccountOption?: boolean;
};

const defaultProps = {
iouReport: {},
anchorPosition: {},
anchorAlignment: {
function AddPaymentMethodMenu({
isVisible,
onClose,
anchorPosition,
anchorAlignment = {
horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT,
vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM,
},
anchorRef: () => {},
session: {},
shouldShowPersonalBankAccountOption: false,
};

function AddPaymentMethodMenu({isVisible, onClose, anchorPosition, anchorAlignment, anchorRef, iouReport, onItemSelected, session, shouldShowPersonalBankAccountOption}) {
anchorRef,
iouReport,
onItemSelected,
session,
shouldShowPersonalBankAccountOption = false,
}: AddPaymentMethodMenuProps) {
const {translate} = useLocalize();

// Users can choose to pay with business bank account in case of Expense reports or in case of P2P IOU report
// which then starts a bottom up flow and creates a Collect workspace where the payer is an admin and payee is an employee.
const isIOUReport = ReportUtils.isIOUReport(iouReport ?? {});
const canUseBusinessBankAccount =
ReportUtils.isExpenseReport(iouReport) ||
(ReportUtils.isIOUReport(iouReport) && !ReportActionsUtils.hasRequestFromCurrentAccount(lodashGet(iouReport, 'reportID', 0), lodashGet(session, 'accountID', 0)));
ReportUtils.isExpenseReport(iouReport ?? {}) || (isIOUReport && !ReportActionsUtils.hasRequestFromCurrentAccount(iouReport?.reportID ?? '', session?.accountID ?? 0));

const canUsePersonalBankAccount = shouldShowPersonalBankAccountOption || ReportUtils.isIOUReport(iouReport);
const canUsePersonalBankAccount = shouldShowPersonalBankAccountOption || isIOUReport;

return (
<PopoverMenu
Expand Down Expand Up @@ -116,11 +113,9 @@ function AddPaymentMethodMenu({isVisible, onClose, anchorPosition, anchorAlignme
);
}

AddPaymentMethodMenu.propTypes = propTypes;
AddPaymentMethodMenu.defaultProps = defaultProps;
AddPaymentMethodMenu.displayName = 'AddPaymentMethodMenu';

export default withOnyx({
export default withOnyx<AddPaymentMethodMenuProps, AddPaymentMethodMenuOnyxProps>({
session: {
key: ONYXKEYS.SESSION,
},
Expand Down
7 changes: 6 additions & 1 deletion src/components/ContextMenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {ForwardedRef} from 'react';
import React, {forwardRef, useImperativeHandle} from 'react';
import type {GestureResponderEvent, StyleProp, ViewStyle} from 'react-native';
import type {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native';
import useStyleUtils from '@hooks/useStyleUtils';
import useThemeStyles from '@hooks/useThemeStyles';
import useThrottledButtonState from '@hooks/useThrottledButtonState';
Expand Down Expand Up @@ -46,6 +46,9 @@ type ContextMenuItemProps = {
wrapperStyle?: StyleProp<ViewStyle>;

shouldPreventDefaultFocusOnPress?: boolean;

/** The ref of mini context menu item */
buttonRef?: React.RefObject<View>;
};

type ContextMenuItemHandle = {
Expand All @@ -66,6 +69,7 @@ function ContextMenuItem(
shouldLimitWidth = true,
wrapperStyle,
shouldPreventDefaultFocusOnPress = true,
buttonRef = {current: null},
}: ContextMenuItemProps,
ref: ForwardedRef<ContextMenuItemHandle>,
) {
Expand Down Expand Up @@ -94,6 +98,7 @@ function ContextMenuItem(

return isMini ? (
<BaseMiniContextMenuItem
ref={buttonRef}
tooltipText={itemText}
onPress={triggerPressAndUpdateSuccess}
isDelayButtonStateComplete={!isThrottledButtonActive}
Expand Down
24 changes: 22 additions & 2 deletions src/components/EmojiPicker/EmojiPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const EmojiPicker = forwardRef((props, ref) => {
const [emojiPopoverAnchorOrigin, setEmojiPopoverAnchorOrigin] = useState(DEFAULT_ANCHOR_ORIGIN);
const [activeID, setActiveID] = useState();
const emojiPopoverAnchorRef = useRef(null);
const emojiAnchorDimension = useRef({
width: 0,
height: 0,
});
const onModalHide = useRef(() => {});
const onEmojiSelected = useRef(() => {});
const activeEmoji = useRef();
Expand Down Expand Up @@ -76,7 +80,14 @@ const EmojiPicker = forwardRef((props, ref) => {
// eslint-disable-next-line es/no-optional-chaining
onWillShow?.();
setIsEmojiPickerVisible(true);
setEmojiPopoverAnchorPosition(value);
setEmojiPopoverAnchorPosition({
horizontal: value.horizontal,
vertical: value.vertical,
});
emojiAnchorDimension.current = {
width: value.width,
height: value.height,
};
setEmojiPopoverAnchorOrigin(anchorOriginValue);
setActiveID(id);
});
Expand Down Expand Up @@ -155,7 +166,14 @@ const EmojiPicker = forwardRef((props, ref) => {
return;
}
calculateAnchorPosition(emojiPopoverAnchor.current, emojiPopoverAnchorOrigin).then((value) => {
setEmojiPopoverAnchorPosition(value);
setEmojiPopoverAnchorPosition({
horizontal: value.horizontal,
vertical: value.vertical,
});
emojiAnchorDimension.current = {
width: value.width,
height: value.height,
};
});
});
return () => {
Expand Down Expand Up @@ -192,7 +210,9 @@ const EmojiPicker = forwardRef((props, ref) => {
anchorAlignment={emojiPopoverAnchorOrigin}
outerStyle={StyleUtils.getOuterModalStyle(windowHeight, props.viewportOffsetTop)}
innerContainerStyle={styles.popoverInnerContainer}
anchorDimensions={emojiAnchorDimension.current}
avoidKeyboard
shoudSwitchPositionIfOverflow
>
<EmojiPickerMenu
onEmojiSelected={selectEmoji}
Expand Down
22 changes: 20 additions & 2 deletions src/components/PopoverWithMeasuredContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import PopoverWithMeasuredContentUtils from '@libs/PopoverWithMeasuredContentUtils';
import CONST from '@src/CONST';
import type {AnchorPosition} from '@src/styles';
import type {AnchorDimensions, AnchorPosition} from '@src/styles';
import Popover from './Popover';
import type {PopoverProps} from './Popover/types';
import type {WindowDimensionsProps} from './withWindowDimensions/types';
Expand All @@ -15,6 +15,12 @@ type PopoverWithMeasuredContentProps = Omit<PopoverProps, 'anchorPosition' | key
/** The horizontal and vertical anchors points for the popover */
anchorPosition: AnchorPosition;

/** The dimension of anchor component */
anchorDimensions?: AnchorDimensions;

/** Whether we should change the vertical position if the popover's position is overflow */
shoudSwitchPositionIfOverflow?: boolean;

/** Whether handle navigation back when modal show. */
shouldHandleNavigationBack?: boolean;
};
Expand Down Expand Up @@ -45,6 +51,11 @@ function PopoverWithMeasuredContent({
statusBarTranslucent = true,
avoidKeyboard = false,
hideModalContentWhileAnimating = false,
anchorDimensions = {
height: 0,
width: 0,
},
shoudSwitchPositionIfOverflow = false,
shouldHandleNavigationBack = false,
...props
}: PopoverWithMeasuredContentProps) {
Expand Down Expand Up @@ -114,11 +125,18 @@ function PopoverWithMeasuredContent({
}, [anchorPosition, anchorAlignment, popoverWidth, popoverHeight]);

const horizontalShift = PopoverWithMeasuredContentUtils.computeHorizontalShift(adjustedAnchorPosition.left, popoverWidth, windowWidth);
const verticalShift = PopoverWithMeasuredContentUtils.computeVerticalShift(adjustedAnchorPosition.top, popoverHeight, windowHeight);
const verticalShift = PopoverWithMeasuredContentUtils.computeVerticalShift(
adjustedAnchorPosition.top,
popoverHeight,
windowHeight,
anchorDimensions.height,
shoudSwitchPositionIfOverflow,
);
const shiftedAnchorPosition = {
left: adjustedAnchorPosition.left + horizontalShift,
bottom: windowHeight - (adjustedAnchorPosition.top + popoverHeight) - verticalShift,
};

return isContentMeasured ? (
<Popover
shouldHandleNavigationBack={shouldHandleNavigationBack}
Expand Down
2 changes: 2 additions & 0 deletions src/components/SelectionList/BaseListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function BaseListItem<TItem extends ListItem>({
item,
pressableStyle,
wrapperStyle,
containerStyle,
selectMultipleStyle,
isDisabled = false,
shouldPreventDefaultFocusOnSelectRow = false,
Expand Down Expand Up @@ -62,6 +63,7 @@ function BaseListItem<TItem extends ListItem>({
pendingAction={pendingAction}
errors={errors}
errorRowStyles={styles.ph5}
style={containerStyle}
>
<PressableWithFeedback
// eslint-disable-next-line react/jsx-props-no-spreading
Expand Down
1 change: 1 addition & 0 deletions src/components/SelectionList/TableListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function TableListItem({
item={item}
pressableStyle={[[styles.selectionListPressableItemWrapper, item.isSelected && styles.activeComponentBG, isFocused && styles.sidebarLinkActive]]}
wrapperStyle={[styles.flexRow, styles.flex1, styles.justifyContentBetween, styles.userSelectNone, styles.alignItemsCenter]}
containerStyle={styles.mb3}
selectMultipleStyle={[StyleUtils.getCheckboxContainerStyle(20), StyleUtils.getMultiselectListStyles(!!item.isSelected, !!item.isDisabled)]}
isFocused={isFocused}
isDisabled={isDisabled}
Expand Down
3 changes: 3 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type CommonListItemProps<TItem> = {
/** Styles for the wrapper view */
wrapperStyle?: StyleProp<ViewStyle>;

/** Styles for the container view */
containerStyle?: StyleProp<ViewStyle>;

/** Styles for the checkbox wrapper view if select multiple option is on */
selectMultipleStyle?: StyleProp<ViewStyle>;

Expand Down
2 changes: 1 addition & 1 deletion src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ export default {
recordDistance: 'Record Distance',
requestMoney: 'Request Money',
splitBill: 'Split Bill',
splitReceipt: 'Split Receipt',
splitScan: 'Split Receipt',
splitDistance: 'Split Distance',
sendMoney: 'Send Money',
assignTask: 'Assign Task',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ export default {
recordDistance: 'Grabar Distancia',
requestMoney: 'Solicitar Dinero',
splitBill: 'Dividir Cuenta',
splitReceipt: 'Dividir Recibo',
splitScan: 'Dividir Recibo',
splitDistance: 'Dividir Distancia',
sendMoney: 'Enviar Dinero',
assignTask: 'Assignar Tarea',
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/SendMoneyParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type SendMoneyParams = {
newIOUReportDetails: string;
createdReportActionID: string;
reportPreviewReportActionID: string;
createdIOUReportActionID: string;
transactionThreadReportID: string;
createdReportActionIDForThread: string;
};
Expand Down
17 changes: 17 additions & 0 deletions src/libs/IntlPolyfill/index.android.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import polyfillListFormat from './polyfillListFormat';
import type IntlPolyfill from './types';

/**
* Polyfill the Intl API, always performed for native devices.
*/
const intlPolyfill: IntlPolyfill = () => {
// Native devices require extra polyfills which are
// not yet implemented in hermes.
// see support: https://hermesengine.dev/docs/intl/

require('@formatjs/intl-locale/polyfill');

polyfillListFormat();
};

export default intlPolyfill;
Loading

0 comments on commit 431dc3f

Please sign in to comment.