Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
61f4961
Implement ChangeReportPolicy
rayane-d Feb 27, 2025
548ae3e
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Feb 27, 2025
0503fcf
Correct ModalStackNavigator name
rayane-d Feb 28, 2025
ae3da3a
Fix changeReportPolicy action logic
rayane-d Feb 28, 2025
5f7bd16
add comments to functions
rayane-d Feb 28, 2025
43377ba
revert a change
rayane-d Feb 28, 2025
cfc5f07
ReportChangeWorkspacePage
rayane-d Feb 28, 2025
d285d3e
isWorkspaceEligibleForReportChange
rayane-d Feb 28, 2025
c80610c
action message
rayane-d Feb 28, 2025
706c8e2
remove unused translation
rayane-d Feb 28, 2025
cebcba7
ChangePolicyEducationalModal
rayane-d Feb 28, 2025
c3292d8
prettier
rayane-d Feb 28, 2025
c1e1bbe
fix Eslint errors
rayane-d Feb 28, 2025
4d553cc
fix lint errors
rayane-d Feb 28, 2025
78205ad
fix lint error
rayane-d Feb 28, 2025
d8c3311
update changeReportPolicy logic
rayane-d Mar 1, 2025
cbe2407
Merge branch 'Expensify:main' into Implement-ChangeReportPolicy
rayane-d Mar 3, 2025
26bc7f7
address review comments
rayane-d Mar 4, 2025
65e2227
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Mar 4, 2025
7dc8a2e
lint
rayane-d Mar 4, 2025
2ac603a
correct formatting in changeReportPolicy translation
rayane-d Mar 4, 2025
7373efe
address review comments
rayane-d Mar 4, 2025
9e391ab
DRY common code
rayane-d Mar 4, 2025
fea2af7
adjust paddings
rayane-d Mar 4, 2025
6911734
prettier
rayane-d Mar 4, 2025
f74833a
Merge branch 'Expensify:main' into Implement-ChangeReportPolicy
rayane-d Mar 5, 2025
afaecbc
remove unnecessary code
rayane-d Mar 5, 2025
29bfa8c
rename the component
rayane-d Mar 5, 2025
1b32db0
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Mar 5, 2025
d7517ea
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Mar 5, 2025
c375808
address review comments
rayane-d Mar 6, 2025
b8a0a04
update workspace eligibility logic for report changes
rayane-d Mar 6, 2025
f1d61c7
prettier
rayane-d Mar 6, 2025
41ff79d
remove eslint-disable comment for array index key
rayane-d Mar 6, 2025
4dc6a93
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Mar 7, 2025
5325d0d
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Mar 12, 2025
e6ed654
fix approver logic
rayane-d Mar 12, 2025
2d4ecbd
Add isWorkspaceEligibleForReportChange tests
rayane-d Mar 12, 2025
c3e9628
Merge branch 'main' into Implement-ChangeReportPolicy
rayane-d Mar 12, 2025
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
154 changes: 154 additions & 0 deletions assets/images/product-illustrations/emptystate__receiptfairy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6790,6 +6790,7 @@ const CONST = {
SCAN_TEST_TOOLTIP_MANAGER: 'scanTestTooltipManager',
SCAN_TEST_CONFIRMATION: 'scanTestConfirmation',
},
CHANGE_POLICY_TRAINING_MODAL: 'changePolicyModal',
SMART_BANNER_HEIGHT: 152,

NAVIGATION_TESTS: {
Expand Down Expand Up @@ -6821,6 +6822,7 @@ const CONST = {
},
SKIPPABLE_COLLECTION_MEMBER_IDS: [String(DEFAULT_NUMBER_ID), '-1', 'undefined', 'null', 'NaN'] as string[],
SETUP_SPECIALIST_LOGIN: 'Setup Specialist',
ILLUSTRATION_ASPECT_RATIO: 39 / 22,
} as const;

type Country = keyof typeof CONST.ALL_COUNTRIES;
Expand Down
8 changes: 8 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,10 @@ const ROUTES = {
route: 'r/:reportID/details/export/:connectionName',
getRoute: (reportID: string, connectionName: ConnectionName, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/details/export/${connectionName as string}` as const, backTo),
},
REPORT_WITH_ID_CHANGE_WORKSPACE: {
route: 'r/:reportID/change-workspace',
getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/change-workspace` as const, backTo),
},
REPORT_SETTINGS: {
route: 'r/:reportID/settings',
getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/settings` as const, backTo),
Expand Down Expand Up @@ -1685,6 +1689,10 @@ const ROUTES = {
route: 'hold-expense-educational',
getRoute: (backTo?: string) => getUrlWithBackToParam('hold-expense-educational', backTo),
},
CHANGE_POLICY_EDUCATIONAL: {
route: 'change-workspace-educational',
getRoute: (backTo?: string) => getUrlWithBackToParam('change-workspace-educational', backTo),
},
TRAVEL_MY_TRIPS: 'travel',
TRAVEL_TCS: {
route: 'travel/terms/:domain/accept',
Expand Down
6 changes: 6 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ const SCREENS = {
PROFILE: 'Profile',
NEW_REPORT_WORKSPACE_SELECTION: 'New_Report_Workspace_Selection',
REPORT_DETAILS: 'Report_Details',
REPORT_CHANGE_WORKSPACE: 'ReportChangeWorkspace',
WORKSPACE_CONFIRMATION: 'Workspace_Confirmation',
REPORT_SETTINGS: 'Report_Settings',
REPORT_DESCRIPTION: 'Report_Description',
Expand Down Expand Up @@ -339,6 +340,10 @@ const SCREENS = {
EXPORT: 'Report_Details_Export',
},

REPORT_CHANGE_WORKSPACE: {
ROOT: 'ReportChangeWorkspace_Root',
},

WORKSPACE_CONFIRMATION: {ROOT: 'Workspace_Confirmation_Root'},

WORKSPACE: {
Expand Down Expand Up @@ -652,6 +657,7 @@ const SCREENS = {
DETAILS_ROOT: 'Details_Root',
PROFILE_ROOT: 'Profile_Root',
PROCESS_MONEY_REQUEST_HOLD_ROOT: 'ProcessMoneyRequestHold_Root',
CHANGE_POLICY_EDUCATIONAL_ROOT: 'ChangePolicyEducational_Root',
REPORT_DESCRIPTION_ROOT: 'Report_Description_Root',
REPORT_PARTICIPANTS: {
ROOT: 'ReportParticipants_Root',
Expand Down
59 changes: 59 additions & 0 deletions src/components/ChangeWorkspaceMenuSectionList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import convertToLTR from '@libs/convertToLTR';
import variables from '@styles/variables';
import type {TranslationPaths} from '@src/languages/types';
import type IconAsset from '@src/types/utils/IconAsset';
import Icon from './Icon';
import * as Illustrations from './Icon/Illustrations';
import RenderHTML from './RenderHTML';

type ChangeWorkspaceMenuSection = {
/** The icon supplied with the section */
icon: IconAsset;

/** Translation key for the title */
titleTranslationKey: TranslationPaths;
};

const changeWorkspaceMenuSections: ChangeWorkspaceMenuSection[] = [
{
icon: Illustrations.FolderOpen,
titleTranslationKey: 'iou.changePolicyEducational.reCategorize',
},
{
icon: Illustrations.Workflows,
titleTranslationKey: 'iou.changePolicyEducational.workflows',
},
];

function ChangeWorkspaceMenuSectionList() {
const {translate} = useLocalize();
const styles = useThemeStyles();

return (
<>
{changeWorkspaceMenuSections.map((section) => (
<View
key={section.titleTranslationKey}
style={[styles.flexRow, styles.alignItemsCenter, styles.mt3]}
>
<Icon
width={variables.menuIconSize}
height={variables.menuIconSize}
src={section.icon}
additionalStyles={[styles.mr4]}
/>
<View style={[styles.flex1, styles.justifyContentCenter]}>
<RenderHTML html={`<comment>${convertToLTR(translate(section.titleTranslationKey))}</comment>`} />
</View>
</View>
))}
</>
);
}

ChangeWorkspaceMenuSectionList.displayName = 'ChangeWorkspaceMenuSectionList';
export default ChangeWorkspaceMenuSectionList;
12 changes: 12 additions & 0 deletions src/components/FeatureTrainingModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ type FeatureTrainingModalSVGProps = {

/** Determines how the image should be resized to fit its container */
contentFitImage?: ImageContentFit;

/** The width of the image */
imageWidth?: number;

/** The height of the image */
imageHeight?: number;
};

// This page requires either an icon or a video/animation, but not both
Expand Down Expand Up @@ -143,6 +149,8 @@ function FeatureTrainingModal({
contentInnerContainerStyles,
contentOuterContainerStyles,
modalInnerContainerStyle,
imageWidth,
imageHeight,
isModalDisabled = true,
}: FeatureTrainingModalProps) {
const styles = useThemeStyles();
Expand Down Expand Up @@ -211,6 +219,8 @@ function FeatureTrainingModal({
<ImageSVG
src={image}
contentFit={contentFitImage}
width={imageWidth}
height={imageHeight}
/>
)}
{!!videoURL && videoStatus === 'video' && (
Expand Down Expand Up @@ -241,6 +251,8 @@ function FeatureTrainingModal({
);
}, [
image,
imageHeight,
imageWidth,
contentFitImage,
illustrationAspectRatio,
styles.w100,
Expand Down
34 changes: 15 additions & 19 deletions src/components/HoldMenuSectionList.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
import React from 'react';
import {View} from 'react-native';
import type {ImageSourcePropType} from 'react-native';
import type {SvgProps} from 'react-native-svg';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';
import type {TranslationPaths} from '@src/languages/types';
import type IconAsset from '@src/types/utils/IconAsset';
import Icon from './Icon';
import * as Illustrations from './Icon/Illustrations';
import Text from './Text';

type HoldMenuSection = {
/** The icon supplied with the section */
icon: React.FC<SvgProps> | ImageSourcePropType;
icon: IconAsset;

/** Translation key for the title */
titleTranslationKey: TranslationPaths;
};

const holdMenuSections: HoldMenuSection[] = [
{
icon: Illustrations.Stopwatch,
titleTranslationKey: 'iou.holdIsLeftBehind',
},
{
icon: Illustrations.RealtimeReport,
titleTranslationKey: 'iou.unholdWhenReady',
},
];

function HoldMenuSectionList() {
const {translate} = useLocalize();
const styles = useThemeStyles();

const holdMenuSections: HoldMenuSection[] = [
{
icon: Illustrations.Stopwatch,
titleTranslationKey: 'iou.holdIsLeftBehind',
},
{
icon: Illustrations.RealtimeReport,
titleTranslationKey: 'iou.unholdWhenReady',
},
];

return (
<>
{holdMenuSections.map((section, i) => (
{holdMenuSections.map((section) => (
<View
// eslint-disable-next-line react/no-array-index-key
key={i}
key={section.titleTranslationKey}
style={[styles.flexRow, styles.alignItemsCenter, styles.mt5]}
>
<Icon
Expand All @@ -58,6 +56,4 @@ function HoldMenuSectionList() {

HoldMenuSectionList.displayName = 'HoldMenuSectionList';

export type {HoldMenuSection};

export default HoldMenuSectionList;
2 changes: 2 additions & 0 deletions src/components/Icon/Illustrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import ConciergeExclamation from '@assets/images/product-illustrations/concierge
import CreditCardsBlue from '@assets/images/product-illustrations/credit-cards--blue.svg';
import EmptyStateExpenses from '@assets/images/product-illustrations/emptystate__expenses.svg';
import HoldExpense from '@assets/images/product-illustrations/emptystate__holdexpense.svg';
import ReceiptFairy from '@assets/images/product-illustrations/emptystate__receiptfairy.svg';
import EmptyStateTravel from '@assets/images/product-illustrations/emptystate__travel.svg';
import FolderWithPapers from '@assets/images/product-illustrations/folder-with-papers.svg';
import GpsTrackOrange from '@assets/images/product-illustrations/gps-track--orange.svg';
Expand Down Expand Up @@ -231,6 +232,7 @@ export {
QRCode,
RealtimeReport,
HoldExpense,
ReceiptFairy,
ReceiptEnvelope,
Approval,
WalletAlt,
Expand Down
15 changes: 5 additions & 10 deletions src/components/ProcessMoneyRequestHoldMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useMemo} from 'react';
import React, {useMemo} from 'react';
import {View} from 'react-native';
import useBeforeRemove from '@hooks/useBeforeRemove';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import FeatureTrainingModal from './FeatureTrainingModal';
import HoldMenuSectionList from './HoldMenuSectionList';
import * as Illustrations from './Icon/Illustrations';
Expand All @@ -22,15 +23,9 @@ type ProcessMoneyRequestHoldMenuProps = {
function ProcessMoneyRequestHoldMenu({onClose, onConfirm}: ProcessMoneyRequestHoldMenuProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const navigation = useNavigation();
const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout();

useEffect(() => {
const unsub = navigation.addListener('beforeRemove', () => {
onClose();
});
return unsub;
}, [navigation, onClose]);
useBeforeRemove(onClose);

const title = useMemo(
() => (
Expand All @@ -50,7 +45,7 @@ function ProcessMoneyRequestHoldMenu({onClose, onConfirm}: ProcessMoneyRequestHo
image={Illustrations.HoldExpense}
contentFitImage="cover"
width={variables.holdEducationModalWidth}
illustrationAspectRatio={39 / 22}
illustrationAspectRatio={CONST.ILLUSTRATION_ASPECT_RATIO}
contentInnerContainerStyles={styles.mb5}
modalInnerContainerStyle={styles.pt0}
illustrationOuterContainerStyle={styles.p0}
Expand Down
Loading
Loading