Skip to content
Merged
37 changes: 34 additions & 3 deletions src/components/ReportActionItem/MoneyRequestReceiptView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useRoute} from '@react-navigation/native';
import {hasSeenTourSelector} from '@selectors/Onboarding';
import {conciergePersonalDetailSelector, personalDetailByAccountIDSelector} from '@selectors/PersonalDetails';
import mapValues from 'lodash/mapValues';
import React, {useEffect, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
Expand Down Expand Up @@ -136,6 +137,11 @@ function MoneyRequestReceiptView({
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
const [betas] = useOnyx(ONYXKEYS.BETAS);
const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: conciergePersonalDetailSelector});
const reportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(report?.ownerAccountID), [report?.ownerAccountID]);
const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]);
const chatReportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(chatReport?.ownerAccountID), [chatReport?.ownerAccountID]);
const [chatReportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: chatReportOwnerSelector}, [chatReportOwnerSelector]);
const delegateAccountID = useDelegateAccountID();

const [isLoading, setIsLoading] = useState(true);
Expand Down Expand Up @@ -164,7 +170,8 @@ function MoneyRequestReceiptView({
const didReceiptScanSucceed = hasReceipt && didReceiptScanSucceedTransactionUtils(transaction);
const isInvoice = isInvoiceReport(moneyRequestReport);
const isChatReportArchived = useReportIsArchived(moneyRequestReport?.chatReportID);
const {login: currentUserLogin, accountID: currentUserAccountID, timezone: currentUserTimezone} = useCurrentUserPersonalDetails();
const currentUserPersonalDetail = useCurrentUserPersonalDetails();
const {login: currentUserLogin, accountID: currentUserAccountID, timezone: currentUserTimezone} = currentUserPersonalDetail;
const theme = useTheme();
const ancestors = useAncestors(report);
const {hovered, bind: hoverBind} = useHover();
Expand Down Expand Up @@ -394,7 +401,19 @@ function MoneyRequestReceiptView({
}
if (transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) {
if (chatReport?.reportID && getCreationReportErrors(chatReport)) {
navigateToConciergeChatAndDeleteReport(chatReport.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true);
navigateToConciergeChatAndDeleteReport(
chatReport.reportID,
conciergeReportID,
currentUserAccountID,
introSelected,
isSelfTourViewed,
betas,
chatReportOwnerPersonalDetail,
currentUserPersonalDetail,
conciergePersonalDetail,
true,
true,
);
return;
}
if (parentReportAction) {
Expand Down Expand Up @@ -433,7 +452,19 @@ function MoneyRequestReceiptView({
if (isInNarrowPaneModal) {
Navigation.goBack();
}
navigateToConciergeChatAndDeleteReport(report.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true);
navigateToConciergeChatAndDeleteReport(
report.reportID,
conciergeReportID,
currentUserAccountID,
introSelected,
isSelfTourViewed,
betas,
reportOwnerPersonalDetail,
currentUserPersonalDetail,
conciergePersonalDetail,
true,
true,
);
}
};

Expand Down
14 changes: 13 additions & 1 deletion src/components/ReportActionItem/TaskView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,19 @@ function TaskView({report, parentReport, action}: TaskViewProps) {
<OfflineWithFeedback
shouldShowErrorMessages
errors={report?.errorFields?.editTask ?? report?.errorFields?.createTask}
onClose={() => clearTaskErrors(report, conciergeReportID, accountID, introSelected, betas, isSelfTourViewed)}
onClose={() =>
clearTaskErrors(
report,
conciergeReportID,
accountID,
introSelected,
betas,
isSelfTourViewed,
report?.ownerAccountID ? (personalDetails?.[report.ownerAccountID] ?? undefined) : undefined,
currentUserPersonalDetails,
(personalDetails ? Object.values(personalDetails).find((detail) => detail?.login === CONST.EMAIL.CONCIERGE) : undefined) ?? undefined,
)
}
errorRowStyles={styles.ph5}
>
<Hoverable>
Expand Down
60 changes: 44 additions & 16 deletions src/libs/actions/Report/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ import type {
VisibleReportActionsDerivedValue,
} from '@src/types/onyx';
import type {Decision} from '@src/types/onyx/OriginalMessage';
import type PersonalDetails from '@src/types/onyx/PersonalDetails';
import type {CurrentUserPersonalDetails, Timezone} from '@src/types/onyx/PersonalDetails';
import type {ConnectionName} from '@src/types/onyx/Policy';
import type {NotificationPreference, Participants, Participant as ReportParticipant, RoomVisibility, WriteCapability} from '@src/types/onyx/Report';
Expand Down Expand Up @@ -482,6 +483,20 @@ Onyx.connect({
},
});

/**
* Builds a partial PersonalDetailsList containing only the records passed in. Skips entries with no accountID.
*/
function buildPersonalDetailsList(details: Array<OnyxEntry<PersonalDetails>>): PersonalDetailsList {
const result: PersonalDetailsList = {};
for (const detail of details) {
if (detail?.accountID == null) {
continue;
}
result[detail.accountID] = detail;
}
return result;
}

const typingWatchTimers: Record<string, NodeJS.Timeout> = {};

// Track subscriptions to conciergeReasoning Pusher events to avoid duplicates.
Expand Down Expand Up @@ -2344,8 +2359,7 @@ function navigateToAndOpenReportWithAccountIDs(
introSelected: OnyxEntry<IntroSelected>,
isSelfTourViewed: boolean | undefined,
betas: OnyxEntry<Beta[]>,
// TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656
personalDetails?: OnyxEntry<PersonalDetailsList>,
personalDetails: OnyxEntry<PersonalDetailsList>,
shouldRevalidateExistingChat = false,
) {
const participants = participantAccountIDs.map((accountID): ParticipantInfo => {
Expand All @@ -2372,8 +2386,7 @@ function navigateToAndOpenReportWithAccountIDs(
newReportObject: fallbackChat,
parentReportActionID: '0',
participants,
// TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656
personalDetails: personalDetails ?? allPersonalDetails,
personalDetails,
betas,
});

Expand Down Expand Up @@ -2431,9 +2444,8 @@ function navigateToAndOpenChildReport(
currentUserAccountID: number,
introSelected: OnyxEntry<IntroSelected>,
betas: OnyxEntry<Beta[]>,
personalDetails: OnyxEntry<PersonalDetailsList>,
isSelfTourViewed: boolean | undefined,
// TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656
personalDetails?: OnyxEntry<PersonalDetailsList>,
) {
const report = childReport ?? createChildReport(childReport, parentReportAction, parentReport, currentUserAccountID, introSelected, betas, isSelfTourViewed, personalDetails);

Expand Down Expand Up @@ -3428,9 +3440,8 @@ function toggleSubscribeToChildReport(
introSelected: OnyxEntry<IntroSelected>,
isSelfTourViewed: boolean | undefined,
betas: OnyxEntry<Beta[]>,
prevNotificationPreference?: NotificationPreference,
// TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656
personalDetails?: OnyxEntry<PersonalDetailsList>,
prevNotificationPreference: NotificationPreference | undefined,
personalDetails: OnyxEntry<PersonalDetailsList>,
) {
if (childReportID) {
openReport({reportID: childReportID, introSelected, betas, isSelfTourViewed});
Expand Down Expand Up @@ -3474,8 +3485,7 @@ function toggleSubscribeToChildReport(
reportID: newChat.reportID,
introSelected,
participants,
// TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656
personalDetails: personalDetails ?? allPersonalDetails,
personalDetails,
newReportObject: newChat,
parentReportActionID: parentReportAction.reportActionID,
isSelfTourViewed,
Expand Down Expand Up @@ -4362,26 +4372,29 @@ function deleteReport(reportID: string | undefined, shouldDeleteChildReports = f
/**
* @param reportID The reportID of the policy report (workspace room)
*/
// eslint-disable-next-line @typescript-eslint/max-params
function navigateToConciergeChatAndDeleteReport(
reportID: string | undefined,
conciergeReportID: string | undefined,
currentUserAccountID: number,
introSelected: OnyxEntry<IntroSelected>,
isSelfTourViewed: boolean | undefined,
betas: OnyxEntry<Beta[]>,
reportOwnerPersonalDetail: OnyxEntry<PersonalDetails>,
currentUserPersonalDetail: OnyxEntry<PersonalDetails>,
conciergePersonalDetail: OnyxEntry<PersonalDetails>,
shouldPopToTop = false,
shouldDeleteChildReports = false,
// TODO: personalDetails should be a required field in follow-up PRs https://github.com/Expensify/App/issues/73656
personalDetails?: OnyxEntry<PersonalDetailsList>,
) {
// Dismiss the current report screen and replace it with Concierge Chat
if (shouldPopToTop) {
Navigation.popToSidebar();
} else {
Navigation.goBack();
}
// TODO: allPersonalDetails fallback should be removed in follow-up PRs https://github.com/Expensify/App/issues/73656
navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas, false, undefined, undefined, undefined, personalDetails ?? allPersonalDetails);
const personalDetails = buildPersonalDetailsList([reportOwnerPersonalDetail, currentUserPersonalDetail, conciergePersonalDetail]);
navigateToConciergeChat(conciergeReportID, introSelected, currentUserAccountID, isSelfTourViewed, betas, false, undefined, undefined, undefined, personalDetails);
// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => {
deleteReport(reportID, shouldDeleteChildReports);
});
Expand All @@ -4394,6 +4407,9 @@ function clearCreateChatError(
currentUserAccountID: number,
betas: OnyxEntry<Beta[]>,
isSelfTourViewed: boolean | undefined,
reportOwnerPersonalDetail: OnyxEntry<PersonalDetails>,
currentUserPersonalDetail: OnyxEntry<PersonalDetails>,
conciergePersonalDetail: OnyxEntry<PersonalDetails>,
) {
const metaData = getReportMetadata(report?.reportID);
const isOptimisticReport = metaData?.isOptimisticReport;
Expand All @@ -4402,7 +4418,19 @@ function clearCreateChatError(
return;
}

navigateToConciergeChatAndDeleteReport(report?.reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, undefined, true);
navigateToConciergeChatAndDeleteReport(
report?.reportID,
conciergeReportID,
currentUserAccountID,
introSelected,
isSelfTourViewed,
betas,
reportOwnerPersonalDetail,
currentUserPersonalDetail,
conciergePersonalDetail,
undefined,
true,
);
}

/**
Expand Down
18 changes: 17 additions & 1 deletion src/libs/actions/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import ROUTES from '@src/ROUTES';
import type {Route} from '@src/ROUTES';
import type * as OnyxTypes from '@src/types/onyx';
import type {Icon} from '@src/types/onyx/OnyxCommon';
import type PersonalDetails from '@src/types/onyx/PersonalDetails';
import type {ReportActions} from '@src/types/onyx/ReportAction';
import type ReportAction from '@src/types/onyx/ReportAction';
import type {OnyxData} from '@src/types/onyx/Request';
Expand Down Expand Up @@ -1432,6 +1433,9 @@ function clearTaskErrors(
introSelected: OnyxEntry<OnyxTypes.IntroSelected>,
betas: OnyxEntry<OnyxTypes.Beta[]>,
isSelfTourViewed: boolean | undefined,
reportOwnerPersonalDetail: OnyxEntry<PersonalDetails>,
currentUserPersonalDetail: OnyxEntry<PersonalDetails>,
conciergePersonalDetail: OnyxEntry<PersonalDetails>,
) {
const reportID = report?.reportID;
if (!reportID) {
Expand All @@ -1442,7 +1446,19 @@ function clearTaskErrors(
if (report?.pendingFields?.createChat === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) {
Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`, report.parentReportActionID ? {[report.parentReportActionID]: null} : {});

navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas);
navigateToConciergeChatAndDeleteReport(
reportID,
conciergeReportID,
currentUserAccountID,
introSelected,
isSelfTourViewed,
betas,
reportOwnerPersonalDetail,
currentUserPersonalDetail,
conciergePersonalDetail,
undefined,
undefined,
);
return;
}

Expand Down
24 changes: 22 additions & 2 deletions src/pages/Debug/Report/DebugReportPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {hasSeenTourSelector} from '@selectors/Onboarding';
import {conciergePersonalDetailSelector, personalDetailByAccountIDSelector} from '@selectors/PersonalDetails';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
Expand Down Expand Up @@ -76,7 +77,11 @@ function DebugReportPage({
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
const {accountID: currentUserAccountID, login: currentUserLogin} = useCurrentUserPersonalDetails();
const currentUserPersonalDetail = useCurrentUserPersonalDetails();
const {accountID: currentUserAccountID, login: currentUserLogin} = currentUserPersonalDetail;
const [conciergePersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: conciergePersonalDetailSelector});
const reportOwnerSelector = useMemo(() => personalDetailByAccountIDSelector(report?.ownerAccountID), [report?.ownerAccountID]);
const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: reportOwnerSelector}, [reportOwnerSelector]);
const transactionID = DebugUtils.getTransactionID(report, reportActions);
const isReportArchived = useReportIsArchived(reportID);

Expand Down Expand Up @@ -185,7 +190,19 @@ function DebugReportPage({
Debug.setDebugData(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, data);
}}
onDelete={() => {
navigateToConciergeChatAndDeleteReport(reportID, conciergeReportID, currentUserAccountID, introSelected, isSelfTourViewed, betas, true, true);
navigateToConciergeChatAndDeleteReport(
reportID,
conciergeReportID,
currentUserAccountID,
introSelected,
isSelfTourViewed,
betas,
reportOwnerPersonalDetail,
currentUserPersonalDetail,
conciergePersonalDetail,
true,
true,
);
}}
validate={DebugUtils.validateReportDraftProperty}
>
Expand Down Expand Up @@ -251,6 +268,9 @@ function DebugReportPage({
introSelected,
isSelfTourViewed,
betas,
reportOwnerPersonalDetail,
currentUserPersonalDetail,
conciergePersonalDetail,
],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import CompactMenuContext from '@components/CompactMenuContext';
import ContextMenuItem from '@components/ContextMenuItem';
import {useDelegateNoAccessActions, useDelegateNoAccessState} from '@components/DelegateNoAccessModalProvider';
import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal';
import {useSession} from '@components/OnyxListItemProvider';
import {usePersonalDetails, useSession} from '@components/OnyxListItemProvider';
import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useDelegateAccountID from '@hooks/useDelegateAccountID';
Expand Down Expand Up @@ -245,6 +245,7 @@ function BaseReportActionContextMenu({
const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST);
const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
const personalDetails = usePersonalDetails();
const reportAttributes = useReportAttributes();
const delegateAccountID = useDelegateAccountID();

Expand Down Expand Up @@ -395,6 +396,7 @@ function BaseReportActionContextMenu({
interceptAnonymousUser,
openOverflowMenu,
setIsEmojiPickerActive,
personalDetails,
isHarvestReport,
moneyRequestAction,
card,
Expand Down
Loading
Loading