Skip to content

Commit

Permalink
Merge pull request #55536 from callstack-internal/undo-defaults-value…
Browse files Browse the repository at this point in the history
…s-purereportactionitem

Undo defaults values for onyx ids PureReportActionItem
  • Loading branch information
neil-marcellini authored Jan 27, 2025
2 parents 8e5fb5e + 778ad98 commit b4e662c
Show file tree
Hide file tree
Showing 31 changed files with 323 additions and 261 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.changed.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = {
},
overrides: [
{
files: ['src/pages/workspace/WorkspaceInitialPage.tsx', 'src/pages/home/report/PureReportActionItem.tsx', 'src/libs/SidebarUtils.ts'],
files: ['src/pages/workspace/WorkspaceInitialPage.tsx', 'src/libs/SidebarUtils.ts'],
rules: {
'rulesdir/no-default-id-values': 'off',
},
Expand Down
31 changes: 25 additions & 6 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,12 @@ const ROUTES = {
},
EDIT_REPORT_FIELD_REQUEST: {
route: 'r/:reportID/edit/policyField/:policyID/:fieldID',
getRoute: (reportID: string, policyID: string, fieldID: string, backTo?: string) =>
getUrlWithBackToParam(`r/${reportID}/edit/policyField/${policyID}/${encodeURIComponent(fieldID)}` as const, backTo),
getRoute: (reportID: string | undefined, policyID: string | undefined, fieldID: string, backTo?: string) => {
if (!policyID || !reportID) {
Log.warn('Invalid policyID or reportID is used to build the EDIT_REPORT_FIELD_REQUEST route', {policyID, reportID});
}
return getUrlWithBackToParam(`r/${reportID}/edit/policyField/${policyID}/${encodeURIComponent(fieldID)}` as const, backTo);
},
},
REPORT_WITH_ID_DETAILS_SHARE_CODE: {
route: 'r/:reportID/details/shareCode',
Expand Down Expand Up @@ -400,11 +404,21 @@ const ROUTES = {
},
SPLIT_BILL_DETAILS: {
route: 'r/:reportID/split/:reportActionID',
getRoute: (reportID: string, reportActionID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/split/${reportActionID}` as const, backTo),
getRoute: (reportID: string | undefined, reportActionID: string, backTo?: string) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the SPLIT_BILL_DETAILS route');
}
return getUrlWithBackToParam(`r/${reportID}/split/${reportActionID}` as const, backTo);
},
},
TASK_TITLE: {
route: 'r/:reportID/title',
getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/title` as const, backTo),
getRoute: (reportID: string | undefined, backTo?: string) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the TASK_TITLE route');
}
return getUrlWithBackToParam(`r/${reportID}/title` as const, backTo);
},
},
REPORT_DESCRIPTION: {
route: 'r/:reportID/description',
Expand All @@ -417,7 +431,12 @@ const ROUTES = {
},
TASK_ASSIGNEE: {
route: 'r/:reportID/assignee',
getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/assignee` as const, backTo),
getRoute: (reportID: string | undefined, backTo?: string) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the TASK_ASSIGNEE route');
}
return getUrlWithBackToParam(`r/${reportID}/assignee` as const, backTo);
},
},
PRIVATE_NOTES_LIST: {
route: 'r/:reportID/notes',
Expand Down Expand Up @@ -1926,7 +1945,7 @@ const ROUTES = {
},
DEBUG_REPORT: {
route: 'debug/report/:reportID',
getRoute: (reportID: string) => `debug/report/${reportID}` as const,
getRoute: (reportID: string | undefined) => `debug/report/${reportID}` as const,
},
DEBUG_REPORT_TAB_DETAILS: {
route: 'debug/report/:reportID/details',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {createContext} from 'react';

type MentionReportContextProps = {
currentReportID: string;
currentReportID: string | undefined;
exactlyMatch?: boolean;
};

const MentionReportContext = createContext<MentionReportContextProps>({
currentReportID: '',
currentReportID: undefined,
});

export default MentionReportContext;
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ function MentionReportRenderer({style, tnode, TDefaultRenderer, ...defaultRender
const [reports] = useOnyx(ONYXKEYS.COLLECTION.REPORT);

const currentReportID = useCurrentReportID();
const currentReportIDValue = currentReportIDContext || currentReportID?.currentReportID;
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const [currentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${currentReportIDValue || -1}`);
const currentReportIDValue = currentReportIDContext || currentReportID?.currentReportID;
const [currentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${currentReportIDValue}`);

// When we invite someone to a room they don't have the policy object, but we still want them to be able to see and click on report mentions, so we only check if the policyID in the report is from a workspace
const isGroupPolicyReport = useMemo(() => currentReport && !isEmptyObject(currentReport) && !!currentReport.policyID && currentReport.policyID !== CONST.POLICY.ID_FAKE, [currentReport]);
Expand Down
1 change: 0 additions & 1 deletion src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
const [isScreenFocused, setIsScreenFocused] = useState(false);
const {shouldUseNarrowLayout} = useResponsiveLayout();

// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${optionItem?.reportID}`);
const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID);
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
Expand Down
10 changes: 5 additions & 5 deletions src/components/ReportActionItem/ChronosOOOListActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import DateUtils from '@libs/DateUtils';
import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as Chronos from '@userActions/Chronos';
import {getOriginalMessage} from '@libs/ReportActionsUtils';
import {removeEvent} from '@userActions/Chronos';
import type CONST from '@src/CONST';
import type ReportAction from '@src/types/onyx/ReportAction';

type ChronosOOOListActionsProps = {
/** The ID of the report */
reportID: string;
reportID: string | undefined;

/** All the data of the action */
action: ReportAction<typeof CONST.REPORT.ACTIONS.TYPE.CHRONOS_OOO_LIST>;
Expand All @@ -24,7 +24,7 @@ function ChronosOOOListActions({reportID, action}: ChronosOOOListActionsProps) {

const {translate, preferredLocale} = useLocalize();

const events = ReportActionsUtils.getOriginalMessage(action)?.events ?? [];
const events = getOriginalMessage(action)?.events ?? [];

if (!events.length) {
return (
Expand Down Expand Up @@ -61,7 +61,7 @@ function ChronosOOOListActions({reportID, action}: ChronosOOOListActionsProps) {
<Button
small
style={styles.pl2}
onPress={() => Chronos.removeEvent(reportID, action.reportActionID, event.id, events)}
onPress={() => removeEvent(reportID, action.reportActionID, event.id, events)}
>
<Text style={styles.buttonSmallText}>{translate('common.remove')}</Text>
</Button>
Expand Down
82 changes: 45 additions & 37 deletions src/components/ReportActionItem/MoneyReportView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,33 @@ import useNetwork from '@hooks/useNetwork';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import * as CurrencyUtils from '@libs/CurrencyUtils';
import {convertToDisplayString} from '@libs/CurrencyUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as ReportUtils from '@libs/ReportUtils';
import {
getAvailableReportFields,
getFieldViolation,
getFieldViolationTranslation,
getMoneyRequestSpendBreakdown,
getReportFieldKey,
hasUpdatedTotal,
isClosedExpenseReportWithNoExpenses as isClosedExpenseReportWithNoExpensesReportUtils,
isInvoiceReport as isInvoiceReportUtils,
isPaidGroupPolicyExpenseReport as isPaidGroupPolicyExpenseReportUtils,
isReportFieldDisabled,
isReportFieldOfTypeTitle,
isSettled as isSettledReportUtils,
} from '@libs/ReportUtils';
import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground';
import variables from '@styles/variables';
import * as reportActions from '@src/libs/actions/Report';
import {clearReportFieldKeyErrors} from '@src/libs/actions/Report';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Policy, PolicyReportField, Report} from '@src/types/onyx';
import type {PendingAction} from '@src/types/onyx/OnyxCommon';

type MoneyReportViewProps = {
/** The report currently being looked at */
report: Report;
report: OnyxEntry<Report>;

/** Policy that the report belongs to */
policy: OnyxEntry<Policy>;
Expand All @@ -52,15 +65,15 @@ function MoneyReportView({report, policy, isCombinedReport = false, shouldShowTo
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
const {isOffline} = useNetwork();
const isSettled = ReportUtils.isSettled(report.reportID);
const isTotalUpdated = ReportUtils.hasUpdatedTotal(report, policy);
const isSettled = isSettledReportUtils(report?.reportID);
const isTotalUpdated = hasUpdatedTotal(report, policy);

const {totalDisplaySpend, nonReimbursableSpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(report);
const {totalDisplaySpend, nonReimbursableSpend, reimbursableSpend} = getMoneyRequestSpendBreakdown(report);

const shouldShowBreakdown = nonReimbursableSpend && reimbursableSpend && shouldShowTotal;
const formattedTotalAmount = CurrencyUtils.convertToDisplayString(totalDisplaySpend, report.currency);
const formattedOutOfPocketAmount = CurrencyUtils.convertToDisplayString(reimbursableSpend, report.currency);
const formattedCompanySpendAmount = CurrencyUtils.convertToDisplayString(nonReimbursableSpend, report.currency);
const formattedTotalAmount = convertToDisplayString(totalDisplaySpend, report?.currency);
const formattedOutOfPocketAmount = convertToDisplayString(reimbursableSpend, report?.currency);
const formattedCompanySpendAmount = convertToDisplayString(nonReimbursableSpend, report?.currency);
const isPartiallyPaid = !!report?.pendingFields?.partial;

const subAmountTextStyles: StyleProp<TextStyle> = [
Expand All @@ -70,25 +83,25 @@ function MoneyReportView({report, policy, isCombinedReport = false, shouldShowTo
StyleUtils.getColorStyle(theme.textSupporting),
];

const [violations] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_VIOLATIONS}${report.reportID}`);
const [violations] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_VIOLATIONS}${report?.reportID}`);

const sortedPolicyReportFields = useMemo<PolicyReportField[]>((): PolicyReportField[] => {
const fields = ReportUtils.getAvailableReportFields(report, Object.values(policy?.fieldList ?? {}));
return fields.filter((field) => field.target === report.type).sort(({orderWeight: firstOrderWeight}, {orderWeight: secondOrderWeight}) => firstOrderWeight - secondOrderWeight);
const fields = getAvailableReportFields(report, Object.values(policy?.fieldList ?? {}));
return fields.filter((field) => field.target === report?.type).sort(({orderWeight: firstOrderWeight}, {orderWeight: secondOrderWeight}) => firstOrderWeight - secondOrderWeight);
}, [policy, report]);

const enabledReportFields = sortedPolicyReportFields.filter((reportField) => !ReportUtils.isReportFieldDisabled(report, reportField, policy));
const isOnlyTitleFieldEnabled = enabledReportFields.length === 1 && ReportUtils.isReportFieldOfTypeTitle(enabledReportFields.at(0));
const isClosedExpenseReportWithNoExpenses = ReportUtils.isClosedExpenseReportWithNoExpenses(report);
const isPaidGroupPolicyExpenseReport = ReportUtils.isPaidGroupPolicyExpenseReport(report);
const isInvoiceReport = ReportUtils.isInvoiceReport(report);
const enabledReportFields = sortedPolicyReportFields.filter((reportField) => !isReportFieldDisabled(report, reportField, policy));
const isOnlyTitleFieldEnabled = enabledReportFields.length === 1 && isReportFieldOfTypeTitle(enabledReportFields.at(0));
const isClosedExpenseReportWithNoExpenses = isClosedExpenseReportWithNoExpensesReportUtils(report);
const isPaidGroupPolicyExpenseReport = isPaidGroupPolicyExpenseReportUtils(report);
const isInvoiceReport = isInvoiceReportUtils(report);
const shouldShowReportField = !isClosedExpenseReportWithNoExpenses && (isPaidGroupPolicyExpenseReport || isInvoiceReport) && (!isCombinedReport || !isOnlyTitleFieldEnabled);

const renderThreadDivider = useMemo(
() =>
shouldHideThreadDividerLine && !isCombinedReport ? (
<UnreadActionIndicator
reportActionID={report.reportID}
reportActionID={report?.reportID}
shouldHideThreadDividerLine={shouldHideThreadDividerLine}
/>
) : (
Expand All @@ -97,7 +110,7 @@ function MoneyReportView({report, policy, isCombinedReport = false, shouldShowTo
style={[!shouldHideThreadDividerLine ? styles.reportHorizontalRule : {}]}
/>
),
[shouldHideThreadDividerLine, report.reportID, styles.reportHorizontalRule, isCombinedReport],
[shouldHideThreadDividerLine, report?.reportID, styles.reportHorizontalRule, isCombinedReport],
);

return (
Expand All @@ -110,39 +123,34 @@ function MoneyReportView({report, policy, isCombinedReport = false, shouldShowTo
policy?.areReportFieldsEnabled &&
(!isCombinedReport || !isOnlyTitleFieldEnabled) &&
sortedPolicyReportFields.map((reportField) => {
if (ReportUtils.isReportFieldOfTypeTitle(reportField)) {
if (isReportFieldOfTypeTitle(reportField)) {
return null;
}

const fieldValue = reportField.value ?? reportField.defaultValue;
const isFieldDisabled = ReportUtils.isReportFieldDisabled(report, reportField, policy);
const fieldKey = ReportUtils.getReportFieldKey(reportField.fieldID);
const isFieldDisabled = isReportFieldDisabled(report, reportField, policy);
const fieldKey = getReportFieldKey(reportField.fieldID);

const violation = ReportUtils.getFieldViolation(violations, reportField);
const violationTranslation = ReportUtils.getFieldViolationTranslation(reportField, violation);
const violation = getFieldViolation(violations, reportField);
const violationTranslation = getFieldViolationTranslation(reportField, violation);

return (
<OfflineWithFeedback
// Need to return undefined when we have pendingAction to avoid the duplicate pending action
pendingAction={pendingAction ? undefined : report.pendingFields?.[fieldKey as keyof typeof report.pendingFields]}
errors={report.errorFields?.[fieldKey]}
pendingAction={pendingAction ? undefined : report?.pendingFields?.[fieldKey as keyof typeof report.pendingFields]}
errors={report?.errorFields?.[fieldKey]}
errorRowStyles={styles.ph5}
key={`menuItem-${fieldKey}`}
onClose={() => reportActions.clearReportFieldKeyErrors(report.reportID, fieldKey)}
onClose={() => clearReportFieldKeyErrors(report?.reportID, fieldKey)}
>
<MenuItemWithTopDescription
description={Str.UCFirst(reportField.name)}
title={fieldValue}
onPress={() =>
onPress={() => {
Navigation.navigate(
ROUTES.EDIT_REPORT_FIELD_REQUEST.getRoute(
report.reportID,
report.policyID ?? '-1',
reportField.fieldID,
Navigation.getReportRHPActiveRoute(),
),
)
}
ROUTES.EDIT_REPORT_FIELD_REQUEST.getRoute(report?.reportID, report?.policyID, reportField.fieldID, Navigation.getReportRHPActiveRoute()),
);
}}
shouldShowRightIcon
disabled={isFieldDisabled}
wrapperStyle={[styles.pv2, styles.taskDescriptionMenuItem]}
Expand Down
Loading

0 comments on commit b4e662c

Please sign in to comment.