diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 4d3c977497dd..71edff9b863f 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1369,16 +1369,6 @@ const ROUTES = { return getUrlWithBackToParam(`${action as string}/${iouType as string}/taxAmount/${transactionID}/${reportID}`, backTo); }, }, - MONEY_REQUEST_STEP_CATEGORY_CREATE: { - route: ':action/:iouType/category/new/:transactionID/:reportID/:reportActionID?', - getRoute: (action: IOUAction, iouType: IOUType, transactionID: string | undefined, reportID: string | undefined, reportActionID?: string, backTo = '') => { - if (!transactionID || !reportID) { - Log.warn('Invalid transactionID or reportID is used to build the MONEY_REQUEST_STEP_CATEGORY_CREATE route'); - } - // eslint-disable-next-line no-restricted-syntax -- backTo is needed here to track where editing was initiated from (e.g. search/view or r/:reportID) - return getUrlWithBackToParam(`${action as string}/${iouType as string}/category/new/${transactionID}/${reportID}${reportActionID ? `/${reportActionID}` : ''}`, backTo); - }, - }, MONEY_REQUEST_STEP_CATEGORY: { route: ':action/:iouType/category/:transactionID/:reportID/:reportActionID?', getRoute: (action: IOUAction, iouType: IOUType, transactionID: string | undefined, reportID: string | undefined, backTo = '', reportActionID?: string) => { diff --git a/src/SCREENS.ts b/src/SCREENS.ts index b9289a81f8ed..a663ef23621c 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -362,7 +362,6 @@ const SCREENS = { STEP_UPGRADE: 'Money_Request_Step_Upgrade', STEP_AMOUNT: 'Money_Request_Step_Amount', STEP_CATEGORY: 'Money_Request_Step_Category', - STEP_CATEGORY_CREATE: 'Money_Request_Step_Category_Create', STEP_DATE: 'Money_Request_Step_Date', STEP_DESCRIPTION: 'Money_Request_Step_Description', STEP_DISTANCE: 'Money_Request_Step_Distance', diff --git a/src/components/MoneyRequestConfirmationList/hooks/useConfirmationValidation.ts b/src/components/MoneyRequestConfirmationList/hooks/useConfirmationValidation.ts index cbe3ff2e30e6..3a885a5f8e1e 100644 --- a/src/components/MoneyRequestConfirmationList/hooks/useConfirmationValidation.ts +++ b/src/components/MoneyRequestConfirmationList/hooks/useConfirmationValidation.ts @@ -174,9 +174,7 @@ function useConfirmationValidation({ return {errorKey: 'iou.error.invalidCategoryLength'}; } - const isCategoryBeingCreated = policyCategories?.[iouCategory]?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD; - - if (iouCategory && policyCategories && !policyCategories[iouCategory]?.enabled && !isCategoryBeingCreated) { + if (iouCategory && policyCategories && !policyCategories[iouCategory]?.enabled) { return {errorKey: 'violations.categoryOutOfPolicy'}; } diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 080cbb419d16..5844f1528b3d 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -178,7 +178,6 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator require('../../../../pages/iou/request/step/IOURequestStepTaxAmountPage').default, [SCREENS.MONEY_REQUEST.STEP_TAX_RATE]: () => require('../../../../pages/iou/request/step/IOURequestStepTaxRatePage').default, [SCREENS.MONEY_REQUEST.STEP_CATEGORY]: () => require('../../../../pages/iou/request/step/IOURequestStepCategory').default, - [SCREENS.MONEY_REQUEST.STEP_CATEGORY_CREATE]: () => require('../../../../pages/iou/request/step/IOURequestStepCategoryCreate').default, [SCREENS.MONEY_REQUEST.STEP_DATE]: () => require('../../../../pages/iou/request/step/IOURequestStepDate').default, [SCREENS.MONEY_REQUEST.STEP_DESCRIPTION]: () => require('../../../../pages/iou/request/step/IOURequestStepDescription').default, [SCREENS.MONEY_REQUEST.STEP_DISTANCE]: () => require('../../../../pages/iou/request/step/IOURequestStepDistance').default, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 439d68eecdeb..09a6647c148e 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -1731,7 +1731,6 @@ const config: LinkingOptions['config'] = { [SCREENS.MONEY_REQUEST.STEP_COMPANY_INFO]: ROUTES.MONEY_REQUEST_STEP_COMPANY_INFO.route, [SCREENS.MONEY_REQUEST.STEP_AMOUNT]: ROUTES.MONEY_REQUEST_STEP_AMOUNT.route, [SCREENS.MONEY_REQUEST.STEP_CATEGORY]: ROUTES.MONEY_REQUEST_STEP_CATEGORY.route, - [SCREENS.MONEY_REQUEST.STEP_CATEGORY_CREATE]: ROUTES.MONEY_REQUEST_STEP_CATEGORY_CREATE.route, [SCREENS.MONEY_REQUEST.STEP_CONFIRMATION]: ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.route, [SCREENS.MONEY_REQUEST.STEP_CONFIRMATION_VERIFY_ACCOUNT]: ROUTES.MONEY_REQUEST_STEP_CONFIRMATION_VERIFY_ACCOUNT.route, [SCREENS.MONEY_REQUEST.STEP_DATE]: ROUTES.MONEY_REQUEST_STEP_DATE.route, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 57c5dbd085ad..29e26555278a 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1900,15 +1900,6 @@ type MoneyRequestNavigatorParamList = { // eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md backTo: Routes; }; - [SCREENS.MONEY_REQUEST.STEP_CATEGORY_CREATE]: { - action: IOUAction; - iouType: Exclude; - transactionID: string; - reportID: string; - reportActionID?: string; - // eslint-disable-next-line no-restricted-syntax -- backTo is needed to track where editing was initiated from (search/view or r/:reportID) - backTo?: Routes; - }; [SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT]: { action: IOUAction; iouType: Exclude; diff --git a/src/libs/Violations/ViolationsUtils.ts b/src/libs/Violations/ViolationsUtils.ts index 9afe0c99410d..c0fe48155a9d 100644 --- a/src/libs/Violations/ViolationsUtils.ts +++ b/src/libs/Violations/ViolationsUtils.ts @@ -395,10 +395,7 @@ const ViolationsUtils = { const hasCategoryOutOfPolicyViolation = transactionViolations.some((violation) => violation.name === 'categoryOutOfPolicy'); const hasMissingCategoryViolation = transactionViolations.some((violation) => violation.name === 'missingCategory'); const categoryKey = updatedTransaction.category; - const categoryData = policyCategories?.[categoryKey ?? '']; - // A category being created optimistically (pendingAction === 'add') is treated as valid - // so in-situ creation doesn't trigger a "categoryOutOfPolicy" violation before the server confirms it. - const isCategoryInPolicy = categoryKey ? !!(categoryData?.enabled || categoryData?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) : false; + const isCategoryInPolicy = categoryKey ? policyCategories?.[categoryKey]?.enabled : false; // Add 'categoryOutOfPolicy' violation if category is not in policy if (!hasCategoryOutOfPolicyViolation && !isCategoryMissing(categoryKey) && !isCategoryInPolicy) { diff --git a/src/pages/iou/request/step/IOURequestStepCategory.tsx b/src/pages/iou/request/step/IOURequestStepCategory.tsx index 80194f18d065..415e22fd9ff1 100644 --- a/src/pages/iou/request/step/IOURequestStepCategory.tsx +++ b/src/pages/iou/request/step/IOURequestStepCategory.tsx @@ -11,7 +11,7 @@ import {useSearchStateContext} from '@components/Search/SearchContext'; import type {ListItem} from '@components/SelectionList/types'; import WorkspaceEmptyStateSection from '@components/WorkspaceEmptyStateSection'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -29,7 +29,7 @@ import {isCategoryMissing} from '@libs/CategoryUtils'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; import Navigation from '@libs/Navigation/Navigation'; import {hasEnabledOptions} from '@libs/OptionsListUtils'; -import {getValidConnectedIntegration, isPolicyAdmin} from '@libs/PolicyUtils'; +import {isPolicyAdmin} from '@libs/PolicyUtils'; import {getReportOrDraftReport, getTransactionDetails, isGroupPolicy, isReportInGroupPolicy} from '@libs/ReportUtils'; import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan'; import {getRequestType} from '@libs/TransactionUtils'; @@ -57,7 +57,6 @@ function IOURequestStepCategory({ const styles = useThemeStyles(); const {translate} = useLocalize(); const illustrations = useMemoizedLazyIllustrations(['EmptyStateExpenses']); - const expensifyIcons = useMemoizedLazyExpensifyIcons(['Plus']); const requestType = getRequestType(transaction); const isPerDiemRequest = requestType === CONST.IOU.REQUEST_TYPE.PER_DIEM; const transactionReport = getReportOrDraftReport(transaction?.reportID); @@ -91,23 +90,6 @@ function IOURequestStepCategory({ const categoryForDisplay = isCategoryMissing(transactionCategory) ? '' : transactionCategory; - const canCreateCategoryInSitu = isPolicyAdmin(policy) && !getValidConnectedIntegration(policy) && !!policy?.areCategoriesEnabled; - - const createCategoryMenuItems = canCreateCategoryInSitu - ? [ - { - icon: expensifyIcons.Plus, - text: translate('workspace.categories.addCategory'), - onSelected: () => { - if (!policyID || !report?.reportID) { - return; - } - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CATEGORY_CREATE.getRoute(action, iouType, transactionID, report.reportID, reportActionID, backTo)); - }, - }, - ] - : undefined; - const shouldShowCategory = (isReportInGroupPolicy(report) || isGroupPolicy(policy?.type ?? '')) && // The transactionCategory can be an empty string, so to maintain the logic we'd like to keep it in this shape until utils refactor @@ -197,8 +179,6 @@ function IOURequestStepCategory({ shouldShowOfflineIndicator={policyCategories !== undefined} testID="IOURequestStepCategory" shouldEnableKeyboardAvoidingView={false} - threeDotsMenuItems={createCategoryMenuItems} - shouldMinimizeMenuButton > {isLoading && ( & - WithFullTransactionOrNotFoundProps; - -function IOURequestStepCategoryCreate({ - report: reportReal, - reportDraft, - route: { - params: {transactionID, action, iouType, reportID, backTo}, - }, - transaction, -}: IOURequestStepCategoryCreateProps) { - const {translate} = useLocalize(); - const currentUserPersonalDetails = useCurrentUserPersonalDetails(); - const {isBetaEnabled} = usePermissions(); - const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT); - const {currentSearchHash} = useSearchStateContext(); - - const isEditing = action === CONST.IOU.ACTION.EDIT; - const isEditingSplit = (iouType === CONST.IOU.TYPE.SPLIT || iouType === CONST.IOU.TYPE.SPLIT_EXPENSE) && isEditing; - - const policyIdReal = getIOURequestPolicyID(transaction, reportReal); - const policyIdDraft = getIOURequestPolicyID(transaction, reportDraft); - const {policy} = usePolicyForTransaction({ - transaction, - reportPolicyID: policyIdReal ?? policyIdDraft, - action, - iouType, - isPerDiemRequest: false, - }); - const policyID = policy?.id; - - const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`); - const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); - const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`); - const [policyRecentlyUsedCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES}${policyID}`); - const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(reportReal?.parentReportID ?? reportDraft?.parentReportID)}`); - const [parentReportNextStep] = useOnyx(`${ONYXKEYS.COLLECTION.NEXT_STEP}${getNonEmptyStringOnyxID(reportReal?.parentReportID ?? reportDraft?.parentReportID)}`); - - const report = reportReal ?? reportDraft; - - useRestartOnReceiptFailure(transaction, reportID, iouType, action); - - const policyHasTags = hasTags(policyTags); - - const { - taskReport: setupCategoryTaskReport, - taskParentReport: setupCategoryTaskParentReport, - isOnboardingTaskParentReportArchived: isSetupCategoryTaskParentReportArchived, - hasOutstandingChildTask, - parentReportAction, - } = useOnboardingTaskInformation(CONST.ONBOARDING_TASK_TYPE.SETUP_CATEGORIES); - - const { - taskReport: setupCategoriesAndTagsTaskReport, - taskParentReport: setupCategoriesAndTagsTaskParentReport, - isOnboardingTaskParentReportArchived: isSetupCategoriesAndTagsTaskParentReportArchived, - hasOutstandingChildTask: setupCategoriesAndTagsHasOutstandingChildTask, - parentReportAction: setupCategoriesAndTagsParentReportAction, - } = useOnboardingTaskInformation(CONST.ONBOARDING_TASK_TYPE.SETUP_CATEGORIES_AND_TAGS); - - const createCategory = useCallback( - (values: FormOnyxValues) => { - const categoryName = values.categoryName.trim(); - - if (!policyID) { - return; - } - - // 1. Create the category in the workspace (optimistic update, queued API call). - createPolicyCategory({ - policyID, - categoryName, - isSetupCategoriesTaskParentReportArchived: isSetupCategoryTaskParentReportArchived, - setupCategoryTaskReport, - setupCategoryTaskParentReport, - currentUserAccountID: currentUserPersonalDetails.accountID, - hasOutstandingChildTask, - parentReportAction, - setupCategoriesAndTagsTaskReport, - setupCategoriesAndTagsTaskParentReport, - isSetupCategoriesAndTagsTaskParentReportArchived, - setupCategoriesAndTagsHasOutstandingChildTask, - setupCategoriesAndTagsParentReportAction, - policyHasTags, - }); - - // 2. Apply the newly created category to the transaction. - const policyCategoriesWithNewCategory = { - ...policyCategories, - [categoryName]: { - name: categoryName, - enabled: true, - errors: null, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - }; - - if (isEditingSplit && transaction) { - setDraftSplitTransaction(transaction.transactionID, splitDraftTransaction, {category: categoryName}, policy); - } else if (isEditing && report) { - updateMoneyRequestCategory({ - transactionID: transaction?.transactionID ?? transactionID, - transactionThreadReport: report, - parentReport, - parentReportNextStep, - category: categoryName, - policy, - policyTagList: policyTags, - policyCategories: policyCategoriesWithNewCategory, - policyRecentlyUsedCategories, - currentUserAccountIDParam: currentUserPersonalDetails.accountID, - currentUserEmailParam: currentUserPersonalDetails.login ?? '', - isASAPSubmitBetaEnabled, - hash: currentSearchHash, - }); - } else { - setMoneyRequestCategory(transactionID, categoryName, policy); - } - - if (isEditing) { - Navigation.goBack(backTo); - } else { - Navigation.goBack(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, iouType, transactionID, reportID)); - } - }, - [ - action, - backTo, - currentSearchHash, - currentUserPersonalDetails.accountID, - currentUserPersonalDetails.login, - hasOutstandingChildTask, - isASAPSubmitBetaEnabled, - isEditing, - isEditingSplit, - isSetupCategoriesAndTagsTaskParentReportArchived, - isSetupCategoryTaskParentReportArchived, - iouType, - parentReport, - parentReportAction, - parentReportNextStep, - policy, - policyCategories, - policyHasTags, - policyID, - policyRecentlyUsedCategories, - policyTags, - report, - reportID, - setupCategoriesAndTagsHasOutstandingChildTask, - setupCategoriesAndTagsParentReportAction, - setupCategoriesAndTagsTaskParentReport, - setupCategoriesAndTagsTaskReport, - setupCategoryTaskParentReport, - setupCategoryTaskReport, - splitDraftTransaction, - transaction, - transactionID, - ], - ); - - return ( - - Navigation.goBack()} - shouldShowWrapper - testID="IOURequestStepCategoryCreate" - > - - - - ); -} - -const IOURequestStepCategoryCreateWithFullTransactionOrNotFound = withFullTransactionOrNotFound(IOURequestStepCategoryCreate); -const IOURequestStepCategoryCreateWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepCategoryCreateWithFullTransactionOrNotFound); -export default IOURequestStepCategoryCreateWithWritableReportOrNotFound; diff --git a/src/pages/iou/request/step/StepScreenWrapper.tsx b/src/pages/iou/request/step/StepScreenWrapper.tsx index dff47036cf2c..7b4283e368fe 100644 --- a/src/pages/iou/request/step/StepScreenWrapper.tsx +++ b/src/pages/iou/request/step/StepScreenWrapper.tsx @@ -3,7 +3,6 @@ import type {ReactNode} from 'react'; import {View} from 'react-native'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import type {PopoverMenuItem} from '@components/PopoverMenu'; import type {ScreenWrapperChildrenProps} from '@components/ScreenWrapper'; import ScreenWrapper from '@components/ScreenWrapper'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -40,12 +39,6 @@ type StepScreenWrapperProps = { /** Flag to indicate if the keyboard avoiding view should be enabled */ shouldEnableKeyboardAvoidingView?: boolean; - - /** Menu items to display in the header three-dots / action button */ - threeDotsMenuItems?: PopoverMenuItem[]; - - /** When true and there is a single menu item, renders it as a direct icon button instead of a three-dots menu */ - shouldMinimizeMenuButton?: boolean; }; function StepScreenWrapper({ @@ -59,8 +52,6 @@ function StepScreenWrapper({ includeSafeAreaPaddingBottom, shouldShowOfflineIndicator = true, shouldEnableKeyboardAvoidingView = true, - threeDotsMenuItems, - shouldMinimizeMenuButton, }: StepScreenWrapperProps) { const styles = useThemeStyles(); @@ -83,9 +74,6 @@ function StepScreenWrapper({ { // If props.children is a function, call it to provide the insets to the children diff --git a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx index 19555ecfad4e..9a99774e8415 100644 --- a/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx +++ b/src/pages/iou/request/step/withFullTransactionOrNotFound.tsx @@ -56,8 +56,7 @@ type MoneyRequestRouteName = | typeof SCREENS.MONEY_REQUEST.ODOMETER_IMAGE | typeof SCREENS.MONEY_REQUEST.STEP_TIME_RATE | typeof SCREENS.MONEY_REQUEST.STEP_HOURS - | typeof SCREENS.MONEY_REQUEST.STEP_HOURS_EDIT - | typeof SCREENS.MONEY_REQUEST.STEP_CATEGORY_CREATE; + | typeof SCREENS.MONEY_REQUEST.STEP_HOURS_EDIT; type WithFullTransactionOrNotFoundProps = WithFullTransactionOrNotFoundOnyxProps & PlatformStackScreenProps; diff --git a/src/pages/iou/request/step/withWritableReportOrNotFound.tsx b/src/pages/iou/request/step/withWritableReportOrNotFound.tsx index 2f56d246d763..0fdb535c2ca6 100644 --- a/src/pages/iou/request/step/withWritableReportOrNotFound.tsx +++ b/src/pages/iou/request/step/withWritableReportOrNotFound.tsx @@ -59,8 +59,7 @@ type MoneyRequestRouteName = | typeof SCREENS.MONEY_REQUEST.STEP_DISTANCE_MANUAL | typeof SCREENS.MONEY_REQUEST.STEP_TIME_RATE | typeof SCREENS.MONEY_REQUEST.STEP_HOURS - | typeof SCREENS.MONEY_REQUEST.STEP_HOURS_EDIT - | typeof SCREENS.MONEY_REQUEST.STEP_CATEGORY_CREATE; + | typeof SCREENS.MONEY_REQUEST.STEP_HOURS_EDIT; type WithWritableReportOrNotFoundProps = WithWritableReportOrNotFoundOnyxProps & PlatformStackScreenProps;