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
21 changes: 20 additions & 1 deletion src/components/Search/SearchList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef,
import type {ForwardedRef} from 'react';
import {View} from 'react-native';
import type {FlatList, ListRenderItemInfo, NativeSyntheticEvent, StyleProp, ViewStyle, ViewToken} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import Animated from 'react-native-reanimated';
import type {FlatListPropsWithLayout} from 'react-native-reanimated';
import Checkbox from '@components/Checkbox';
Expand All @@ -28,6 +29,7 @@ import {isMobileChrome} from '@libs/Browser';
import {addKeyDownPressListener, removeKeyDownPressListener} from '@libs/KeyboardShortcut/KeyDownPressListener';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

type SearchListItem = TransactionListItemType | ReportListItemType | ReportActionListItemType;
type SearchListItemComponentType = typeof TransactionListItem | typeof ChatListItem | typeof ReportListItem;
Expand Down Expand Up @@ -125,6 +127,10 @@ function SearchList(
// Keep track of the number of selected items to determine if we should turn off selection mode
const selectionRef = useRef(0);

const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {
canBeMissing: true,
});

useEffect(() => {
selectionRef.current = selectedItemsLength;

Expand Down Expand Up @@ -311,10 +317,23 @@ function SearchList(
}}
shouldPreventDefaultFocusOnSelectRow={shouldPreventDefaultFocusOnSelectRow}
queryJSONHash={queryJSONHash}
policies={policies}
/>
);
},
[ListItem, canSelectMultiple, focusedIndex, handleLongPressRow, itemsToHighlight, onCheckboxPress, onSelectRow, queryJSONHash, setFocusedIndex, shouldPreventDefaultFocusOnSelectRow],
[
ListItem,
canSelectMultiple,
focusedIndex,
handleLongPressRow,
itemsToHighlight,
onCheckboxPress,
onSelectRow,
policies,
queryJSONHash,
setFocusedIndex,
shouldPreventDefaultFocusOnSelectRow,
],
);

return (
Expand Down
7 changes: 6 additions & 1 deletion src/components/SelectionList/ChatListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ function ChatListItem<TItem extends ListItem>({
onFocus,
onLongPressRow,
shouldSyncFocus,
policies,
}: ChatListItemProps<TItem>) {
const reportActionItem = item as unknown as ReportActionListItemType;
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.reportID ?? CONST.DEFAULT_NUMBER_ID}`);
const reportID = Number(reportActionItem?.reportID ?? CONST.DEFAULT_NUMBER_ID);
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {
canBeMissing: true,
});
const styles = useThemeStyles();
const theme = useTheme();
const animatedHighlightStyle = useAnimatedHighlightStyle({
Expand Down Expand Up @@ -87,6 +91,7 @@ function ChatListItem<TItem extends ListItem>({
CONST.REPORT.ACTIONS.TYPE.FORWARDED,
].some((type) => type === reportActionItem.actionName)
}
policies={policies}
/>
</BaseListItem>
);
Expand Down
5 changes: 5 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import type {
TextStyle,
ViewStyle,
} from 'react-native';
import type {OnyxCollection} from 'react-native-onyx';
import type {AnimatedStyle} from 'react-native-reanimated';
import type {SearchRouterItem} from '@components/Search/SearchAutocompleteList';
import type {SearchColumnType} from '@components/Search/types';
import type {BrickRoad} from '@libs/WorkspacesSettingsUtils';
// eslint-disable-next-line no-restricted-imports
import type CursorStyles from '@styles/utils/cursor/types';
import type CONST from '@src/CONST';
import type {Policy} from '@src/types/onyx';
import type {Attendee} from '@src/types/onyx/IOU';
import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon';
import type {SearchPersonalDetails, SearchReport, SearchReportAction, SearchTransaction} from '@src/types/onyx/SearchResults';
Expand Down Expand Up @@ -365,6 +367,9 @@ type ReportListItemProps<TItem extends ListItem> = ListItemProps<TItem> & {

type ChatListItemProps<TItem extends ListItem> = ListItemProps<TItem> & {
queryJSONHash?: number;

/** The policies which the user has access to */
policies?: OnyxCollection<Policy>;
};

type ValidListItem =
Expand Down
7 changes: 6 additions & 1 deletion src/pages/home/report/PureReportActionItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import mapValues from 'lodash/mapValues';
import React, {memo, useCallback, useContext, useEffect, useMemo, useRef, useState} from 'react';
import type {GestureResponderEvent, TextInput} from 'react-native';
import {InteractionManager, Keyboard, View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import type {Emoji} from '@assets/emojis/types';
import {AttachmentContext} from '@components/AttachmentContext';
Expand Down Expand Up @@ -333,6 +333,9 @@ type PureReportActionItemProps = {

/** A message related to a report action that has been automatically forwarded */
reportAutomaticallyForwardedMessage?: string;

/** Policies */
policies?: OnyxCollection<OnyxTypes.Policy>;
};

// This is equivalent to returning a negative boolean in normal functions, but we can keep the element return type
Expand Down Expand Up @@ -392,6 +395,7 @@ function PureReportActionItem({
dismissTrackExpenseActionableWhisper = () => {},
userBillingFundID,
reportAutomaticallyForwardedMessage,
policies,
}: PureReportActionItemProps) {
const {translate} = useLocalize();
const {shouldUseNarrowLayout} = useResponsiveLayout();
Expand Down Expand Up @@ -1227,6 +1231,7 @@ function PureReportActionItem({
hasBeenFlagged={
![CONST.MODERATION.MODERATOR_DECISION_APPROVED, CONST.MODERATION.MODERATOR_DECISION_PENDING].some((item) => item === moderationDecision) && !isPendingRemove(action)
}
policies={policies}
>
{content}
</ReportActionItemSingle>
Expand Down
21 changes: 15 additions & 6 deletions src/pages/home/report/ReportActionItemSingle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import Avatar from '@components/Avatar';
import {FallbackAvatar} from '@components/Icon/Expensicons';
import MultipleAvatars from '@components/MultipleAvatars';
Expand Down Expand Up @@ -39,7 +39,7 @@ import {
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Report, ReportAction} from '@src/types/onyx';
import type {Policy, Report, ReportAction} from '@src/types/onyx';
import type {Icon} from '@src/types/onyx/OnyxCommon';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import ReportActionItemDate from './ReportActionItemDate';
Expand Down Expand Up @@ -72,6 +72,9 @@ type ReportActionItemSingleProps = Partial<ChildrenProps> & {

/** If the action is being actived */
isActive?: boolean;

/** Policies */
policies?: OnyxCollection<Policy>;
};

const showUserDetails = (accountID: number | undefined) => {
Expand All @@ -96,20 +99,26 @@ function ReportActionItemSingle({
iouReport,
isHovered = false,
isActive = false,
policies,
}: ReportActionItemSingleProps) {
const theme = useTheme();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST);
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {
canBeMissing: true,
});
const [innerPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you clarify what innerPolicies represents? I want to make sure I fully understand its role in the context.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I can. The component is used on both the Report and Search pages, but these pages handle data differently. On the Search page, the new policy data isn’t in the snapshot until the Search API runs again. So, I pass the policies from the parent (SearchList) to make sure it has the latest data. For the Report page, I keep using the internal policies since it works fine there.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah, thanks for clarifying 👍🏼

canBeMissing: true,
});
const activePolicies = policies ?? innerPolicies;
const policy = usePolicy(report?.policyID);
const delegatePersonalDetails = action?.delegateAccountID ? personalDetails?.[action?.delegateAccountID] : undefined;
const ownerAccountID = iouReport?.ownerAccountID ?? action?.childOwnerAccountID;
const isReportPreviewAction = action?.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW;
const actorAccountID = getReportActionActorAccountID(action, iouReport, report, delegatePersonalDetails);
const [invoiceReceiverPolicy] = useOnyx(
`${ONYXKEYS.COLLECTION.POLICY}${report?.invoiceReceiver && 'policyID' in report.invoiceReceiver ? report.invoiceReceiver.policyID : CONST.DEFAULT_NUMBER_ID}`,
);
const invoiceReceiverPolicy =
report?.invoiceReceiver && 'policyID' in report.invoiceReceiver ? activePolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${report.invoiceReceiver.policyID}`] : undefined;

let displayName = getDisplayNameForParticipant({accountID: actorAccountID, personalDetailsData: personalDetails});
const {avatar, login, pendingFields, status, fallbackIcon} = personalDetails?.[actorAccountID ?? CONST.DEFAULT_NUMBER_ID] ?? {};
Expand Down