From fda657cf96c1235cf0606a89cd91cd4d764f7ad7 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:42:10 +0300 Subject: [PATCH 001/137] add payroll screen --- src/SCREENS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SCREENS.ts b/src/SCREENS.ts index fd7418aee1c5..5dea2db57668 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -310,6 +310,7 @@ const SCREENS = { NAME: 'Workspace_Profile_Name', CATEGORY_CREATE: 'Category_Create', CATEGORY_EDIT: 'Category_Edit', + CATEGORY_PAYROLL_CODE: 'Category_Payroll_Code', CATEGORY_SETTINGS: 'Category_Settings', CATEGORIES_SETTINGS: 'Categories_Settings', MORE_FEATURES: 'Workspace_More_Features', From bdf8070fa997f2efb2c48d080f318a18fc0f5bc8 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:42:41 +0300 Subject: [PATCH 002/137] add payroll route --- src/ROUTES.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 5a8f4a2cd4d0..9081c58fb9b0 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -688,6 +688,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/categories/:categoryName/edit', getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURIComponent(categoryName)}/edit` as const, }, + WORKSPACE_CATEGORY_PAYROLL_CODE: { + route: 'settings/workspaces/:policyID/categories/:categoryName/payroll-code', + getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/categories/${encodeURIComponent(categoryName)}/payroll-code` as const, + }, WORKSPACE_MORE_FEATURES: { route: 'settings/workspaces/:policyID/more-features', getRoute: (policyID: string) => `settings/workspaces/${policyID}/more-features` as const, From b29331ad03df15319d4326918475dee2b168100c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:45:52 +0300 Subject: [PATCH 003/137] add navigation links for payroll --- .../AppNavigator/ModalStackNavigators/index.tsx | 1 + .../linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts | 8 +++++++- src/libs/Navigation/linkingConfig/config.ts | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 9a391e386f15..827ea8cd74f8 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -243,6 +243,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/members/WorkspaceOwnerChangeErrorPage').default as React.ComponentType, [SCREENS.WORKSPACE.CATEGORY_CREATE]: () => require('../../../../pages/workspace/categories/CreateCategoryPage').default as React.ComponentType, [SCREENS.WORKSPACE.CATEGORY_EDIT]: () => require('../../../../pages/workspace/categories/EditCategoryPage').default as React.ComponentType, + [SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE]: () => require('../../../../pages/workspace/categories/CategoryPayrollCodePage').default as React.ComponentType, [SCREENS.WORKSPACE.CREATE_DISTANCE_RATE]: () => require('../../../../pages/workspace/distanceRates/CreateDistanceRatePage').default as React.ComponentType, [SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS]: () => require('../../../../pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage').default as React.ComponentType, [SCREENS.WORKSPACE.DISTANCE_RATE_DETAILS]: () => require('../../../../pages/workspace/distanceRates/PolicyDistanceRateDetailsPage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index f91d290639ff..67d1c6a76851 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -74,7 +74,13 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.TAG_EDIT, SCREENS.WORKSPACE.TAG_LIST_VIEW, ], - [SCREENS.WORKSPACE.CATEGORIES]: [SCREENS.WORKSPACE.CATEGORY_CREATE, SCREENS.WORKSPACE.CATEGORY_SETTINGS, SCREENS.WORKSPACE.CATEGORIES_SETTINGS, SCREENS.WORKSPACE.CATEGORY_EDIT], + [SCREENS.WORKSPACE.CATEGORIES]: [ + SCREENS.WORKSPACE.CATEGORY_CREATE, + SCREENS.WORKSPACE.CATEGORY_SETTINGS, + SCREENS.WORKSPACE.CATEGORIES_SETTINGS, + SCREENS.WORKSPACE.CATEGORY_EDIT, + SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE, + ], [SCREENS.WORKSPACE.DISTANCE_RATES]: [ SCREENS.WORKSPACE.CREATE_DISTANCE_RATE, SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index b3f27d422b4b..bf0d35eb9363 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -408,6 +408,12 @@ const config: LinkingOptions['config'] = { categoryName: (categoryName: string) => decodeURIComponent(categoryName), }, }, + [SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE]: { + path: ROUTES.WORKSPACE_CATEGORY_PAYROLL_CODE.route, + parse: { + categoryName: (categoryName: string) => decodeURIComponent(categoryName), + }, + }, [SCREENS.WORKSPACE.CREATE_DISTANCE_RATE]: { path: ROUTES.WORKSPACE_CREATE_DISTANCE_RATE.route, }, From 78cb66102120c9525d4e91e1fdd52736a740855d Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:46:31 +0300 Subject: [PATCH 004/137] add nav type --- src/libs/Navigation/types.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 2267d2d38fb7..0d2f61b29b09 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -200,6 +200,10 @@ type SettingsNavigatorParamList = { categoryName: string; backTo?: Routes; }; + [SCREENS.WORKSPACE.CATEGORY_PAYROLL_CODE]: { + policyID: string; + categoryName: string; + }; [SCREENS.WORKSPACE.CATEGORY_SETTINGS]: { policyID: string; categoryName: string; From 4ad00ea3049430c3ac16a1706e1ad9d1ecc132b5 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:48:05 +0300 Subject: [PATCH 005/137] add menu item for payroll code to category settings page --- src/pages/workspace/categories/CategorySettingsPage.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 22f2b4f02fbf..eab73db63367 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -138,6 +138,14 @@ function CategorySettingsPage({route, policyCategories, navigation}: CategorySet shouldShowRightIcon /> + + Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_PAYROLL_CODE.getRoute(route.params.policyID, policyCategory.name))} + shouldShowRightIcon + /> + From 2cec124f843f43816a9322de70b9644ac85565b1 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:51:11 +0300 Subject: [PATCH 006/137] add payroll code to category type --- src/types/onyx/PolicyCategory.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/types/onyx/PolicyCategory.ts b/src/types/onyx/PolicyCategory.ts index d4162bfdcddf..15e237eebf01 100644 --- a/src/types/onyx/PolicyCategory.ts +++ b/src/types/onyx/PolicyCategory.ts @@ -17,6 +17,9 @@ type PolicyCategory = OnyxCommon.OnyxValueWithOfflineFeedback<{ // eslint-disable-next-line @typescript-eslint/naming-convention 'GL Code'?: string; + /** Payroll code is used to keep track of taxes, deductions, and an employee’s earnings */ + payrollCode?: string; + /** An ID for this category from an external accounting system */ externalID?: string; From bf7b779535cd768f6c7fdc243de4d17f9ff123fc Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:52:33 +0300 Subject: [PATCH 007/137] add payroll code to form type --- src/types/form/WorkspaceCategoryForm.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/form/WorkspaceCategoryForm.ts b/src/types/form/WorkspaceCategoryForm.ts index 4f5f9282373c..9e813319b38c 100644 --- a/src/types/form/WorkspaceCategoryForm.ts +++ b/src/types/form/WorkspaceCategoryForm.ts @@ -3,6 +3,7 @@ import type Form from './Form'; const INPUT_IDS = { CATEGORY_NAME: 'categoryName', + PAYROLL_CODE: 'payrollCode', } as const; type InputID = ValueOf; From 6d1e6033b0d767974aa07a86f0a7db3571757fc1 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:52:45 +0300 Subject: [PATCH 008/137] add payroll code to form type --- src/types/form/WorkspaceCategoryForm.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/form/WorkspaceCategoryForm.ts b/src/types/form/WorkspaceCategoryForm.ts index 9e813319b38c..9224957847a3 100644 --- a/src/types/form/WorkspaceCategoryForm.ts +++ b/src/types/form/WorkspaceCategoryForm.ts @@ -12,6 +12,7 @@ type WorkspaceCategoryForm = Form< InputID, { [INPUT_IDS.CATEGORY_NAME]: string; + [INPUT_IDS.PAYROLL_CODE]: string; } >; From 4e6c965f9e954c004bb0f327ab8a877b15b4dede Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:55:15 +0300 Subject: [PATCH 009/137] add payroll code --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index 9a047178147e..328f81a14b7d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2197,6 +2197,7 @@ export default { existingCategoryError: 'A category with this name already exists.', invalidCategoryName: 'Invalid category name.', importedFromAccountingSoftware: 'The categories below are imported from your', + payrollCode: 'Payroll code', }, moreFeatures: { spendSection: { diff --git a/src/languages/es.ts b/src/languages/es.ts index c3fd2bc46849..693bf874e385 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2236,6 +2236,7 @@ export default { existingCategoryError: 'Ya existe una categoría con este nombre.', invalidCategoryName: 'Lo nombre de la categoría es invalido.', importedFromAccountingSoftware: 'Categorías importadas desde', + payrollCode: 'Payroll code', }, moreFeatures: { spendSection: { From 2e60d83936f9979b450b3e0954fcfd407615e656 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:55:58 +0300 Subject: [PATCH 010/137] add payroll code err msg --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index 328f81a14b7d..62e52911f564 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2198,6 +2198,7 @@ export default { invalidCategoryName: 'Invalid category name.', importedFromAccountingSoftware: 'The categories below are imported from your', payrollCode: 'Payroll code', + updatePayrollCodeFailureMessage: 'An error occurred while updating the payroll code, please try again.', }, moreFeatures: { spendSection: { diff --git a/src/languages/es.ts b/src/languages/es.ts index 693bf874e385..5ea9fe95643e 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2237,6 +2237,7 @@ export default { invalidCategoryName: 'Lo nombre de la categoría es invalido.', importedFromAccountingSoftware: 'Categorías importadas desde', payrollCode: 'Payroll code', + updatePayrollCodeFailureMessage: 'An error occurred while updating the payroll code, please try again.', }, moreFeatures: { spendSection: { From f20f10c4035d327b4e68c31d564f53fbfda4fe7c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:56:27 +0300 Subject: [PATCH 011/137] add payroll code page --- .../categories/CategoryPayrollCodePage.tsx | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/pages/workspace/categories/CategoryPayrollCodePage.tsx diff --git a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx new file mode 100644 index 000000000000..2761c8fdb533 --- /dev/null +++ b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx @@ -0,0 +1,94 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback} from 'react'; +import {withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import FormProvider from '@components/Form/FormProvider'; +import InputWrapper from '@components/Form/InputWrapper'; +import type {FormOnyxValues} from '@components/Form/types'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import TextInput from '@components/TextInput'; +import useAutoFocusInput from '@hooks/useAutoFocusInput'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@libs/Navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@navigation/types'; +import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; +import * as Category from '@userActions/Policy/Category'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import INPUT_IDS from '@src/types/form/WorkspaceCategoryForm'; +import type {PolicyCategories} from '@src/types/onyx'; + +type WorkspaceEditCategoryPayrollCodePageOnyxProps = { + /** Collection of categories attached to a policy */ + policyCategories: OnyxEntry; +}; + +type EditCategoryPageProps = WorkspaceEditCategoryPayrollCodePageOnyxProps & StackScreenProps; + +function CategoryPayrollCodePage({route, policyCategories}: EditCategoryPageProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const categoryName = route.params.categoryName; + const glCode = policyCategories?.[categoryName]?.payrollCode; + const {inputCallbackRef} = useAutoFocusInput(); + + const editGLCode = useCallback( + (values: FormOnyxValues) => { + const newGLCode = values.payrollCode.trim(); + if (newGLCode !== glCode) { + Category.setPolicyCategoryPayrollCode(route.params.policyID, categoryName, newGLCode); + } + Navigation.goBack(); + }, + [categoryName, glCode, route.params.policyID], + ); + + return ( + + + Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName))} + /> + + + + + + ); +} + +CategoryPayrollCodePage.displayName = 'CategoryPayrollCodePage'; + +export default withOnyx({ + policyCategories: { + key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route?.params?.policyID}`, + }, +})(CategoryPayrollCodePage); \ No newline at end of file From bf3dd2f538581edb5152eda2c72a0d1dbab07492 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 02:58:48 +0300 Subject: [PATCH 012/137] add api command impl for set payroll code --- src/libs/actions/Policy/Category.ts | 61 +++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 294712666bdf..c4d6d6c54f25 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -334,6 +334,66 @@ function renamePolicyCategory(policyID: string, policyCategory: {oldName: string API.write(WRITE_COMMANDS.RENAME_WORKSPACE_CATEGORY, parameters, onyxData); } +function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, payrollCode: string) { + const policyCategoryToUpdate = allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`]?.[categoryName] ?? {}; + + const onyxData: OnyxData = { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: { + [categoryName]: { + ...policyCategoryToUpdate, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + pendingFields: { + name: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + payrollCode, + }, + }, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: { + [categoryName]: { + ...policyCategoryToUpdate, + pendingAction: null, + pendingFields: { + name: null, + }, + payrollCode, + }, + }, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, + value: { + [categoryName]: { + ...policyCategoryToUpdate, + errors: ErrorUtils.getMicroSecondOnyxError('workspace.categories.updatePayrollCodeFailureMessage'), + pendingAction: null, + }, + }, + }, + ], + }; + + const parameters = { + policyID, + categoryName, + payrollCode, + }; + + API.write(WRITE_COMMANDS.UPDATE_POLICY_CATEGORY_GL_CODE, parameters, onyxData); +} + function setWorkspaceRequiresCategory(policyID: string, requiresCategory: boolean) { const onyxData: OnyxData = { optimisticData: [ @@ -591,6 +651,7 @@ export { buildOptimisticPolicyRecentlyUsedCategories, setWorkspaceCategoryEnabled, setWorkspaceRequiresCategory, + setPolicyCategoryPayrollCode, createPolicyCategory, renamePolicyCategory, clearCategoryErrors, From ed69bd00fc5b8558cc7b7edcc60a8c95fc8ddda4 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:01:42 +0300 Subject: [PATCH 013/137] add api params --- .../parameters/UpdatePolicyCategoryPayrollCodeParams.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts diff --git a/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts b/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts new file mode 100644 index 000000000000..d5f71f7179c4 --- /dev/null +++ b/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts @@ -0,0 +1,7 @@ +type UpdatePolicyCategoryPayrollCodeParams = { + policyID: string; + categoryName: string; + payroll: string; +}; + +export default UpdatePolicyCategoryPayrollCodeParams; \ No newline at end of file From d150bdc4d7a9a69137a3c03cfdb421ffc41d41f5 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:01:52 +0300 Subject: [PATCH 014/137] link api params --- src/libs/API/parameters/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index de8d6f55418b..7fb617ca71a5 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -165,6 +165,7 @@ export type {default as CreateWorkspaceCategoriesParams} from './CreateWorkspace export type {default as RenameWorkspaceCategoriesParams} from './RenameWorkspaceCategoriesParams'; export type {default as SetWorkspaceRequiresCategoryParams} from './SetWorkspaceRequiresCategoryParams'; export type {default as DeleteWorkspaceCategoriesParams} from './DeleteWorkspaceCategoriesParams'; +export type {default as UpdatePolicyCategoryPayrollCodeParams} from './UpdatePolicyCategoryPayrollCodeParams'; export type {default as SetWorkspaceAutoReportingParams} from './SetWorkspaceAutoReportingParams'; export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWorkspaceAutoReportingFrequencyParams'; export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams'; From 05be40cb5c43c611fcbbf7bfa394f9b1ba169b4e Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:03:49 +0300 Subject: [PATCH 015/137] add payroll code api typing --- src/libs/API/types.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 3f1acaaed466..9a8fbe457d28 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -132,6 +132,7 @@ const WRITE_COMMANDS = { CREATE_POLICY_TAG: 'CreatePolicyTag', RENAME_POLICY_TAG: 'RenamePolicyTag', SET_WORKSPACE_REQUIRES_CATEGORY: 'SetWorkspaceRequiresCategory', + UPDATE_POLICY_CATEGORY_PAYROLL_CODE: 'UpdatePolicyCategoryPayrollCode', DELETE_WORKSPACE_CATEGORIES: 'DeleteWorkspaceCategories', SET_POLICY_REQUIRES_TAG: 'SetPolicyRequiresTag', RENAME_POLICY_TAG_LIST: 'RenamePolicyTaglist', @@ -342,6 +343,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.RENAME_WORKSPACE_CATEGORY]: Parameters.RenameWorkspaceCategoriesParams; [WRITE_COMMANDS.SET_WORKSPACE_REQUIRES_CATEGORY]: Parameters.SetWorkspaceRequiresCategoryParams; [WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES]: Parameters.DeleteWorkspaceCategoriesParams; + [WRITE_COMMANDS.UPDATE_POLICY_CATEGORY_PAYROLL_CODE]: Parameters.UpdatePolicyCategoryPayrollCodeParams; [WRITE_COMMANDS.SET_POLICY_REQUIRES_TAG]: Parameters.SetPolicyRequiresTag; [WRITE_COMMANDS.RENAME_POLICY_TAG_LIST]: Parameters.RenamePolicyTaglist; [WRITE_COMMANDS.CREATE_POLICY_TAG]: Parameters.CreatePolicyTagsParams; From 9a1509813bccbde7122f3b6da22ec2f6c57974af Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:10:51 +0300 Subject: [PATCH 016/137] api call to payroll code --- src/libs/actions/Policy/Category.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index c4d6d6c54f25..4dd66dbce4bb 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -391,7 +391,7 @@ function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, pa payrollCode, }; - API.write(WRITE_COMMANDS.UPDATE_POLICY_CATEGORY_GL_CODE, parameters, onyxData); + API.write(WRITE_COMMANDS.UPDATE_POLICY_CATEGORY_PAYROLL_CODE, parameters, onyxData); } function setWorkspaceRequiresCategory(policyID: string, requiresCategory: boolean) { From 47d4566c3b59e37e4bade371ac16133605a094a8 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:16:41 +0300 Subject: [PATCH 017/137] fix typo --- .../API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts b/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts index d5f71f7179c4..8751832f7cad 100644 --- a/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts +++ b/src/libs/API/parameters/UpdatePolicyCategoryPayrollCodeParams.ts @@ -1,7 +1,7 @@ type UpdatePolicyCategoryPayrollCodeParams = { policyID: string; categoryName: string; - payroll: string; + payrollCode: string; }; -export default UpdatePolicyCategoryPayrollCodeParams; \ No newline at end of file +export default UpdatePolicyCategoryPayrollCodeParams; From b8aa3b2df48cbf0ff50f25b6998f63166962c477 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:21:02 +0300 Subject: [PATCH 018/137] use correct pending fields --- src/libs/actions/Policy/Category.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 4dd66dbce4bb..ad4fd97c535b 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -347,7 +347,7 @@ function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, pa ...policyCategoryToUpdate, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, pendingFields: { - name: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + payrollCode: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, payrollCode, }, @@ -363,7 +363,7 @@ function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, pa ...policyCategoryToUpdate, pendingAction: null, pendingFields: { - name: null, + payrollCode: null, }, payrollCode, }, From ff2c26166100ed50a01ecd014cc8c4b3264bb9b5 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 6 Jun 2024 03:29:51 +0300 Subject: [PATCH 019/137] run prettier --- src/pages/workspace/categories/CategoryPayrollCodePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx index 2761c8fdb533..8dc491e2b331 100644 --- a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx +++ b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx @@ -91,4 +91,4 @@ export default withOnyx `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route?.params?.policyID}`, }, -})(CategoryPayrollCodePage); \ No newline at end of file +})(CategoryPayrollCodePage); From e5c6ca0d6f2e7a3bf259f87f6c2c08e8aab668ed Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 26 Jun 2024 16:03:49 +0300 Subject: [PATCH 020/137] add max length --- src/CONST.ts | 2 ++ src/pages/workspace/categories/CategoryPayrollCodePage.tsx | 1 + 2 files changed, 3 insertions(+) diff --git a/src/CONST.ts b/src/CONST.ts index e71ad55a452c..6364391f72c3 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -4912,6 +4912,8 @@ const CONST = { }, }, + MAX_LENGTH_256: 256, + EXCLUDE_FROM_LAST_VISITED_PATH: [SCREENS.NOT_FOUND, SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN] as string[], } as const; diff --git a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx index 8dc491e2b331..bc8666effb74 100644 --- a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx +++ b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx @@ -78,6 +78,7 @@ function CategoryPayrollCodePage({route, policyCategories}: EditCategoryPageProp accessibilityLabel={translate('workspace.categories.payrollCode')} inputID={INPUT_IDS.PAYROLL_CODE} role={CONST.ROLE.PRESENTATION} + maxLength={CONST.MAX_LENGTH_256} /> From 2a4637b08bb6070b621bce6f9f8ef169df55486d Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 26 Jun 2024 16:04:21 +0300 Subject: [PATCH 021/137] fix merge --- src/pages/workspace/categories/CategorySettingsPage.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index ce216b16d306..317cb50d66f4 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -126,7 +126,6 @@ function CategorySettingsPage({route, policyCategories, navigation}: CategorySet shouldShowRightIcon /> -<<<<<<< HEAD -======= {!isThereAnyAccountingConnection && ( setDeleteCategoryConfirmModalVisible(true)} /> )} ->>>>>>> main From 3e7bb90a94125d44fa31094f303f366c6859ac37 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 26 Jun 2024 16:07:55 +0300 Subject: [PATCH 022/137] use translation key --- src/libs/actions/Policy/Category.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 0eb3622f3ed6..b68c8a8c082b 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -374,7 +374,7 @@ function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, pa value: { [categoryName]: { ...policyCategoryToUpdate, - errors: ErrorUtils.getMicroSecondOnyxError('workspace.categories.updatePayrollCodeFailureMessage'), + errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.categories.updatePayrollCodeFailureMessage'), pendingAction: null, }, }, From 9f2d5a2574eb5cbf61dd4a3ebd06d1fa6b5b946d Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Thu, 27 Jun 2024 16:22:53 +0700 Subject: [PATCH 023/137] display begining chat history message in LHN --- src/libs/ReportUtils.ts | 78 +++++++++++++++++++++++++++++++++++++++- src/libs/SidebarUtils.ts | 2 +- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index cca52ac37c9d..c89beace4724 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -21,6 +21,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; import type { Beta, OnyxInputOrEntry, @@ -79,7 +80,7 @@ import * as UserUtils from './UserUtils'; type AvatarRange = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18; -type WelcomeMessage = {showReportName: boolean; phrase1?: string; phrase2?: string}; +type WelcomeMessage = {showReportName: boolean; phrase1?: string; phrase2?: string; phrase3?: string}; type SpendBreakdown = { nonReimbursableSpend: number; @@ -1609,6 +1610,80 @@ function getRoomWelcomeMessage(report: OnyxEntry): WelcomeMessage { return welcomeMessage; } +function getWelcomMessage(report: OnyxEntry): WelcomeMessage { + const welcomeMessage: WelcomeMessage = {showReportName: true}; + if (isChatRoom(report)) { + return getRoomWelcomeMessage(report); + } + + if (isPolicyExpenseChat(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne'); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo'); + welcomeMessage.phrase3 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree'); + return welcomeMessage; + } + + if (isSelfDM(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistorySelfDM'); + return welcomeMessage; + } + + if (isSystemChat(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistorySystemDM'); + return welcomeMessage; + } + + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); + return welcomeMessage; +} + +function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string { + if (isThread(report)) { + return Localize.translateLocal('report.noActivityYet'); + } + + const welcomeMessage = getWelcomMessage(report); + if (isPolicyExpenseChat(report)) { + if (report?.description) { + return parseHtmlToText(report.description); + } + return `${welcomeMessage.phrase1} ${getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${getPolicyName(report)} ${welcomeMessage.phrase3}`; + } + + if (isChatRoom(report)) { + if (report?.description) { + return parseHtmlToText(report.description); + } + return `${welcomeMessage.phrase1} ${welcomeMessage.showReportName ? getReportName(report) : ''} ${welcomeMessage.phrase2 ?? ''}`; + } + + if (isSelfDM(report) || isSystemChat(report)) { + return `${welcomeMessage.phrase1}`; + } + + const participantAccountIDs = getParticipantsAccountIDsForDisplay(report); + const isMultipleParticipant = participantAccountIDs.length > 1; + const displayNamesWithTooltips = getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, allPersonalDetails), isMultipleParticipant); + const displayNamesWithTooltipsText = displayNamesWithTooltips + .map(({displayName, pronouns}, index) => { + const formattedText = !pronouns ? displayName : `${displayName} (${pronouns})`; + + if (index === displayNamesWithTooltips.length - 1) { + return `${formattedText}.`; + } + if (index === displayNamesWithTooltips.length - 2) { + return `${formattedText} ${Localize.translateLocal('common.and')}`; + } + if (index < displayNamesWithTooltips.length - 2) { + return `${formattedText},`; + } + + return ''; + }) + .join(' '); + return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; +} + /** * Returns true if Concierge is one of the chat participants (1:1 as well as group chats) */ @@ -7144,6 +7219,7 @@ export { getPolicyExpenseChat, getPolicyName, getPolicyType, + getReportBeginningOfChatHistoryMessage, getReimbursementDeQueuedActionMessage, getReimbursementQueuedActionMessage, getReportActionActorAccountID, diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index ee2807a94c7c..081e70df4be8 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -367,7 +367,7 @@ function getOptionData({ } else { result.alternateText = lastMessageTextFromReport.length > 0 ? lastMessageText : ReportActionsUtils.getLastVisibleMessage(report.reportID, {}, lastAction)?.lastMessageText; if (!result.alternateText) { - result.alternateText = Localize.translate(preferredLocale, 'report.noActivityYet'); + result.alternateText = ReportUtils.formatReportLastMessageText(ReportUtils.getReportBeginningOfChatHistoryMessage(report)) || Localize.translate(preferredLocale, 'report.noActivityYet');; } } } else { From 99f754410e0028339ec09478d7c731236e145f6e Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Sun, 30 Jun 2024 04:28:36 +0530 Subject: [PATCH 024/137] fix: Search - RHP closes or returns to transaction thread depending on which field is edited. Signed-off-by: Krishna Gupta --- src/pages/iou/request/step/IOURequestStepAmount.tsx | 11 +++-------- src/pages/iou/request/step/IOURequestStepDistance.tsx | 9 +++++---- .../request/step/IOURequestStepScan/index.native.tsx | 2 +- .../iou/request/step/IOURequestStepScan/index.tsx | 4 ++-- src/pages/iou/request/step/IOURequestStepTag.tsx | 2 +- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 04c8e772844b..3f2c2a938e21 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -280,12 +280,7 @@ function IOURequestStepAmount({ // If the value hasn't changed, don't request to save changes on the server and just close the modal const transactionCurrency = TransactionUtils.getCurrency(currentTransaction); if (newAmount === TransactionUtils.getAmount(currentTransaction) && currency === transactionCurrency) { - if (isSplitBill) { - Navigation.goBack(backTo); - } else { - Navigation.dismissModal(); - } - + navigateBack(); return; } @@ -298,12 +293,12 @@ function IOURequestStepAmount({ if (isSplitBill) { IOU.setDraftSplitTransaction(transactionID, {amount: newAmount, currency, taxCode, taxAmount}); - Navigation.goBack(backTo); + navigateBack(); return; } IOU.updateMoneyRequestAmountAndCurrency({transactionID, transactionThreadReportID: reportID, currency, amount: newAmount, taxAmount, policy, taxCode}); - Navigation.dismissModal(); + navigateBack(); }; return ( diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 11d5687a55e9..2735a2f90411 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -171,9 +171,9 @@ function IOURequestStepDistance({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const navigateBack = () => { + const navigateBack = useCallback(() => { Navigation.goBack(backTo); - }; + }, [backTo]); /** * Takes the user to the page for editing a specific waypoint @@ -379,7 +379,7 @@ function IOURequestStepDistance({ const addresses = Object.fromEntries(Object.entries(waypoints).map(([key, waypoint]) => [key, 'address' in waypoint ? waypoint.address : {}])); const hasRouteChanged = !isEqual(transactionBackup?.routes, transaction?.routes); if (isEqual(oldAddresses, addresses)) { - Navigation.dismissModal(); + navigateBack(); return; } IOU.updateMoneyRequestDistance({ @@ -389,12 +389,13 @@ function IOURequestStepDistance({ ...(hasRouteChanged ? {routes: transaction?.routes} : {}), policy, }); - Navigation.dismissModal(); + navigateBack(); return; } navigateToNextStep(); }, [ + navigateBack, duplicateWaypointsError, atLeastTwoDifferentWaypointsError, hasRouteError, diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 056a03b3b8f5..b5220ee53e15 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -370,7 +370,7 @@ function IOURequestStepScan({ const updateScanAndNavigate = useCallback( (file: FileObject, source: string) => { - Navigation.dismissModal(); + navigateBack(); IOU.replaceReceipt(transactionID, file as File, source); }, [transactionID], diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 00e0e14ee27c..8b0e17f7e6ef 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -417,9 +417,9 @@ function IOURequestStepScan({ const updateScanAndNavigate = useCallback( (file: FileObject, source: string) => { IOU.replaceReceipt(transactionID, file as File, source); - Navigation.dismissModal(); + navigateBack(); }, - [transactionID], + [transactionID, navigateBack], ); /** diff --git a/src/pages/iou/request/step/IOURequestStepTag.tsx b/src/pages/iou/request/step/IOURequestStepTag.tsx index d50b90f6d1ae..2d068e9acb81 100644 --- a/src/pages/iou/request/step/IOURequestStepTag.tsx +++ b/src/pages/iou/request/step/IOURequestStepTag.tsx @@ -98,7 +98,7 @@ function IOURequestStepTag({ } if (isEditing) { IOU.updateMoneyRequestTag(transactionID, report?.reportID ?? '-1', updatedTag, policy, policyTags, policyCategories); - Navigation.dismissModal(); + navigateBack(); return; } IOU.setMoneyRequestTag(transactionID, updatedTag); From c3344a465ac21c3bc88becc5ebc7f29ffc4e7cd3 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Sun, 30 Jun 2024 04:42:59 +0530 Subject: [PATCH 025/137] minor update. Signed-off-by: Krishna Gupta --- .../ReportActionItem/MoneyRequestView.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index a0d73a1b2844..29836183b8c9 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -12,6 +12,7 @@ import ReceiptEmptyState from '@components/ReceiptEmptyState'; import Switch from '@components/Switch'; import Text from '@components/Text'; import ViolationMessages from '@components/ViolationMessages'; +import useIsReportOpenInRHP from '@hooks/useIsReportOpenInRHP'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; @@ -115,6 +116,7 @@ function MoneyRequestView({ const {isOffline} = useNetwork(); const {translate, toLocaleDigit} = useLocalize(); const [activePolicyID] = useOnyx(ONYXKEYS.NVP_ACTIVE_POLICY_ID); + const isReportOpenInRHP = useIsReportOpenInRHP(); const parentReportAction = parentReportActions?.[report.parentReportActionID ?? '-1']; const isTrackExpense = ReportUtils.isTrackExpenseReport(report); @@ -216,17 +218,22 @@ function MoneyRequestView({ merchantTitle = translate('iou.receiptStatusTitle'); amountTitle = translate('iou.receiptStatusTitle'); } + const saveBillable = useCallback( (newBillable: boolean) => { // If the value hasn't changed, don't request to save changes on the server and just close the modal if (newBillable === TransactionUtils.getBillable(transaction)) { - Navigation.dismissModal(); + if (!isReportOpenInRHP) { + Navigation.dismissModal(); + } return; } IOU.updateMoneyRequestBillable(transaction?.transactionID ?? '-1', report?.reportID, newBillable, policy, policyTagList, policyCategories); - Navigation.dismissModal(); + if (!isReportOpenInRHP) { + Navigation.dismissModal(); + } }, - [transaction, report, policy, policyTagList, policyCategories], + [transaction, report, policy, policyTagList, policyCategories, isReportOpenInRHP], ); if (isCardTransaction) { From 632df80823af323216b79a7b63eb8b56151a6449 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Sun, 30 Jun 2024 05:55:09 +0530 Subject: [PATCH 026/137] fix lint warning. Signed-off-by: Krishna Gupta --- src/pages/iou/request/step/IOURequestStepScan/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 8b0e17f7e6ef..570a1cf3a294 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -230,9 +230,9 @@ function IOURequestStepScan({ }); } - const navigateBack = () => { + const navigateBack = useCallback(() => { Navigation.goBack(backTo); - }; + }, [backTo]); const navigateToParticipantPage = useCallback(() => { switch (iouType) { From d0a59fdb1bcb7213cd1f84a8b76b38c9fcb4d05c Mon Sep 17 00:00:00 2001 From: Someshwar Tripathi Date: Mon, 1 Jul 2024 03:55:50 +0530 Subject: [PATCH 027/137] Remove REPORT_FIELDS beta --- src/components/ReportActionItem/MoneyReportView.tsx | 2 +- src/libs/Permissions.ts | 5 ----- src/libs/ReportUtils.ts | 12 ++---------- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/components/ReportActionItem/MoneyReportView.tsx b/src/components/ReportActionItem/MoneyReportView.tsx index a724fd27f134..736b385c99a0 100644 --- a/src/components/ReportActionItem/MoneyReportView.tsx +++ b/src/components/ReportActionItem/MoneyReportView.tsx @@ -62,7 +62,7 @@ function MoneyReportView({report, policy}: MoneyReportViewProps) { {!ReportUtils.isClosedExpenseReportWithNoExpenses(report) && ( <> - {ReportUtils.reportFieldsEnabled(report) && + {ReportUtils.isPaidGroupPolicyExpenseReport(report) && sortedPolicyReportFields.map((reportField) => { const isTitleField = ReportUtils.isReportFieldOfTypeTitle(reportField); const fieldValue = isTitleField ? report.reportName : reportField.value ?? reportField.defaultValue; diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 79936d498280..ad8503a14d40 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -15,10 +15,6 @@ function canUseDefaultRooms(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.DEFAULT_ROOMS) || canUseAllBetas(betas); } -function canUseReportFields(betas: OnyxEntry): boolean { - return !!betas?.includes(CONST.BETAS.REPORT_FIELDS) || canUseAllBetas(betas); -} - function canUseViolations(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.VIOLATIONS) || canUseAllBetas(betas); } @@ -65,7 +61,6 @@ export default { canUseLinkPreviews, canUseViolations, canUseDupeDetection, - canUseReportFields, canUseP2PDistanceRequests, canUseWorkflowsDelayedSubmission, canUseSpotnanaTravel, diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index b17fe7266079..fc32bdbe77c6 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2431,13 +2431,6 @@ function isHoldCreator(transaction: OnyxEntry, reportID: string): b return isActionCreator(holdReportAction); } -/** - * Check if report fields are available to use in a report - */ -function reportFieldsEnabled(report: Report) { - return Permissions.canUseReportFields(allBetas ?? []) && isPaidGroupPolicyExpenseReport(report); -} - /** * Given a report field, check if the field can be edited or not. * For title fields, its considered disabled if `deletable` prop is `true` (https://github.com/Expensify/App/issues/35043#issuecomment-1911275433) @@ -2539,7 +2532,7 @@ function getMoneyRequestReportName(report: OnyxEntry, policy?: OnyxEntry const reportFields = isReportSettled ? report?.fieldList : getReportFieldsByPolicyID(report?.policyID ?? '-1'); const titleReportField = getFormulaTypeReportField(reportFields ?? {}); - if (titleReportField && report?.reportName && reportFieldsEnabled(report)) { + if (titleReportField && report?.reportName && isPaidGroupPolicyExpenseReport(report)) { return report.reportName; } @@ -3946,7 +3939,7 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa } const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policyID) ?? {}); - if (!!titleReportField && reportFieldsEnabled(expenseReport)) { + if (!!titleReportField && isPaidGroupPolicyExpenseReport(expenseReport)) { expenseReport.reportName = populateOptimisticReportFormula(titleReportField.defaultValue, expenseReport, policy); } @@ -7286,7 +7279,6 @@ export { navigateBackAfterDeleteTransaction, parseReportRouteParams, parseReportActionHtmlToText, - reportFieldsEnabled, requiresAttentionFromCurrentUser, shouldAutoFocusOnKeyPress, shouldCreateNewMoneyRequestReport, From e32567e76c635b081fce45c0bb1f6a0101cf1917 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 1 Jul 2024 11:02:18 +0700 Subject: [PATCH 028/137] fix lint --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 65a93c5c4491..13fd4b533453 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -21,7 +21,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; import type { Beta, OnyxInputOrEntry, @@ -48,6 +47,7 @@ import type {Message, ReportActions} from '@src/types/onyx/ReportAction'; import type {Comment, Receipt, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; +import * as OptionsListUtils from './OptionsListUtils'; import AccountUtils from './AccountUtils'; import * as IOU from './actions/IOU'; import * as PolicyActions from './actions/Policy/Policy'; From 0051894593f3578c9058fa78048b4918050cedaa Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 1 Jul 2024 11:20:44 +0700 Subject: [PATCH 029/137] fix lint --- src/libs/ReportUtils.ts | 50 +-------------------------------- src/libs/SidebarUtils.ts | 60 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 50 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 13fd4b533453..e083ba9634dd 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -47,7 +47,6 @@ import type {Message, ReportActions} from '@src/types/onyx/ReportAction'; import type {Comment, Receipt, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; -import * as OptionsListUtils from './OptionsListUtils'; import AccountUtils from './AccountUtils'; import * as IOU from './actions/IOU'; import * as PolicyActions from './actions/Policy/Policy'; @@ -1637,53 +1636,6 @@ function getWelcomMessage(report: OnyxEntry): WelcomeMessage { return welcomeMessage; } -function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string { - if (isThread(report)) { - return Localize.translateLocal('report.noActivityYet'); - } - - const welcomeMessage = getWelcomMessage(report); - if (isPolicyExpenseChat(report)) { - if (report?.description) { - return parseHtmlToText(report.description); - } - return `${welcomeMessage.phrase1} ${getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${getPolicyName(report)} ${welcomeMessage.phrase3}`; - } - - if (isChatRoom(report)) { - if (report?.description) { - return parseHtmlToText(report.description); - } - return `${welcomeMessage.phrase1} ${welcomeMessage.showReportName ? getReportName(report) : ''} ${welcomeMessage.phrase2 ?? ''}`; - } - - if (isSelfDM(report) || isSystemChat(report)) { - return `${welcomeMessage.phrase1}`; - } - - const participantAccountIDs = getParticipantsAccountIDsForDisplay(report); - const isMultipleParticipant = participantAccountIDs.length > 1; - const displayNamesWithTooltips = getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, allPersonalDetails), isMultipleParticipant); - const displayNamesWithTooltipsText = displayNamesWithTooltips - .map(({displayName, pronouns}, index) => { - const formattedText = !pronouns ? displayName : `${displayName} (${pronouns})`; - - if (index === displayNamesWithTooltips.length - 1) { - return `${formattedText}.`; - } - if (index === displayNamesWithTooltips.length - 2) { - return `${formattedText} ${Localize.translateLocal('common.and')}`; - } - if (index < displayNamesWithTooltips.length - 2) { - return `${formattedText},`; - } - - return ''; - }) - .join(' '); - return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; -} - /** * Returns true if Concierge is one of the chat participants (1:1 as well as group chats) */ @@ -7226,7 +7178,7 @@ export { getPolicyExpenseChat, getPolicyName, getPolicyType, - getReportBeginningOfChatHistoryMessage, + getWelcomMessage, getReimbursementDeQueuedActionMessage, getReimbursementQueuedActionMessage, getReportActionActorAccountID, diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 7cd60edeca14..1f6fc9a52c74 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -21,8 +21,16 @@ import * as PolicyUtils from './PolicyUtils'; import * as ReportActionsUtils from './ReportActionsUtils'; import * as ReportUtils from './ReportUtils'; import * as TaskUtils from './TaskUtils'; +import {parseHtmlToText} from './OnyxAwareParser'; const visibleReportActionItems: ReportActions = {}; +let allPersonalDetails: OnyxEntry; +Onyx.connect({ + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + callback: (value) => { + allPersonalDetails = value ?? {}; + }, +}); Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, callback: (actions, key) => { @@ -381,7 +389,7 @@ function getOptionData({ } else { result.alternateText = lastMessageTextFromReport.length > 0 ? lastMessageText : ReportActionsUtils.getLastVisibleMessage(report.reportID, {}, lastAction)?.lastMessageText; if (!result.alternateText) { - result.alternateText = ReportUtils.formatReportLastMessageText(ReportUtils.getReportBeginningOfChatHistoryMessage(report)) || Localize.translate(preferredLocale, 'report.noActivityYet');; + result.alternateText = ReportUtils.formatReportLastMessageText(getReportBeginningOfChatHistoryMessage(report)) || Localize.translate(preferredLocale, 'report.noActivityYet'); } } } else { @@ -447,8 +455,58 @@ function getOptionData({ return result; } +function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string { + if (ReportUtils.isThread(report)) { + return Localize.translateLocal('report.noActivityYet'); + } + + const welcomeMessage = ReportUtils.getWelcomMessage(report); + if (ReportUtils.isPolicyExpenseChat(report)) { + if (report?.description) { + return parseHtmlToText(report.description); + } + return `${welcomeMessage.phrase1} ${ReportUtils.getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${ReportUtils.getPolicyName(report)} ${welcomeMessage.phrase3}`; + } + + if (ReportUtils.isChatRoom(report)) { + if (report?.description) { + return parseHtmlToText(report.description); + } + return `${welcomeMessage.phrase1} ${welcomeMessage.showReportName ? ReportUtils.getReportName(report) : ''} ${welcomeMessage.phrase2 ?? ''}`; + } + + if (ReportUtils.isSelfDM(report) || ReportUtils.isSystemChat(report)) { + return `${welcomeMessage.phrase1}`; + } + + const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); + const isMultipleParticipant = participantAccountIDs.length > 1; + const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips( + OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, allPersonalDetails), + isMultipleParticipant, + ); + const displayNamesWithTooltipsText = displayNamesWithTooltips + .map(({displayName, pronouns}, index) => { + const formattedText = !pronouns ? displayName : `${displayName} (${pronouns})`; + + if (index === displayNamesWithTooltips.length - 1) { + return `${formattedText}.`; + } + if (index === displayNamesWithTooltips.length - 2) { + return `${formattedText} ${Localize.translateLocal('common.and')}`; + } + if (index < displayNamesWithTooltips.length - 2) { + return `${formattedText},`; + } + + return ''; + }) + .join(' '); + return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; +} export default { getOptionData, getOrderedReportIDs, + getReportBeginningOfChatHistoryMessage, }; From b23327b13f1d025ba93caa396757af4d58fede34 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 1 Jul 2024 15:21:12 +0700 Subject: [PATCH 030/137] run prettier --- src/libs/SidebarUtils.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 1f6fc9a52c74..1cedf7573506 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -16,12 +16,12 @@ import {hasValidDraftComment} from './DraftCommentUtils'; import localeCompare from './LocaleCompare'; import * as LocalePhoneNumber from './LocalePhoneNumber'; import * as Localize from './Localize'; +import {parseHtmlToText} from './OnyxAwareParser'; import * as OptionsListUtils from './OptionsListUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportActionsUtils from './ReportActionsUtils'; import * as ReportUtils from './ReportUtils'; import * as TaskUtils from './TaskUtils'; -import {parseHtmlToText} from './OnyxAwareParser'; const visibleReportActionItems: ReportActions = {}; let allPersonalDetails: OnyxEntry; @@ -465,7 +465,9 @@ function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): stri if (report?.description) { return parseHtmlToText(report.description); } - return `${welcomeMessage.phrase1} ${ReportUtils.getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${ReportUtils.getPolicyName(report)} ${welcomeMessage.phrase3}`; + return `${welcomeMessage.phrase1} ${ReportUtils.getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${ReportUtils.getPolicyName(report)} ${ + welcomeMessage.phrase3 + }`; } if (ReportUtils.isChatRoom(report)) { From e12e507f0f967151874e053a3bf3a4e4f6f9b74c Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 1 Jul 2024 17:49:24 +0700 Subject: [PATCH 031/137] fix: update grouped expense on search page --- src/components/SelectionList/Search/ActionCell.tsx | 2 ++ .../SelectionList/Search/ReportListItem.tsx | 2 -- .../Search/TransactionListItemRow.tsx | 14 +++++++------- src/styles/index.ts | 1 - 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/components/SelectionList/Search/ActionCell.tsx b/src/components/SelectionList/Search/ActionCell.tsx index 6aabfebf0da9..e4730753e61d 100644 --- a/src/components/SelectionList/Search/ActionCell.tsx +++ b/src/components/SelectionList/Search/ActionCell.tsx @@ -53,6 +53,8 @@ function ActionCell({onButtonPress, action = CONST.SEARCH.ACTION_TYPES.VIEW, isL small pressOnEnter style={[styles.w100]} + innerStyles={[styles.bgTransparent]} + textStyles={[styles.link]} /> ); } diff --git a/src/components/SelectionList/Search/ReportListItem.tsx b/src/components/SelectionList/Search/ReportListItem.tsx index f9e8e1951d9a..ed7c6e3a1180 100644 --- a/src/components/SelectionList/Search/ReportListItem.tsx +++ b/src/components/SelectionList/Search/ReportListItem.tsx @@ -147,7 +147,6 @@ function ReportListItem({ {reportItem?.reportName} - {`${reportItem.transactions.length} ${translate('search.groupedExpenses')}`} @@ -172,7 +171,6 @@ function ReportListItem({ )} - {reportItem.transactions.map((transaction) => ( + + + - - - reportListItemTitle: { color: theme.text, fontSize: variables.fontSizeNormal, - fontWeight: FontUtils.fontWeight.bold, }, } satisfies Styles); From 36218136814a2071f56ecdebabfc2cb4b14aa743 Mon Sep 17 00:00:00 2001 From: dominictb Date: Tue, 2 Jul 2024 14:18:55 +0700 Subject: [PATCH 032/137] Fix: Remove unsed lib --- src/components/SelectionList/Search/ReportListItem.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/SelectionList/Search/ReportListItem.tsx b/src/components/SelectionList/Search/ReportListItem.tsx index ed7c6e3a1180..d4fb4a2377b8 100644 --- a/src/components/SelectionList/Search/ReportListItem.tsx +++ b/src/components/SelectionList/Search/ReportListItem.tsx @@ -4,7 +4,6 @@ import BaseListItem from '@components/SelectionList/BaseListItem'; import type {ListItem, ReportListItemProps, ReportListItemType, TransactionListItemType} from '@components/SelectionList/types'; import Text from '@components/Text'; import TextWithTooltip from '@components/TextWithTooltip'; -import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -62,7 +61,6 @@ function ReportListItem({ const reportItem = item as unknown as ReportListItemType; const styles = useThemeStyles(); - const {translate} = useLocalize(); const {isLargeScreenWidth} = useWindowDimensions(); const StyleUtils = useStyleUtils(); From 4b73b4abaf616ee19c4a0008a2e03baffea14cbf Mon Sep 17 00:00:00 2001 From: dominictb Date: Tue, 2 Jul 2024 14:53:01 +0700 Subject: [PATCH 033/137] fix: change order type --- src/components/SelectionList/SearchTableHeader.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/SelectionList/SearchTableHeader.tsx b/src/components/SelectionList/SearchTableHeader.tsx index 6ba753273e8c..ae7422af816d 100644 --- a/src/components/SelectionList/SearchTableHeader.tsx +++ b/src/components/SelectionList/SearchTableHeader.tsx @@ -25,6 +25,12 @@ const SearchColumns: SearchColumnConfig[] = [ shouldShow: () => true, isColumnSortable: false, }, + { + columnName: CONST.SEARCH.TABLE_COLUMNS.TYPE, + translationKey: 'common.type', + shouldShow: () => true, + isColumnSortable: false, + }, { columnName: CONST.SEARCH.TABLE_COLUMNS.DATE, translationKey: 'common.date', @@ -71,12 +77,6 @@ const SearchColumns: SearchColumnConfig[] = [ translationKey: 'common.total', shouldShow: () => true, }, - { - columnName: CONST.SEARCH.TABLE_COLUMNS.TYPE, - translationKey: 'common.type', - shouldShow: () => true, - isColumnSortable: false, - }, { columnName: CONST.SEARCH.TABLE_COLUMNS.ACTION, translationKey: 'common.action', From ffb7b62d45cdbbf2ac730c16d7a45e5d59d2fa26 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Tue, 2 Jul 2024 15:02:40 +0700 Subject: [PATCH 034/137] re-apply missing not found fix --- .../workspace/AccessOrNotFoundWrapper.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 02e5ab13fd86..3f3a7350f375 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -1,5 +1,5 @@ /* eslint-disable rulesdir/no-negated-variables */ -import React, {useEffect} from 'react'; +import React, {useEffect, useState} from 'react'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import type {FullPageNotFoundViewProps} from '@components/BlockingViews/FullPageNotFoundView'; @@ -20,6 +20,7 @@ import type * as OnyxTypes from '@src/types/onyx'; import type {PolicyFeatureName} from '@src/types/onyx/Policy'; import callOrReturn from '@src/types/utils/callOrReturn'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import useNetwork from '@hooks/useNetwork'; const ACCESS_VARIANTS = { [CONST.POLICY.ACCESS_VARIANTS.PAID]: (policy: OnyxEntry) => PolicyUtils.isPaidGroupPolicy(policy), @@ -108,6 +109,7 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps const isPolicyIDInRoute = !!policyID?.length; const isMoneyRequest = !!iouType && IOUUtils.isValidMoneyRequestType(iouType); const isFromGlobalCreate = isEmptyObject(report?.reportID); + const pendingField = featureName ? props.policy?.pendingFields?.[featureName] : undefined; useEffect(() => { if (!isPolicyIDInRoute || !isEmptyObject(policy)) { @@ -123,13 +125,26 @@ function AccessOrNotFoundWrapper({accessVariants = [], fullPageNotFoundViewProps const isFeatureEnabled = featureName ? PolicyUtils.isPolicyFeatureEnabled(policy, featureName) : true; + const [isPolicyFeatureEnabled, setIsPolicyFeatureEnabled] = useState(isFeatureEnabled); + const {isOffline} = useNetwork(); + const isPageAccessible = accessVariants.reduce((acc, variant) => { const accessFunction = ACCESS_VARIANTS[variant]; return acc && accessFunction(policy, login, report, allPolicies ?? null, iouType); }, true); const isPolicyNotAccessible = isEmptyObject(policy) || (Object.keys(policy).length === 1 && !isEmptyObject(policy.errors)) || !policy?.id; - const shouldShowNotFoundPage = (!isMoneyRequest && !isFromGlobalCreate && isPolicyNotAccessible) || !isPageAccessible || !isFeatureEnabled || shouldBeBlocked; + const shouldShowNotFoundPage = (!isMoneyRequest && !isFromGlobalCreate && isPolicyNotAccessible) || !isPageAccessible || !isPolicyFeatureEnabled || shouldBeBlocked; + + // We only update the feature state if it isn't pending. + // This is because the feature state changes several times during the creation of a workspace, while we are waiting for a response from the backend. + // Without this, we can have unexpectedly have 'Not Found' be shown. + useEffect(() => { + if (pendingField && !isOffline && !isFeatureEnabled) { + return; + } + setIsPolicyFeatureEnabled(isFeatureEnabled); + }, [pendingField, isOffline, isFeatureEnabled]); if (shouldShowFullScreenLoadingIndicator) { return ; From 91d090c25387b93223dddfe40e02fe3a0d130117 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 2 Jul 2024 15:17:07 +0700 Subject: [PATCH 035/137] fix logic get welcome text --- src/components/ReportWelcomeText.tsx | 20 ++++++++++---------- src/libs/ReportUtils.ts | 4 ++-- src/libs/SidebarUtils.ts | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index a5c46b82d94a..9368d0c3e7ca 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -42,7 +42,7 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); const isMultipleParticipant = participantAccountIDs.length > 1; const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails), isMultipleParticipant); - const roomWelcomeMessage = ReportUtils.getRoomWelcomeMessage(report); + const welcomeMessage = ReportUtils.getWelcomeMessage(report); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const additionalText = moneyRequestOptions .filter((item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE) @@ -101,11 +101,11 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP ) : ( - {translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne')} + {welcomeMessage.phrase1} {ReportUtils.getDisplayNameForParticipant(report?.ownerAccountID)} - {translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo')} + {welcomeMessage.phrase2} {ReportUtils.getPolicyName(report)} - {translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree')} + {welcomeMessage.phrase3} ))} {isChatRoom && @@ -125,8 +125,8 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP ) : ( - {roomWelcomeMessage.phrase1} - {roomWelcomeMessage.showReportName && ( + {welcomeMessage.phrase1} + {welcomeMessage.showReportName && ( )} - {roomWelcomeMessage.phrase2 !== undefined && {roomWelcomeMessage.phrase2}} + {welcomeMessage.phrase2 !== undefined && {welcomeMessage.phrase2}} ))} {isSelfDM && ( - {translate('reportActionsView.beginningOfChatHistorySelfDM')} + {welcomeMessage.phrase1} )} {isSystemChat && ( - {translate('reportActionsView.beginningOfChatHistorySystemDM')} + {welcomeMessage.phrase1} )} {isDefault && ( - {translate('reportActionsView.beginningOfChatHistory')} + {welcomeMessage.phrase1} {displayNamesWithTooltips.map(({displayName, accountID}, index) => ( // eslint-disable-next-line react/no-array-index-key diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index e083ba9634dd..e7ff19008ebf 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1609,7 +1609,7 @@ function getRoomWelcomeMessage(report: OnyxEntry): WelcomeMessage { return welcomeMessage; } -function getWelcomMessage(report: OnyxEntry): WelcomeMessage { +function getWelcomeMessage(report: OnyxEntry): WelcomeMessage { const welcomeMessage: WelcomeMessage = {showReportName: true}; if (isChatRoom(report)) { return getRoomWelcomeMessage(report); @@ -7178,7 +7178,7 @@ export { getPolicyExpenseChat, getPolicyName, getPolicyType, - getWelcomMessage, + getWelcomeMessage, getReimbursementDeQueuedActionMessage, getReimbursementQueuedActionMessage, getReportActionActorAccountID, diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 1cedf7573506..9776ebda5265 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -460,7 +460,7 @@ function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): stri return Localize.translateLocal('report.noActivityYet'); } - const welcomeMessage = ReportUtils.getWelcomMessage(report); + const welcomeMessage = ReportUtils.getWelcomeMessage(report); if (ReportUtils.isPolicyExpenseChat(report)) { if (report?.description) { return parseHtmlToText(report.description); From 00d5b265b0c8538e0ece52d8b6eaf87654563919 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Wed, 3 Jul 2024 02:53:52 +0530 Subject: [PATCH 036/137] fix: Distance - Start and Stop labels do not change when dragging one over another. Signed-off-by: Krishna Gupta --- src/libs/actions/IOU.ts | 4 ++-- .../request/step/IOURequestStepDistance.tsx | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 48c70021cacc..831291cbd6e5 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -339,8 +339,8 @@ function initMoneyRequest(reportID: string, policy: OnyxEntry, // Add initial empty waypoints when starting a distance expense if (iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE) { comment.waypoints = { - waypoint0: {}, - waypoint1: {}, + waypoint0: {keyForList: 'start_waypoint'}, + waypoint1: {keyForList: 'stop_waypoint'}, }; if (!isFromGlobalCreate) { const customUnitRateID = DistanceRequestUtils.getCustomUnitRateID(reportID); diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 11d5687a55e9..acbec6ece047 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -76,7 +76,15 @@ function IOURequestStepDistance({ const {translate} = useLocalize(); const [optimisticWaypoints, setOptimisticWaypoints] = useState(null); - const waypoints = useMemo(() => optimisticWaypoints ?? transaction?.comment?.waypoints ?? {waypoint0: {}, waypoint1: {}}, [optimisticWaypoints, transaction]); + const waypoints = useMemo( + () => + optimisticWaypoints ?? + transaction?.comment?.waypoints ?? { + waypoint0: {keyForList: 'start_waypoint'}, + waypoint1: {keyForList: 'stop_waypoint'}, + }, + [optimisticWaypoints, transaction], + ); const waypointsList = Object.keys(waypoints); const previousWaypoints = usePrevious(waypoints); const numberOfWaypoints = Object.keys(waypoints).length; @@ -92,7 +100,14 @@ function IOURequestStepDistance({ const isRouteAbsentWithoutErrors = !hasRoute && !hasRouteError; const shouldFetchRoute = (isRouteAbsentWithoutErrors || haveValidatedWaypointsChanged) && !isLoadingRoute && Object.keys(validatedWaypoints).length > 1; const [shouldShowAtLeastTwoDifferentWaypointsError, setShouldShowAtLeastTwoDifferentWaypointsError] = useState(false); - const nonEmptyWaypointsCount = useMemo(() => Object.keys(waypoints).filter((key) => !isEmpty(waypoints[key])).length, [waypoints]); + const nonEmptyWaypointsCount = useMemo( + () => + Object.keys(waypoints).filter((key) => { + const {keyForList, ...waypointWithoutKey} = waypoints[key]; + return !isEmpty(waypointWithoutKey); + }).length, + [waypoints], + ); const duplicateWaypointsError = useMemo( () => nonEmptyWaypointsCount >= 2 && Object.keys(validatedWaypoints).length !== nonEmptyWaypointsCount, [nonEmptyWaypointsCount, validatedWaypoints], From 717e2ec21e34e4ed6fddb1349df0e0588e9d0bb2 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Wed, 3 Jul 2024 03:26:42 +0530 Subject: [PATCH 037/137] minor fix. Signed-off-by: Krishna Gupta --- src/pages/iou/request/step/IOURequestStepDistance.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index acbec6ece047..ac90b126fdc0 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -361,7 +361,9 @@ function IOURequestStepDistance({ data.forEach((waypoint, index) => { newWaypoints[`waypoint${index}`] = waypoints[waypoint] ?? {}; // Find waypoint that BECOMES empty after dragging - if (isEmpty(newWaypoints[`waypoint${index}`]) && !isEmpty(waypoints[`waypoint${index}`] ?? {})) { + const {keyForList, ...newWaypointsWithoutKey} = newWaypoints[`waypoint${index}`]; + const {keyForList: waypointKey, ...waypointWithoutKey} = waypoints[`waypoint${index}`]; + if (isEmpty(newWaypointsWithoutKey) && !isEmpty(waypointWithoutKey ?? {})) { emptyWaypointIndex = index; } }); From d3c7f1318a8d1d9be1d9d0496bf3d220c5a8f13b Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:52:21 +0700 Subject: [PATCH 038/137] Update src/libs/SidebarUtils.ts Co-authored-by: Abdelhafidh Belalia <16493223+s77rt@users.noreply.github.com> --- src/libs/SidebarUtils.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 9776ebda5265..86ca3ab0c604 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -456,9 +456,6 @@ function getOptionData({ return result; } function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string { - if (ReportUtils.isThread(report)) { - return Localize.translateLocal('report.noActivityYet'); - } const welcomeMessage = ReportUtils.getWelcomeMessage(report); if (ReportUtils.isPolicyExpenseChat(report)) { From d949ba064d4c53d071be38e9a66a9dd37b1d63c3 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 3 Jul 2024 16:08:12 +0700 Subject: [PATCH 039/137] fix: logic get begin of chat history --- src/libs/SidebarUtils.ts | 63 ++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 86ca3ab0c604..866a06896681 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -389,7 +389,7 @@ function getOptionData({ } else { result.alternateText = lastMessageTextFromReport.length > 0 ? lastMessageText : ReportActionsUtils.getLastVisibleMessage(report.reportID, {}, lastAction)?.lastMessageText; if (!result.alternateText) { - result.alternateText = ReportUtils.formatReportLastMessageText(getReportBeginningOfChatHistoryMessage(report)) || Localize.translate(preferredLocale, 'report.noActivityYet'); + result.alternateText = ReportUtils.formatReportLastMessageText(getReportBeginningOfChatHistoryMessage(report) ?? ''); } } } else { @@ -455,8 +455,7 @@ function getOptionData({ return result; } -function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string { - +function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string | undefined { const welcomeMessage = ReportUtils.getWelcomeMessage(report); if (ReportUtils.isPolicyExpenseChat(report)) { if (report?.description) { @@ -477,31 +476,39 @@ function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): stri if (ReportUtils.isSelfDM(report) || ReportUtils.isSystemChat(report)) { return `${welcomeMessage.phrase1}`; } - - const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); - const isMultipleParticipant = participantAccountIDs.length > 1; - const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips( - OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, allPersonalDetails), - isMultipleParticipant, - ); - const displayNamesWithTooltipsText = displayNamesWithTooltips - .map(({displayName, pronouns}, index) => { - const formattedText = !pronouns ? displayName : `${displayName} (${pronouns})`; - - if (index === displayNamesWithTooltips.length - 1) { - return `${formattedText}.`; - } - if (index === displayNamesWithTooltips.length - 2) { - return `${formattedText} ${Localize.translateLocal('common.and')}`; - } - if (index < displayNamesWithTooltips.length - 2) { - return `${formattedText},`; - } - - return ''; - }) - .join(' '); - return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; + const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); + const isChatRoom = ReportUtils.isChatRoom(report); + const isSelfDM = ReportUtils.isSelfDM(report); + const isInvoiceRoom = ReportUtils.isInvoiceRoom(report); + const isSystemChat = ReportUtils.isSystemChat(report); + const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat); + + if (isDefault) { + const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); + const isMultipleParticipant = participantAccountIDs.length > 1; + const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips( + OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, allPersonalDetails), + isMultipleParticipant, + ); + const displayNamesWithTooltipsText = displayNamesWithTooltips + .map(({displayName, pronouns}, index) => { + const formattedText = !pronouns ? displayName : `${displayName} (${pronouns})`; + + if (index === displayNamesWithTooltips.length - 1) { + return `${formattedText}.`; + } + if (index === displayNamesWithTooltips.length - 2) { + return `${formattedText} ${Localize.translateLocal('common.and')}`; + } + if (index < displayNamesWithTooltips.length - 2) { + return `${formattedText},`; + } + + return ''; + }) + .join(' '); + return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; + } } export default { From 6ef8464a0befa020edf9a0616fc4d65db9b4f9ae Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Thu, 4 Jul 2024 08:36:52 +0700 Subject: [PATCH 040/137] hide task report by default --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index e16c5c7abe56..779d12fdd713 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5134,7 +5134,7 @@ function buildOptimisticTaskReport( title?: string, description?: string, policyID: string = CONST.POLICY.OWNER_EMAIL_FAKE, - notificationPreference: NotificationPreference = CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, + notificationPreference: NotificationPreference = CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, ): OptimisticTaskReport { const participants: Participants = { [ownerAccountID]: { From 3bf9ce93f106b6f2995318dfc295e32efb3d39b4 Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 4 Jul 2024 10:27:39 +0700 Subject: [PATCH 041/137] Feat: Update styles --- src/components/Button/index.tsx | 13 ++++++++++++- src/components/SelectionList/Search/ActionCell.tsx | 8 +++++--- .../SelectionList/Search/ReportListItem.tsx | 2 -- .../SelectionList/Search/TransactionListItemRow.tsx | 1 + src/styles/index.ts | 9 ++++----- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 88ae8d48a871..1ffbf496f4ab 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -1,6 +1,6 @@ import {useIsFocused} from '@react-navigation/native'; import type {ForwardedRef} from 'react'; -import React, {useCallback, useMemo} from 'react'; +import React, {useCallback, useMemo, useState} from 'react'; import type {GestureResponderEvent, StyleProp, TextStyle, ViewStyle} from 'react-native'; import {ActivityIndicator, View} from 'react-native'; import Icon from '@components/Icon'; @@ -89,6 +89,9 @@ type ButtonProps = Partial & { /** Whether we should use the danger theme color */ danger?: boolean; + /** Whether we should display the button as a link */ + link?: boolean; + /** Should we remove the right border radius top + bottom? */ shouldRemoveRightBorderRadius?: boolean; @@ -202,6 +205,7 @@ function Button( id = '', accessibilityLabel = '', isSplitButton = false, + link = false, ...rest }: ButtonProps, ref: ForwardedRef, @@ -209,6 +213,7 @@ function Button( const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); + const [isHovered, setIsHovered] = useState(false); const renderContent = () => { if ('children' in rest) { @@ -229,6 +234,9 @@ function Button( danger && styles.buttonDangerText, !!icon && styles.textAlignLeft, textStyles, + link && styles.link, + link && isHovered && styles.linkHover, + link && styles.fontWeightNormal, ]} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} > @@ -339,6 +347,7 @@ function Button( // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing text && shouldShowRightIcon ? styles.alignItemsStretch : undefined, innerStyles, + link && styles.bgTransparent, ]} hoverStyle={[ shouldUseDefaultHover && !isDisabled ? styles.buttonDefaultHovered : undefined, @@ -349,6 +358,8 @@ function Button( accessibilityLabel={accessibilityLabel} role={CONST.ROLE.BUTTON} hoverDimmingValue={1} + onHoverIn={() => setIsHovered(true)} + onHoverOut={() => setIsHovered(false)} > {renderContent()} {isLoading && ( diff --git a/src/components/SelectionList/Search/ActionCell.tsx b/src/components/SelectionList/Search/ActionCell.tsx index f594c10866e1..2e1a79d25464 100644 --- a/src/components/SelectionList/Search/ActionCell.tsx +++ b/src/components/SelectionList/Search/ActionCell.tsx @@ -15,9 +15,10 @@ type ActionCellProps = { action?: string; isLargeScreenWidth?: boolean; isSelected?: boolean; + isChildListItem?: boolean; }; -function ActionCell({onButtonPress, action = CONST.SEARCH.ACTION_TYPES.VIEW, isLargeScreenWidth = true, isSelected = false}: ActionCellProps) { +function ActionCell({onButtonPress, action = CONST.SEARCH.ACTION_TYPES.VIEW, isLargeScreenWidth = true, isSelected = false, isChildListItem = false}: ActionCellProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); @@ -54,8 +55,9 @@ function ActionCell({onButtonPress, action = CONST.SEARCH.ACTION_TYPES.VIEW, isL small pressOnEnter style={[styles.w100]} - innerStyles={[isSelected ? styles.buttonDefaultHovered : {}, styles.bgTransparent]} - textStyles={[styles.link]} + innerStyles={[isSelected ? styles.buttonDefaultHovered : {}]} + link={isChildListItem} + shouldUseDefaultHover={!isChildListItem} /> ); } diff --git a/src/components/SelectionList/Search/ReportListItem.tsx b/src/components/SelectionList/Search/ReportListItem.tsx index 862cd0b3e2aa..12f62b35ca84 100644 --- a/src/components/SelectionList/Search/ReportListItem.tsx +++ b/src/components/SelectionList/Search/ReportListItem.tsx @@ -170,8 +170,6 @@ function ReportListItem({ {isLargeScreenWidth && ( <> - {/** We add an empty view with type style to align the total with the table header */} - diff --git a/src/styles/index.ts b/src/styles/index.ts index 22258cf379c0..8b63f220afbf 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -584,6 +584,10 @@ const styles = (theme: ThemeColors) => borderRadius: variables.buttonBorderRadius, }, + linkHover: { + color: theme.linkHover, + }, + buttonText: { color: theme.text, fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, @@ -5039,11 +5043,6 @@ const styles = (theme: ThemeColors) => height: 172, }, - reportListItemSeparator: { - borderBottomWidth: 1, - borderBottomColor: theme.activeComponentBG, - }, - reportListItemTitle: { color: theme.text, fontSize: variables.fontSizeNormal, From 94509ed112db81a46778721c19460804736a628e Mon Sep 17 00:00:00 2001 From: dominictb Date: Thu, 4 Jul 2024 10:35:49 +0700 Subject: [PATCH 042/137] Fix: Lint --- .../SelectionList/Search/ReportListItem.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/SelectionList/Search/ReportListItem.tsx b/src/components/SelectionList/Search/ReportListItem.tsx index 12f62b35ca84..d45b064ff48d 100644 --- a/src/components/SelectionList/Search/ReportListItem.tsx +++ b/src/components/SelectionList/Search/ReportListItem.tsx @@ -169,16 +169,14 @@ function ReportListItem({ {isLargeScreenWidth && ( - <> - - - - + + + )} {reportItem.transactions.map((transaction) => ( From 5983a4b6d66910e67df716640e49ecaabe0da187 Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 4 Jul 2024 14:28:38 +0200 Subject: [PATCH 043/137] setting the default to not initialize --- android/app/build.gradle | 1 + ios/NewExpensify/Info.plist | 2 ++ 2 files changed, 3 insertions(+) diff --git a/android/app/build.gradle b/android/app/build.gradle index 5b21487d92cd..6936f77cc2ec 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -15,6 +15,7 @@ fullstory { org 'o-1WN56P-na1' enabledVariants 'all' logcatLevel 'debug' + recordOnStart false } react { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index c1aae6e1265d..1f0e6389aa7c 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -45,6 +45,8 @@ OrgId o-1WN56P-na1 + RecordOnStart + ITSAppUsesNonExemptEncryption From 986c7a238e39d9e65251c93ac6b8ad7b3d28276a Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 4 Jul 2024 14:28:54 +0200 Subject: [PATCH 044/137] adding init function --- src/libs/Fullstory/index.native.ts | 14 ++++++++++++++ src/libs/Fullstory/index.ts | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/src/libs/Fullstory/index.native.ts b/src/libs/Fullstory/index.native.ts index 4a7551beca77..01b88b2d5d82 100644 --- a/src/libs/Fullstory/index.native.ts +++ b/src/libs/Fullstory/index.native.ts @@ -2,12 +2,26 @@ import FullStory, {FSPage} from '@fullstory/react-native'; import type {OnyxEntry} from 'react-native-onyx'; import * as Environment from '@src/libs/Environment/Environment'; import type {UserMetadata} from '@src/types/onyx'; +import CONST from '@src/CONST'; /** * Fullstory React-Native lib adapter * Proxy function calls to React-Native lib * */ const FS = { + /** + * Initializes FullStory + */ + init: () => { + Environment.getEnvironment().then((envName: string) => { + // We don't want to + if(envName === CONST.ENVIRONMENT.STAGING) { + return; + } + FullStory.restart(); + }) + }, + /** * Sets the identity as anonymous using the FullStory library. */ diff --git a/src/libs/Fullstory/index.ts b/src/libs/Fullstory/index.ts index a9c75ad838e9..f109e4ee0a27 100644 --- a/src/libs/Fullstory/index.ts +++ b/src/libs/Fullstory/index.ts @@ -92,6 +92,11 @@ const FS = { }); } }, + + /** + * Init function, created so we're consistent with the native file + */ + init: () => {} }; export default FS; From ac96537d60af19a540fd7994c90aa52e702a2f42 Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 4 Jul 2024 14:30:53 +0200 Subject: [PATCH 045/137] initilizing fullstory lib --- src/Expensify.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index bfe4db13d9c4..d8f103c573a5 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -8,6 +8,7 @@ import ConfirmModal from './components/ConfirmModal'; import DeeplinkWrapper from './components/DeeplinkWrapper'; import EmojiPicker from './components/EmojiPicker/EmojiPicker'; import FocusModeNotification from './components/FocusModeNotification'; +import FS from '@libs/Fullstory'; import GrowlNotification from './components/GrowlNotification'; import AppleAuthWrapper from './components/SignInButtons/AppleAuthWrapper'; import SplashScreenHider from './components/SplashScreenHider'; @@ -147,6 +148,9 @@ function Expensify({ // Initialize this client as being an active client ActiveClientManager.init(); + // Initialize Fullstory lib + FS.init(); + // Used for the offline indicator appearing when someone is offline const unsubscribeNetInfo = NetworkConnection.subscribeToNetInfo(); From a8499034b3c7f3a8dd658cf2a2df1f87c054e3f5 Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 4 Jul 2024 14:34:44 +0200 Subject: [PATCH 046/137] only load fullstory in production --- web/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/index.html b/web/index.html index 41c85ec188da..acccbbe4f442 100644 --- a/web/index.html +++ b/web/index.html @@ -118,7 +118,7 @@ - <% if (htmlWebpackPlugin.options.isWeb && (htmlWebpackPlugin.options.isProduction || htmlWebpackPlugin.options.isStaging)) { %> + <% if (htmlWebpackPlugin.options.isWeb && htmlWebpackPlugin.options.isProduction) { %> @@ -126,7 +126,7 @@ - <% if (htmlWebpackPlugin.options.isWeb && (htmlWebpackPlugin.options.isProduction || htmlWebpackPlugin.options.isStaging)) { %> + <% if (htmlWebpackPlugin.options.isWeb && htmlWebpackPlugin.options.isProduction) { %> From 791f7f865da2a4ebeb40dabbb0d1c6acad830c54 Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Thu, 4 Jul 2024 14:34:56 +0200 Subject: [PATCH 047/137] only start fullstory on mobile in production --- src/libs/Fullstory/index.native.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/Fullstory/index.native.ts b/src/libs/Fullstory/index.native.ts index 01b88b2d5d82..2bdeca9e5a63 100644 --- a/src/libs/Fullstory/index.native.ts +++ b/src/libs/Fullstory/index.native.ts @@ -14,11 +14,11 @@ const FS = { */ init: () => { Environment.getEnvironment().then((envName: string) => { - // We don't want to - if(envName === CONST.ENVIRONMENT.STAGING) { - return; + // We only want to start fullstory if the app is running in + // production + if(envName === CONST.ENVIRONMENT.PRODUCTION) { + FullStory.restart(); } - FullStory.restart(); }) }, From 0f1a618ba6ec9a0ad94284639a83fb30e8ba460e Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 4 Jul 2024 22:34:43 +0800 Subject: [PATCH 048/137] show the payable amount --- .../ReportActionItem/ReportPreview.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 9693b982ec4a..26fa308f6f89 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -128,6 +128,7 @@ function ReportPreview({ const [isHoldMenuVisible, setIsHoldMenuVisible] = useState(false); const [requestType, setRequestType] = useState(); const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(iouReport, policy); + const hasOnlyHeldExpenses = ReportUtils.hasOnlyHeldExpenses(iouReport?.reportID ?? ''); const {isSmallScreenWidth} = useWindowDimensions(); const [paymentType, setPaymentType] = useState(); @@ -204,6 +205,18 @@ function ReportPreview({ } }; + const getSettlementAmount = () => { + if (hasOnlyHeldExpenses) { + return ''; + } + + if (ReportUtils.hasHeldExpenses(iouReport?.reportID) && canAllowSettlement) { + return nonHeldAmount; + } + + return CurrencyUtils.convertToDisplayString(reimbursableSpend, iouReport?.currency); + } + const getDisplayAmount = (): string => { if (totalDisplaySpend) { return CurrencyUtils.convertToDisplayString(totalDisplaySpend, iouReport?.currency); @@ -415,7 +428,7 @@ function ReportPreview({ {shouldShowSettlementButton && ( {isHoldMenuVisible && iouReport && requestType !== undefined && ( Date: Fri, 5 Jul 2024 11:10:35 +0700 Subject: [PATCH 049/137] Add hold option to report detail page for combine report --- src/pages/ReportDetailsPage.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index b04e56f288e9..2f477a58912c 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -165,7 +165,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD // 2. MoneyReport case if (caseID === CASES.MONEY_REPORT) { if (!reportActions || !transactionThreadReport?.parentReportActionID) { - return null; + return undefined; } return reportActions.find((action) => action.reportActionID === transactionThreadReport.parentReportActionID); } @@ -183,6 +183,8 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD return report; }, [caseID, parentReport, report]); + const moneyRequestAction = transactionThreadReportID ? requestParentReportAction : parentReportAction; + const canModifyTask = Task.canModifyTask(report, session?.accountID ?? -1); const shouldShowTaskDeleteButton = isTaskReport && @@ -446,9 +448,11 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD ? ReportActionsUtils.getOriginalMessage(requestParentReportAction)?.IOUTransactionID ?? '' : ''; - const canHoldUnholdReportAction = ReportUtils.canHoldUnholdReportAction(parentReportAction); + const canHoldUnholdReportAction = ReportUtils.canHoldUnholdReportAction(moneyRequestAction); const shouldShowHoldAction = - caseID !== CASES.MONEY_REPORT && (canHoldUnholdReportAction.canHoldRequest || canHoldUnholdReportAction.canUnholdRequest) && !ReportUtils.isArchivedRoom(parentReport); + caseID !== CASES.DEFAULT && + (canHoldUnholdReportAction.canHoldRequest || canHoldUnholdReportAction.canUnholdRequest) && + !ReportUtils.isArchivedRoom(transactionThreadReportID ? report : parentReport); const canJoin = ReportUtils.canJoinChat(report, parentReportAction, policy); @@ -460,7 +464,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD } if (isExpenseReport && shouldShowHoldAction) { - result.push(PromotedActions.hold({isTextHold: canHoldUnholdReportAction.canHoldRequest, reportAction: parentReportAction})); + result.push(PromotedActions.hold({isTextHold: canHoldUnholdReportAction.canHoldRequest, reportAction: moneyRequestAction})); } if (report) { @@ -470,7 +474,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD result.push(PromotedActions.share(report)); return result; - }, [report, parentReportAction, canJoin, isExpenseReport, shouldShowHoldAction, canHoldUnholdReportAction.canHoldRequest]); + }, [report, moneyRequestAction, canJoin, isExpenseReport, shouldShowHoldAction, canHoldUnholdReportAction.canHoldRequest]); const nameSectionExpenseIOU = ( From 208bd883f93399e5b9a9c4d6608b9ec6b9a17fea Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Fri, 5 Jul 2024 11:36:55 +0700 Subject: [PATCH 050/137] consistent logic --- src/libs/ReportUtils.ts | 5 ++++- src/libs/SidebarUtils.ts | 28 ++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 901ccd0a78f5..bf0daf198a07 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1680,7 +1680,10 @@ function getWelcomeMessage(report: OnyxEntry): WelcomeMessage { return welcomeMessage; } - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); + if (!(isChatRoom(report) || isPolicyExpenseChat(report) || isSelfDM(report) || isInvoiceRoom(report) || isSystemChat(report))) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); + } + return welcomeMessage; } diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index bcb9d7ac392d..d88b7ec048df 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -393,7 +393,8 @@ function getOptionData({ } else { result.alternateText = lastMessageTextFromReport.length > 0 ? lastMessageText : ReportActionsUtils.getLastVisibleMessage(report.reportID, {}, lastAction)?.lastMessageText; if (!result.alternateText) { - result.alternateText = ReportUtils.formatReportLastMessageText(getReportBeginningOfChatHistoryMessage(report) ?? ''); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + result.alternateText = ReportUtils.formatReportLastMessageText(getReportBeginningOfChatHistoryMessage(report) || Localize.translateLocal('report.noActivityYet')); } } } else { @@ -461,7 +462,18 @@ function getOptionData({ } function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string | undefined { const welcomeMessage = ReportUtils.getWelcomeMessage(report); - if (ReportUtils.isPolicyExpenseChat(report)) { + const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); + const isChatRoom = ReportUtils.isChatRoom(report); + const isSelfDM = ReportUtils.isSelfDM(report); + const isInvoiceRoom = ReportUtils.isInvoiceRoom(report); + const isSystemChat = ReportUtils.isSystemChat(report); + const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat); + + if (ReportUtils.isChatThread(report)) { + return ''; + } + + if (isPolicyExpenseChat) { if (report?.description) { return parseHtmlToText(report.description); } @@ -470,22 +482,16 @@ function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): stri }`; } - if (ReportUtils.isChatRoom(report)) { + if (isChatRoom) { if (report?.description) { return parseHtmlToText(report.description); } return `${welcomeMessage.phrase1} ${welcomeMessage.showReportName ? ReportUtils.getReportName(report) : ''} ${welcomeMessage.phrase2 ?? ''}`; } - if (ReportUtils.isSelfDM(report) || ReportUtils.isSystemChat(report)) { + if (isSelfDM || isSystemChat) { return `${welcomeMessage.phrase1}`; } - const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); - const isChatRoom = ReportUtils.isChatRoom(report); - const isSelfDM = ReportUtils.isSelfDM(report); - const isInvoiceRoom = ReportUtils.isInvoiceRoom(report); - const isSystemChat = ReportUtils.isSystemChat(report); - const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat); if (isDefault) { const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); @@ -513,6 +519,8 @@ function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): stri .join(' '); return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; } + + return ''; } export default { From f55184a12568b98ce5a6b3e97c72310d6507a955 Mon Sep 17 00:00:00 2001 From: dominictb Date: Fri, 5 Jul 2024 18:18:35 +0700 Subject: [PATCH 051/137] fix set minHeight to header report and update ActionCell --- src/components/SelectionList/Search/ActionCell.tsx | 5 +++-- src/components/SelectionList/Search/ReportListItem.tsx | 3 ++- .../SelectionList/Search/TransactionListItemRow.tsx | 3 +++ src/styles/utils/sizing.ts | 3 +++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/components/SelectionList/Search/ActionCell.tsx b/src/components/SelectionList/Search/ActionCell.tsx index 2e1a79d25464..f863ee77fce1 100644 --- a/src/components/SelectionList/Search/ActionCell.tsx +++ b/src/components/SelectionList/Search/ActionCell.tsx @@ -16,15 +16,16 @@ type ActionCellProps = { isLargeScreenWidth?: boolean; isSelected?: boolean; isChildListItem?: boolean; + parentAction?: string; }; -function ActionCell({onButtonPress, action = CONST.SEARCH.ACTION_TYPES.VIEW, isLargeScreenWidth = true, isSelected = false, isChildListItem = false}: ActionCellProps) { +function ActionCell({onButtonPress, action = CONST.SEARCH.ACTION_TYPES.VIEW, isLargeScreenWidth = true, isSelected = false, isChildListItem = false, parentAction = ''}: ActionCellProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); const StyleUtils = useStyleUtils(); - if (action === CONST.SEARCH.ACTION_TYPES.PAID || action === CONST.SEARCH.ACTION_TYPES.DONE) { + if ((parentAction !== CONST.SEARCH.ACTION_TYPES.PAID && action === CONST.SEARCH.ACTION_TYPES.PAID) || action === CONST.SEARCH.ACTION_TYPES.DONE) { const buttonTextKey = action === CONST.SEARCH.ACTION_TYPES.PAID ? 'iou.settledExpensify' : 'common.done'; return ( diff --git a/src/components/SelectionList/Search/ReportListItem.tsx b/src/components/SelectionList/Search/ReportListItem.tsx index a1d8994c02b9..c0982c0a448e 100644 --- a/src/components/SelectionList/Search/ReportListItem.tsx +++ b/src/components/SelectionList/Search/ReportListItem.tsx @@ -143,7 +143,7 @@ function ReportListItem({ onButtonPress={handleOnButtonPress} /> )} - + {canSelectMultiple && ( @@ -181,6 +181,7 @@ function ReportListItem({ {reportItem.transactions.map((transaction) => ( { diff --git a/src/components/SelectionList/Search/TransactionListItemRow.tsx b/src/components/SelectionList/Search/TransactionListItemRow.tsx index dfc53e3a4b41..51c11ebc5480 100644 --- a/src/components/SelectionList/Search/TransactionListItemRow.tsx +++ b/src/components/SelectionList/Search/TransactionListItemRow.tsx @@ -51,6 +51,7 @@ type TransactionListItemRowProps = { isDisabled: boolean; canSelectMultiple: boolean; isButtonSelected?: boolean; + parentAction?: string; }; const getTypeIcon = (type?: SearchTransactionType) => { @@ -225,6 +226,7 @@ function TransactionListItemRow({ containerStyle, isChildListItem = false, isButtonSelected = false, + parentAction = '', }: TransactionListItemRowProps) { const styles = useThemeStyles(); const {isLargeScreenWidth} = useWindowDimensions(); @@ -388,6 +390,7 @@ function TransactionListItemRow({ action={item.action} isSelected={isButtonSelected} isChildListItem={isChildListItem} + parentAction={parentAction} /> diff --git a/src/styles/utils/sizing.ts b/src/styles/utils/sizing.ts index d0855b47f2bd..574bef6b10d4 100644 --- a/src/styles/utils/sizing.ts +++ b/src/styles/utils/sizing.ts @@ -41,6 +41,9 @@ export default { mnh20: { minHeight: 80, }, + mnh40: { + minHeight: 40, + }, mnh0: { minHeight: 0, From 4b9db5fd1293a5d0d4fa3b8cfbd0055f1fc392fa Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Fri, 5 Jul 2024 14:35:40 +0200 Subject: [PATCH 052/137] add condition for old dot messages --- src/pages/home/report/ContextMenu/ContextMenuActions.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 7102c9878dca..78a1841e373b 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -403,6 +403,9 @@ const ContextMenuActions: ContextMenuAction[] = [ Clipboard.setString(Localize.translateLocal('iou.heldExpense')); } else if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.UNHOLD) { Clipboard.setString(Localize.translateLocal('iou.unheldExpense')); + } else if (ReportActionsUtils.isOldDotReportAction(reportAction)) { + const oldDotActionMessage = ReportActionsUtils.getMessageOfOldDotReportAction(reportAction); + Clipboard.setString(oldDotActionMessage); } else if (content) { setClipboardMessage( content.replace(/()(.*?)(<\/mention-user>)/gi, (match, openTag: string, innerContent: string, closeTag: string): string => { From cc0423b159d5c9f9258dd375d604459ef6330915 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Sat, 6 Jul 2024 20:12:40 +0300 Subject: [PATCH 053/137] set pending fields as none --- src/libs/actions/Policy/Category.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index b68c8a8c082b..f9da0ece9a2c 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -376,6 +376,9 @@ function setPolicyCategoryPayrollCode(policyID: string, categoryName: string, pa ...policyCategoryToUpdate, errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('workspace.categories.updatePayrollCodeFailureMessage'), pendingAction: null, + pendingFields: { + payrollCode: null, + }, }, }, }, From d7f3aa433776f02b3bdd8451de9e7c22a8e7e37a Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Sat, 6 Jul 2024 20:23:36 +0300 Subject: [PATCH 054/137] use useonyx --- .../categories/CategoryPayrollCodePage.tsx | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx index bc8666effb74..58174c7738d2 100644 --- a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx +++ b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx @@ -1,7 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback} from 'react'; -import {withOnyx} from 'react-native-onyx'; -import type {OnyxEntry} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; import type {FormOnyxValues} from '@components/Form/types'; @@ -20,31 +19,28 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/WorkspaceCategoryForm'; -import type {PolicyCategories} from '@src/types/onyx'; -type WorkspaceEditCategoryPayrollCodePageOnyxProps = { - /** Collection of categories attached to a policy */ - policyCategories: OnyxEntry; -}; +type EditCategoryPageProps = StackScreenProps; -type EditCategoryPageProps = WorkspaceEditCategoryPayrollCodePageOnyxProps & StackScreenProps; - -function CategoryPayrollCodePage({route, policyCategories}: EditCategoryPageProps) { +function CategoryPayrollCodePage({route}: EditCategoryPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const policyId = route.params.policyID ?? '-1'; + const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyId}`); + const categoryName = route.params.categoryName; - const glCode = policyCategories?.[categoryName]?.payrollCode; + const payrollCode = policyCategories?.[categoryName]?.payrollCode; const {inputCallbackRef} = useAutoFocusInput(); const editGLCode = useCallback( (values: FormOnyxValues) => { - const newGLCode = values.payrollCode.trim(); - if (newGLCode !== glCode) { - Category.setPolicyCategoryPayrollCode(route.params.policyID, categoryName, newGLCode); + const newPayrollCode = values.payrollCode.trim(); + if (newPayrollCode !== payrollCode) { + Category.setPolicyCategoryPayrollCode(route.params.policyID, categoryName, newPayrollCode); } Navigation.goBack(); }, - [categoryName, glCode, route.params.policyID], + [categoryName, payrollCode, route.params.policyID], ); return ( @@ -73,7 +69,7 @@ function CategoryPayrollCodePage({route, policyCategories}: EditCategoryPageProp ({ - policyCategories: { - key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route?.params?.policyID}`, - }, -})(CategoryPayrollCodePage); +export default CategoryPayrollCodePage; From 3bb29bcb0ac6f5c006690bfcc6511a4b28a21e75 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Sat, 6 Jul 2024 20:25:44 +0300 Subject: [PATCH 055/137] add fallback navigation --- src/pages/workspace/categories/CategoryPayrollCodePage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx index 58174c7738d2..85aa031d3fc4 100644 --- a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx +++ b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx @@ -38,9 +38,9 @@ function CategoryPayrollCodePage({route}: EditCategoryPageProps) { if (newPayrollCode !== payrollCode) { Category.setPolicyCategoryPayrollCode(route.params.policyID, categoryName, newPayrollCode); } - Navigation.goBack(); + Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(route.params.policyID, route.params.categoryName)); }, - [categoryName, payrollCode, route.params.policyID], + [categoryName, payrollCode, route.params.categoryName, route.params.policyID], ); return ( From 5e7d6a1735110f27eb687be4d20aa5515430d41f Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Mon, 8 Jul 2024 11:18:13 +0100 Subject: [PATCH 056/137] adjusting style, and calling fsIdentify on restart --- src/Expensify.tsx | 2 +- src/libs/Fullstory/index.native.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Expensify.tsx b/src/Expensify.tsx index d8f103c573a5..5122a4bffbe8 100644 --- a/src/Expensify.tsx +++ b/src/Expensify.tsx @@ -4,11 +4,11 @@ import type {NativeEventSubscription} from 'react-native'; import {AppState, Linking, NativeModules} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Onyx, {withOnyx} from 'react-native-onyx'; +import FS from './libs/Fullstory'; import ConfirmModal from './components/ConfirmModal'; import DeeplinkWrapper from './components/DeeplinkWrapper'; import EmojiPicker from './components/EmojiPicker/EmojiPicker'; import FocusModeNotification from './components/FocusModeNotification'; -import FS from '@libs/Fullstory'; import GrowlNotification from './components/GrowlNotification'; import AppleAuthWrapper from './components/SignInButtons/AppleAuthWrapper'; import SplashScreenHider from './components/SplashScreenHider'; diff --git a/src/libs/Fullstory/index.native.ts b/src/libs/Fullstory/index.native.ts index 2bdeca9e5a63..ac5656fc1ed5 100644 --- a/src/libs/Fullstory/index.native.ts +++ b/src/libs/Fullstory/index.native.ts @@ -1,8 +1,9 @@ import FullStory, {FSPage} from '@fullstory/react-native'; -import type {OnyxEntry} from 'react-native-onyx'; +import {useOnyx, type OnyxEntry} from 'react-native-onyx'; import * as Environment from '@src/libs/Environment/Environment'; import type {UserMetadata} from '@src/types/onyx'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; /** * Fullstory React-Native lib adapter @@ -16,9 +17,12 @@ const FS = { Environment.getEnvironment().then((envName: string) => { // We only want to start fullstory if the app is running in // production - if(envName === CONST.ENVIRONMENT.PRODUCTION) { - FullStory.restart(); + if(envName !== CONST.ENVIRONMENT.PRODUCTION) { + return; } + FullStory.restart(); + const [session] = useOnyx(ONYXKEYS.USER_METADATA); + FS.fsIdentify(session); }) }, From 4dc85fdd1fa283dc217fc7e565c0e3a7b0efc8e5 Mon Sep 17 00:00:00 2001 From: dominictb Date: Mon, 8 Jul 2024 17:44:44 +0700 Subject: [PATCH 057/137] update view link font size --- src/components/Button/index.tsx | 1 + src/styles/index.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 1ffbf496f4ab..494bb56672ad 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -237,6 +237,7 @@ function Button( link && styles.link, link && isHovered && styles.linkHover, link && styles.fontWeightNormal, + link && styles.fontSizeLabel, ]} dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}} > diff --git a/src/styles/index.ts b/src/styles/index.ts index ed0d0cd212da..1686e9338409 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -340,6 +340,9 @@ const styles = (theme: ThemeColors) => appBG: { backgroundColor: theme.appBG, }, + fontSizeLabel: { + fontSize: variables.fontSizeLabel, + }, h4: { fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, From 43a2873a59beee30881f946d504b8f84f682a4d0 Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Mon, 8 Jul 2024 11:51:22 +0100 Subject: [PATCH 058/137] fix lint --- src/libs/Fullstory/index.native.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/Fullstory/index.native.ts b/src/libs/Fullstory/index.native.ts index ac5656fc1ed5..52c70d1700b8 100644 --- a/src/libs/Fullstory/index.native.ts +++ b/src/libs/Fullstory/index.native.ts @@ -1,5 +1,6 @@ import FullStory, {FSPage} from '@fullstory/react-native'; -import {useOnyx, type OnyxEntry} from 'react-native-onyx'; +import {type OnyxEntry} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import * as Environment from '@src/libs/Environment/Environment'; import type {UserMetadata} from '@src/types/onyx'; import CONST from '@src/CONST'; From 046a0244450a6f6272e988725e76f8fd64d427f4 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Mon, 8 Jul 2024 16:50:25 +0300 Subject: [PATCH 059/137] Add Card reconciliation account setting --- src/ROUTES.ts | 16 ++++++++ src/SCREENS.ts | 4 ++ src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../ModalStackNavigators/index.tsx | 8 ++++ .../FULL_SCREEN_TO_RHP_MAPPING.ts | 4 ++ src/libs/Navigation/linkingConfig/config.ts | 4 ++ src/libs/Navigation/types.ts | 12 ++++++ .../accounting/PolicyAccountingPage.tsx | 20 ++++++++-- .../ReconciliationAccountSettingsPage.tsx | 37 +++++++++++++++++++ 10 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 2347bd4f93f4..e5c1b747c458 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -534,6 +534,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/export', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/export` as const, }, + POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CARD_RECONCILIATION: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-online/card-reconciliation', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/card-reconciliation` as const, + }, POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/export/company-card-expense-account', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/export/company-card-expense-account` as const, @@ -932,6 +936,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/xero/import/taxes', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/taxes` as const, }, + POLICY_ACCOUNTING_XERO_CARD_RECONCILIATION: { + route: 'settings/workspaces/:policyID/accounting/xero/card-reconciliation', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/card-reconciliation` as const, + }, POLICY_ACCOUNTING_XERO_EXPORT: { route: 'settings/workspaces/:policyID/accounting/xero/export', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/export` as const, @@ -1021,6 +1029,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/connections/netsuite/export/', getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/netsuite/export/` as const, }, + POLICY_ACCOUNTING_NETSUITE_CARD_RECONCILIATION: { + route: 'settings/workspaces/:policyID/connections/netsuite/card-reconciliation', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/netsuite/card-reconciliation` as const, + }, POLICY_ACCOUNTING_NETSUITE_PREFERRED_EXPORTER_SELECT: { route: 'settings/workspaces/:policyID/connections/netsuite/export/preferred-exporter/select', getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/netsuite/export/preferred-exporter/select` as const, @@ -1090,6 +1102,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/sage-intacct/existing-connections', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/existing-connections` as const, }, + POLICY_ACCOUNTING_SAGE_INTACCT_CARD_RECONCILIATION: { + route: 'settings/workspaces/:policyID/accounting/sage-intacct/card-reconciliation', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/card-reconciliation` as const, + }, } as const; /** diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 8d077d635fcc..6c36a43d0ef4 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -251,6 +251,7 @@ const SCREENS = { QUICKBOOKS_ONLINE_LOCATIONS: 'Policy_Accounting_Quickbooks_Online_Import_Locations', QUICKBOOKS_ONLINE_TAXES: 'Policy_Accounting_Quickbooks_Online_Import_Taxes', QUICKBOOKS_ONLINE_EXPORT: 'Workspace_Accounting_Quickbooks_Online_Export', + QUICKBOOKS_ONLINE_CARD_RECONCILIATION: 'Workspace_Accounting_Quickbooks_Online_Card_Reconciliation', QUICKBOOKS_ONLINE_EXPORT_DATE_SELECT: 'Workspace_Accounting_Quickbooks_Online_Export_Date_Select', QUICKBOOKS_ONLINE_EXPORT_INVOICE_ACCOUNT_SELECT: 'Workspace_Accounting_Quickbooks_Online_Export_Invoice_Account_Select', QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT: 'Workspace_Accounting_Quickbooks_Online_Export_Company_Card_Expense', @@ -269,6 +270,7 @@ const SCREENS = { XERO_CHART_OF_ACCOUNTS: 'Policy_Accounting_Xero_Import_Chart_Of_Accounts', XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer', XERO_TAXES: 'Policy_Accounting_Xero_Taxes', + XERO_CARD_RECONCILIATION: 'Policy_Accounting_Xero_Card_Reconciliation', XERO_TRACKING_CATEGORIES: 'Policy_Accounting_Xero_Tracking_Categories', XERO_MAP_TRACKING_CATEGORY: 'Policy_Accounting_Xero_Map_Tracking_Category', XERO_EXPORT: 'Policy_Accounting_Xero_Export', @@ -286,6 +288,7 @@ const SCREENS = { NETSUITE_SUBSIDIARY_SELECTOR: 'Policy_Accounting_NetSuite_Subsidiary_Selector', NETSUITE_IMPORT: 'Policy_Accounting_NetSuite_Import', NETSUITE_EXPORT: 'Policy_Accounting_NetSuite_Export', + NETSUITE_CARD_RECONCILIATION: 'Policy_Accounting_NetSuite_Card_Reconciliation', NETSUITE_PREFERRED_EXPORTER_SELECT: 'Policy_Accounting_NetSuite_Preferred_Exporter_Select', NETSUITE_DATE_SELECT: 'Policy_Accounting_NetSuite_Date_Select', NETSUITE_EXPORT_EXPENSES: 'Policy_Accounting_NetSuite_Export_Expenses', @@ -302,6 +305,7 @@ const SCREENS = { SAGE_INTACCT_PREREQUISITES: 'Policy_Accounting_Sage_Intacct_Prerequisites', ENTER_SAGE_INTACCT_CREDENTIALS: 'Policy_Enter_Sage_Intacct_Credentials', EXISTING_SAGE_INTACCT_CONNECTIONS: 'Policy_Existing_Sage_Intacct_Connections', + SAGE_INTACCT_CARD_RECONCILIATION: 'Policy_Sage_Intacct_Card_Reconciliation', }, INITIAL: 'Workspace_Initial', PROFILE: 'Workspace_Profile', diff --git a/src/languages/en.ts b/src/languages/en.ts index a72e07701c8a..5eb1fe6f1d6e 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2942,6 +2942,7 @@ export default { defaultVendor: 'Default vendor', autoSync: 'Auto-sync', reimbursedReports: 'Sync reimbursed reports', + cardReconciliation: 'Card reconciliation', }, bills: { manageYourBills: 'Manage your bills', diff --git a/src/languages/es.ts b/src/languages/es.ts index c88b273ae05d..a740ec1cfa05 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2923,6 +2923,7 @@ export default { defaultVendor: 'Proveedor predeterminado', autoSync: 'Autosincronización', reimbursedReports: 'Sincronizar informes reembolsados', + cardReconciliation: 'Conciliación de tarjetas', }, card: { header: 'Desbloquea Tarjetas Expensify gratis', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 0b001d747e5f..2794e21c2e44 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -293,6 +293,8 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/qbo/import/QuickbooksLocationsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CLASSES]: () => require('../../../../pages/workspace/accounting/qbo/import/QuickbooksClassesPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ADVANCED]: () => require('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CARD_RECONCILIATION]: () => + require('../../../../pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR]: () => require('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR]: () => @@ -303,6 +305,8 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/xero/import/XeroChartOfAccountsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: () => require('../../../../pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage').default, [SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: () => require('../../../../pages/workspace/accounting/xero/XeroTaxesConfigurationPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.XERO_CARD_RECONCILIATION]: () => + require('../../../../pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES]: () => require('../../../../pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage').default, [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY]: () => require('../../../../pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage').default, @@ -325,6 +329,8 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/netsuite/NetSuiteTokenInput/NetSuiteTokenInputPage').default, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT]: () => require('../../../../pages/workspace/accounting/netsuite/import/NetSuiteImportPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_CARD_RECONCILIATION]: () => + require('../../../../pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_MAPPING]: () => require('../../../../pages/workspace/accounting/netsuite/import/NetSuiteImportMappingPage').default, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS]: () => require('../../../../pages/workspace/accounting/netsuite/import/NetSuiteImportCustomersOrProjectsPage').default, @@ -356,6 +362,8 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/accounting/netsuite/advanced/NetSuiteAdvancedPage').default, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_PREREQUISITES]: () => require('../../../../pages/workspace/accounting/intacct/IntacctPrerequisitesPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_CARD_RECONCILIATION]: () => + require('../../../../pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.ENTER_SAGE_INTACCT_CREDENTIALS]: () => require('../../../../pages/workspace/accounting/intacct/EnterSageIntacctCredentialsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.EXISTING_SAGE_INTACCT_CONNECTIONS]: () => require('../../../../pages/workspace/accounting/intacct/ExistingConnectionsPage').default, diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index 920e25e7b0be..befc15b65743 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -45,6 +45,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_OUT_OF_POCKET_EXPENSES_SELECT, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ADVANCED, + SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CARD_RECONCILIATION, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR, SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT, @@ -52,6 +53,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION, SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER, SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES, + SCREENS.WORKSPACE.ACCOUNTING.XERO_CARD_RECONCILIATION, SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES, SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY, SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT, @@ -65,6 +67,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_SUBSIDIARY_SELECTOR, SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_TOKEN_INPUT, SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT, + SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_CARD_RECONCILIATION, SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_MAPPING, SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS, SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS_SELECT, @@ -85,6 +88,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_PREREQUISITES, SCREENS.WORKSPACE.ACCOUNTING.ENTER_SAGE_INTACCT_CREDENTIALS, SCREENS.WORKSPACE.ACCOUNTING.EXISTING_SAGE_INTACCT_CONNECTIONS, + SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_CARD_RECONCILIATION, ], [SCREENS.WORKSPACE.TAXES]: [ SCREENS.WORKSPACE.TAXES_SETTINGS, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 6f24aaf82048..ec61b6d37a44 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -305,6 +305,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_TAXES]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_TAXES.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT.route}, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CARD_RECONCILIATION]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CARD_RECONCILIATION.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_DATE_SELECT]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT_DATE_SELECT.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_INVOICE_ACCOUNT_SELECT]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECT.route}, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_OUT_OF_POCKET_EXPENSES_ACCOUNT_SELECT]: { @@ -345,6 +346,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.XERO_MAP_TRACKING_CATEGORY]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TAXES.route}, + [SCREENS.WORKSPACE.ACCOUNTING.XERO_CARD_RECONCILIATION]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CARD_RECONCILIATION.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_EXPORT.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_PURCHASE_BILL_DATE_SELECT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_EXPORT_PURCHASE_BILL_DATE_SELECT.route}, [SCREENS.WORKSPACE.ACCOUNTING.XERO_EXPORT_BANK_ACCOUNT_SELECT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_EXPORT_BANK_ACCOUNT_SELECT.route}, @@ -356,6 +358,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_SUBSIDIARY_SELECTOR]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_SUBSIDIARY_SELECTOR.route}, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_TOKEN_INPUT]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_TOKEN_INPUT.route}, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT.route}, + [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_CARD_RECONCILIATION]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_CARD_RECONCILIATION.route}, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_MAPPING]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT_MAPPING.route}, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS.route}, [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS_SELECT]: {path: ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS_SELECT.route}, @@ -404,6 +407,7 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_PREREQUISITES]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_PREREQUISITES.route}, [SCREENS.WORKSPACE.ACCOUNTING.ENTER_SAGE_INTACCT_CREDENTIALS]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ENTER_CREDENTIALS.route}, [SCREENS.WORKSPACE.ACCOUNTING.EXISTING_SAGE_INTACCT_CONNECTIONS]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXISTING_CONNECTIONS.route}, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_CARD_RECONCILIATION]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_CARD_RECONCILIATION.route}, [SCREENS.WORKSPACE.DESCRIPTION]: { path: ROUTES.WORKSPACE_PROFILE_DESCRIPTION.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index feb822e1e97c..1123b10fb79b 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -338,6 +338,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CARD_RECONCILIATION]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_DATE_SELECT]: { policyID: string; }; @@ -384,6 +387,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.XERO_CARD_RECONCILIATION]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.XERO_TRACKING_CATEGORIES]: { policyID: string; }; @@ -419,6 +425,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.ENTER_SAGE_INTACCT_CREDENTIALS]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_CARD_RECONCILIATION]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.EXISTING_SAGE_INTACCT_CONNECTIONS]: { policyID: string; }; @@ -431,6 +440,9 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_CARD_RECONCILIATION]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS]: { policyID: string; }; diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index ca4c990aea2a..f849d25df9a9 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -63,6 +63,7 @@ type AccountingIntegration = { onImportPagePress: () => void; onExportPagePress: () => void; onAdvancedPagePress: () => void; + onCardReconciliationPagePress: () => void; }; function accountingIntegrationData( connectionName: PolicyConnectionName, @@ -85,6 +86,7 @@ function accountingIntegrationData( ), onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT.getRoute(policyID)), onExportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT.getRoute(policyID)), + onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CARD_RECONCILIATION.getRoute(policyID)), onAdvancedPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID)), }; case CONST.POLICY.CONNECTIONS.NAME.XERO: @@ -100,6 +102,7 @@ function accountingIntegrationData( ), onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_IMPORT.getRoute(policyID)), onExportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_EXPORT.getRoute(policyID)), + onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_CARD_RECONCILIATION.getRoute(policyID)), onAdvancedPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID)), }; case CONST.POLICY.CONNECTIONS.NAME.NETSUITE: @@ -115,6 +118,7 @@ function accountingIntegrationData( ), onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT.getRoute(policyID)), onExportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_EXPORT.getRoute(policyID)), + onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_CARD_RECONCILIATION.getRoute(policyID)), onAdvancedPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_ADVANCED.getRoute(policyID)), }; case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: @@ -130,6 +134,7 @@ function accountingIntegrationData( ), onImportPagePress: () => {}, onExportPagePress: () => {}, + onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_CARD_RECONCILIATION.getRoute(policyID)), onAdvancedPagePress: () => {}, }; default: @@ -201,7 +206,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting }, [getDatetimeToRelative, successfulDate]); const connectionsMenuItems: MenuItemData[] = useMemo(() => { - if (isEmptyObject(policy?.connections) && !isSyncInProgress) { + if (!isEmptyObject(policy?.connections) && !isSyncInProgress) { return accountingIntegrations.map((integration) => { const integrationData = accountingIntegrationData(integration, policyID, translate); const iconProps = integrationData?.icon ? {icon: integrationData.icon, iconType: CONST.ICON_TYPE_AVATAR} : {}; @@ -216,7 +221,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting }); } - if (!connectedIntegration) { + if (connectedIntegration) { return []; } const shouldShowSynchronizationError = hasSynchronizationError(policy, connectedIntegration, isSyncInProgress); @@ -300,7 +305,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting }, ] : []), - ...(isEmptyObject(policy?.connections) || shouldShowSynchronizationError + ...(!isEmptyObject(policy?.connections) || shouldShowSynchronizationError ? [] : [ { @@ -319,6 +324,15 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting wrapperStyle: [styles.sectionMenuItemTopDescription], onPress: integrationData?.onExportPagePress, }, + { + icon: Expensicons.ExpensifyCard, + iconRight: Expensicons.ArrowRight, + shouldShowRightIcon: true, + title: translate('workspace.accounting.cardReconciliation'), + wrapperStyle: [styles.sectionMenuItemTopDescription], + onPress: integrationData?.onCardReconciliationPagePress, + }, + { icon: Expensicons.Gear, iconRight: Expensicons.ArrowRight, diff --git a/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx b/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx new file mode 100644 index 000000000000..bd254ca31e4e --- /dev/null +++ b/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import ScrollView from '@components/ScrollView'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import CONST from '@src/CONST'; + +function ReconciliationAccountSettingsPage({policy}: WithPolicyConnectionsProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const policyID = policy?.id ?? '-1'; + return ( + + + + + + + ); +} + +ReconciliationAccountSettingsPage.displayName = 'ReconciliationAccountSettingsPage'; + +export default withPolicyConnections(ReconciliationAccountSettingsPage); From 328f974d387982f1ce1a91a162c367207e455e36 Mon Sep 17 00:00:00 2001 From: Nicolay Arefyeu Date: Mon, 8 Jul 2024 17:16:04 +0300 Subject: [PATCH 060/137] clean up --- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index f849d25df9a9..cca531e0a166 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -206,7 +206,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting }, [getDatetimeToRelative, successfulDate]); const connectionsMenuItems: MenuItemData[] = useMemo(() => { - if (!isEmptyObject(policy?.connections) && !isSyncInProgress) { + if (isEmptyObject(policy?.connections) && !isSyncInProgress) { return accountingIntegrations.map((integration) => { const integrationData = accountingIntegrationData(integration, policyID, translate); const iconProps = integrationData?.icon ? {icon: integrationData.icon, iconType: CONST.ICON_TYPE_AVATAR} : {}; @@ -221,7 +221,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting }); } - if (connectedIntegration) { + if (!connectedIntegration) { return []; } const shouldShowSynchronizationError = hasSynchronizationError(policy, connectedIntegration, isSyncInProgress); From 3cf84832248318419e23116a19157661bbbd0c7e Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 8 Jul 2024 21:30:03 +0700 Subject: [PATCH 061/137] fix lint --- src/libs/ReportUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index d520982385dc..8e30349da8ef 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1673,8 +1673,9 @@ function getWelcomeMessage(report: OnyxEntry): WelcomeMessage { if (!(isChatRoom(report) || isPolicyExpenseChat(report) || isSelfDM(report) || isInvoiceRoom(report) || isSystemChat(report))) { welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); + return welcomeMessage; } - + return welcomeMessage; } From 15ad9f44ce0497776a84fb659710563b2b278c6e Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 8 Jul 2024 23:26:36 +0700 Subject: [PATCH 062/137] fix: remove useless function --- src/components/ReportWelcomeText.tsx | 3 +- src/libs/ReportUtils.ts | 67 +------------- src/libs/SidebarUtils.ts | 125 +++++++++++++++------------ 3 files changed, 73 insertions(+), 122 deletions(-) diff --git a/src/components/ReportWelcomeText.tsx b/src/components/ReportWelcomeText.tsx index 9368d0c3e7ca..e73f00e81393 100644 --- a/src/components/ReportWelcomeText.tsx +++ b/src/components/ReportWelcomeText.tsx @@ -7,6 +7,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import SidebarUtils from '@libs/SidebarUtils'; import CONST from '@src/CONST'; import type {IOUType} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -42,7 +43,7 @@ function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextP const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); const isMultipleParticipant = participantAccountIDs.length > 1; const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails), isMultipleParticipant); - const welcomeMessage = ReportUtils.getWelcomeMessage(report); + const welcomeMessage = SidebarUtils.getWelcomeMessage(report); const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, policy, participantAccountIDs); const additionalText = moneyRequestOptions .filter((item): item is Exclude => item !== CONST.IOU.TYPE.INVOICE) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 8e30349da8ef..611ab0e117a4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -79,8 +79,6 @@ import * as UserUtils from './UserUtils'; type AvatarRange = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18; -type WelcomeMessage = {showReportName: boolean; phrase1?: string; phrase2?: string; phrase3?: string}; - type SpendBreakdown = { nonReimbursableSpend: number; reimbursableSpend: number; @@ -1617,68 +1615,6 @@ function canDeleteReportAction(reportAction: OnyxInputOrEntry, rep return isActionOwner || isAdmin; } -/** - * Get welcome message based on room type - */ -function getRoomWelcomeMessage(report: OnyxEntry): WelcomeMessage { - const welcomeMessage: WelcomeMessage = {showReportName: true}; - const workspaceName = getPolicyName(report); - - if (isArchivedRoom(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfArchivedRoomPartOne'); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfArchivedRoomPartTwo'); - } else if (isDomainRoom(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryDomainRoomPartOne', {domainRoom: report?.reportName ?? ''}); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryDomainRoomPartTwo'); - } else if (isAdminRoom(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartOne', {workspaceName}); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartTwo'); - } else if (isAnnounceRoom(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartOne', {workspaceName}); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartTwo', {workspaceName}); - } else if (isInvoiceRoom(report)) { - welcomeMessage.showReportName = false; - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryInvoiceRoom'); - } else { - // Message for user created rooms or other room types. - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryUserRoomPartOne'); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryUserRoomPartTwo'); - } - - return welcomeMessage; -} - -function getWelcomeMessage(report: OnyxEntry): WelcomeMessage { - const welcomeMessage: WelcomeMessage = {showReportName: true}; - if (isChatRoom(report)) { - return getRoomWelcomeMessage(report); - } - - if (isPolicyExpenseChat(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne'); - welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo'); - welcomeMessage.phrase3 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree'); - return welcomeMessage; - } - - if (isSelfDM(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistorySelfDM'); - return welcomeMessage; - } - - if (isSystemChat(report)) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistorySystemDM'); - return welcomeMessage; - } - - if (!(isChatRoom(report) || isPolicyExpenseChat(report) || isSelfDM(report) || isInvoiceRoom(report) || isSystemChat(report))) { - welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); - return welcomeMessage; - } - - return welcomeMessage; -} - /** * Returns true if Concierge is one of the chat participants (1:1 as well as group chats) */ @@ -7177,7 +7113,6 @@ export { getPolicyExpenseChat, getPolicyName, getPolicyType, - getWelcomeMessage, getReimbursementDeQueuedActionMessage, getReimbursementQueuedActionMessage, getReportActionActorAccountID, @@ -7191,7 +7126,6 @@ export { getReportPreviewMessage, getReportRecipientAccountIDs, getRoom, - getRoomWelcomeMessage, getRootParentReport, getRouteFromLink, getSystemChat, @@ -7264,6 +7198,7 @@ export { isIOUReport, isIOUReportUsingReport, isJoinRequestInAdminRoom, + isDomainRoom, isMoneyRequest, isMoneyRequestReport, isMoneyRequestReportPendingDeletion, diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 817393bf08f4..57e6d1a8ffb2 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -23,6 +23,8 @@ import * as ReportActionsUtils from './ReportActionsUtils'; import * as ReportUtils from './ReportUtils'; import * as TaskUtils from './TaskUtils'; +type WelcomeMessage = {showReportName: boolean; phrase1?: string; phrase2?: string; phrase3?: string; concatMessage?: string}; + const visibleReportActionItems: ReportActions = {}; let allPersonalDetails: OnyxEntry; Onyx.connect({ @@ -394,38 +396,13 @@ function getOptionData({ result.alternateText = lastMessageTextFromReport.length > 0 ? lastMessageText : ReportActionsUtils.getLastVisibleMessage(report.reportID, {}, lastAction)?.lastMessageText; if (!result.alternateText) { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - result.alternateText = ReportUtils.formatReportLastMessageText(getReportBeginningOfChatHistoryMessage(report) || Localize.translateLocal('report.noActivityYet')); + result.alternateText = ReportUtils.formatReportLastMessageText(getWelcomeMessage(report).concatMessage || Localize.translateLocal('report.noActivityYet')); } } } else { if (!lastMessageText) { - if (ReportUtils.isSystemChat(report)) { - lastMessageText = Localize.translate(preferredLocale, 'reportActionsView.beginningOfChatHistorySystemDM'); - } else if (ReportUtils.isSelfDM(report)) { - lastMessageText = Localize.translate(preferredLocale, 'reportActionsView.beginningOfChatHistorySelfDM'); - } else { - // Here we get the beginning of chat history message and append the display name for each user, adding pronouns if there are any. - // We also add a fullstop after the final name, the word "and" before the final name and commas between all previous names. - lastMessageText = - Localize.translate(preferredLocale, 'reportActionsView.beginningOfChatHistory') + - displayNamesWithTooltips - .map(({displayName, pronouns}, index) => { - const formattedText = !pronouns ? displayName : `${displayName} (${pronouns})`; - - if (index === displayNamesWithTooltips.length - 1) { - return `${formattedText}.`; - } - if (index === displayNamesWithTooltips.length - 2) { - return `${formattedText} ${Localize.translate(preferredLocale, 'common.and')}`; - } - if (index < displayNamesWithTooltips.length - 2) { - return `${formattedText},`; - } - - return ''; - }) - .join(' '); - } + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + result.alternateText = ReportUtils.formatReportLastMessageText(getWelcomeMessage(report).concatMessage || Localize.translateLocal('report.noActivityYet')); } result.alternateText = @@ -465,40 +442,42 @@ function getOptionData({ return result; } -function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): string | undefined { - const welcomeMessage = ReportUtils.getWelcomeMessage(report); - const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report); - const isChatRoom = ReportUtils.isChatRoom(report); - const isSelfDM = ReportUtils.isSelfDM(report); - const isInvoiceRoom = ReportUtils.isInvoiceRoom(report); - const isSystemChat = ReportUtils.isSystemChat(report); - const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat); - - if (ReportUtils.isChatThread(report)) { - return ''; + +function getWelcomeMessage(report: OnyxEntry): WelcomeMessage { + const welcomeMessage: WelcomeMessage = {showReportName: true}; + if (ReportUtils.isChatRoom(report)) { + return getRoomWelcomeMessage(report); } - if (isPolicyExpenseChat) { + if (ReportUtils.isPolicyExpenseChat(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne'); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo'); + welcomeMessage.phrase3 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree'); if (report?.description) { - return parseHtmlToText(report.description); + welcomeMessage.concatMessage = parseHtmlToText(report.description); } - return `${welcomeMessage.phrase1} ${ReportUtils.getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${ReportUtils.getPolicyName(report)} ${ - welcomeMessage.phrase3 - }`; + welcomeMessage.concatMessage = `${welcomeMessage.phrase1} ${ReportUtils.getDisplayNameForParticipant(report?.ownerAccountID)} ${welcomeMessage.phrase2} ${ReportUtils.getPolicyName( + report, + )} ${welcomeMessage.phrase3}`; + return welcomeMessage; } - if (isChatRoom) { - if (report?.description) { - return parseHtmlToText(report.description); - } - return `${welcomeMessage.phrase1} ${welcomeMessage.showReportName ? ReportUtils.getReportName(report) : ''} ${welcomeMessage.phrase2 ?? ''}`; + if (ReportUtils.isSelfDM(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistorySelfDM'); + welcomeMessage.concatMessage = welcomeMessage.phrase1; + return welcomeMessage; } - if (isSelfDM || isSystemChat) { - return `${welcomeMessage.phrase1}`; + if (ReportUtils.isSystemChat(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistorySystemDM'); + welcomeMessage.concatMessage = welcomeMessage.phrase1; + return welcomeMessage; } - if (isDefault) { + if ( + !(ReportUtils.isChatRoom(report) || ReportUtils.isPolicyExpenseChat(report) || ReportUtils.isSelfDM(report) || ReportUtils.isInvoiceRoom(report) || ReportUtils.isSystemChat(report)) + ) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistory'); const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report); const isMultipleParticipant = participantAccountIDs.length > 1; const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips( @@ -522,14 +501,50 @@ function getReportBeginningOfChatHistoryMessage(report: OnyxEntry): stri return ''; }) .join(' '); - return `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; + welcomeMessage.concatMessage = `${welcomeMessage.phrase1} ${displayNamesWithTooltipsText}`; + return welcomeMessage; + } + + return welcomeMessage; +} + +/** + * Get welcome message based on room type + */ +function getRoomWelcomeMessage(report: OnyxEntry): WelcomeMessage { + const welcomeMessage: WelcomeMessage = {showReportName: true}; + const workspaceName = ReportUtils.getPolicyName(report); + + if (ReportUtils.isArchivedRoom(report)) { + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfArchivedRoomPartTwo'); + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfArchivedRoomPartOne'); + } else if (ReportUtils.isDomainRoom(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryDomainRoomPartOne', {domainRoom: report?.reportName ?? ''}); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryDomainRoomPartTwo'); + } else if (ReportUtils.isAdminRoom(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartOne', {workspaceName}); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAdminRoomPartTwo'); + } else if (ReportUtils.isAnnounceRoom(report)) { + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartOne', {workspaceName}); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryAnnounceRoomPartTwo', {workspaceName}); + } else if (ReportUtils.isInvoiceRoom(report)) { + welcomeMessage.showReportName = false; + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryInvoiceRoom'); + } else { + // Message for user created rooms or other room types. + welcomeMessage.phrase1 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryUserRoomPartOne'); + welcomeMessage.phrase2 = Localize.translateLocal('reportActionsView.beginningOfChatHistoryUserRoomPartTwo'); + } + if (report?.description) { + welcomeMessage.concatMessage = parseHtmlToText(report.description); } + welcomeMessage.concatMessage = `${welcomeMessage.phrase1} ${welcomeMessage.showReportName ? ReportUtils.getReportName(report) : ''} ${welcomeMessage.phrase2 ?? ''}`; - return ''; + return welcomeMessage; } export default { getOptionData, getOrderedReportIDs, - getReportBeginningOfChatHistoryMessage, + getWelcomeMessage, }; From 8270b2369377d74d9f2ae8e6272100b05de62472 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 8 Jul 2024 23:36:14 +0700 Subject: [PATCH 063/137] fix lint --- src/libs/SidebarUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 57e6d1a8ffb2..292a1ae519d0 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -347,7 +347,7 @@ function getOptionData({ const lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(report, lastActorDetails, policy); // We need to remove sms domain in case the last message text has a phone number mention with sms domain. - let lastMessageText = Str.removeSMSDomain(lastMessageTextFromReport); + const lastMessageText = Str.removeSMSDomain(lastMessageTextFromReport); const lastAction = visibleReportActionItems[report.reportID]; From 528646bc599caced4deb28efdf90f2f2a992a59a Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 8 Jul 2024 17:17:44 +0200 Subject: [PATCH 064/137] feat: setup route for choosing bank account --- src/ROUTES.ts | 4 +++ src/SCREENS.ts | 1 + .../ModalStackNavigators/index.tsx | 1 + .../FULL_SCREEN_TO_RHP_MAPPING.ts | 2 +- src/libs/Navigation/linkingConfig/config.ts | 3 +++ src/libs/Navigation/types.ts | 4 ++- .../WorkspaceExpensifyCardBankAccounts.tsx | 10 +++++++ .../WorkspaceExpensifyCardPageEmptyState.tsx | 26 ++++++++++++++++--- 8 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index d548297cb854..a420c000c858 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -822,6 +822,10 @@ const ROUTES = { // }, // TODO: remove after development is done - this one is for testing purposes WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW: 'settings/workspaces/expensify-card/issue-new', + WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT: { + route: 'settings/workspaces/:policyID/expensify-card/choose-bank-account', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/expensify-card/choose-bank-account` as const, + }, WORKSPACE_DISTANCE_RATES: { route: 'settings/workspaces/:policyID/distance-rates', getRoute: (policyID: string) => `settings/workspaces/${policyID}/distance-rates` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index e2e3f7acc5b0..105e3d5e959d 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -319,6 +319,7 @@ const SCREENS = { RATE_AND_UNIT_UNIT: 'Workspace_RateAndUnit_Unit', EXPENSIFY_CARD: 'Workspace_ExpensifyCard', EXPENSIFY_CARD_ISSUE_NEW: 'Workspace_ExpensifyCard_New', + EXPENSIFY_CARD_BANK_ACCOUNT: 'Workspace_ExpensifyCard_BankAccount', BILLS: 'Workspace_Bills', INVOICES: 'Workspace_Invoices', TRAVEL: 'Workspace_Travel', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 856e2e090ebb..a920caac8890 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -379,6 +379,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/taxes/ValuePage').default, [SCREENS.WORKSPACE.TAX_CREATE]: () => require('../../../../pages/workspace/taxes/WorkspaceCreateTaxPage').default, [SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: () => require('../../../../pages/workspace/card/issueNew/IssueNewCardPage').default, + [SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: () => require('../../../../pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts').default, [SCREENS.SETTINGS.SAVE_THE_WORLD]: () => require('../../../../pages/TeachersUnite/SaveTheWorldPage').default, [SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_PAYMENT_CURRENCY]: () => require('../../../../pages/settings/PaymentCard/ChangeCurrency').default, [SCREENS.SETTINGS.SUBSCRIPTION.CHANGE_BILLING_CURRENCY]: () => require('../../../../pages/settings/Subscription/PaymentCard/ChangeBillingCurrency').default, diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index 75b096fa4bbe..ffa09ba734f5 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -129,7 +129,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.REPORT_FIELDS_VALUE_SETTINGS, SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_VALUE, ], - [SCREENS.WORKSPACE.EXPENSIFY_CARD]: [], + [SCREENS.WORKSPACE.EXPENSIFY_CARD]: [SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT], }; export default FULL_SCREEN_TO_RHP_MAPPING; diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 699cb9b704e1..5370eab6216c 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -440,6 +440,9 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.EXPENSIFY_CARD_ISSUE_NEW]: { path: ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW, }, + [SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: { + path: ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.route, + }, [SCREENS.WORKSPACE.RATE_AND_UNIT]: { path: ROUTES.WORKSPACE_RATE_AND_UNIT.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index a60316fb7768..ffd347e176b7 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -993,7 +993,9 @@ type FullScreenNavigatorParamList = { [SCREENS.WORKSPACE.DISTANCE_RATES]: { policyID: string; }; - + [SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.ROOT]: { policyID: string; }; diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx new file mode 100644 index 000000000000..83cdc9d02b83 --- /dev/null +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import {View} from 'react-native'; + +function WorkspaceExpensifyCardBankAccounts() { + return ; +} + +WorkspaceExpensifyCardBankAccounts.displayName = 'WorkspaceExpensifyCardBankAccounts'; + +export default WorkspaceExpensifyCardBankAccounts; diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx index 6e04ae6f5d0e..05e5857963ea 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx @@ -1,6 +1,7 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; import FeatureList from '@components/FeatureList'; import type {FeatureListItem} from '@components/FeatureList'; import * as Illustrations from '@components/Icon/Illustrations'; @@ -9,9 +10,15 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import type {FullScreenNavigatorParamList} from '@libs/Navigation/types'; +import Navigation from '@navigation/Navigation'; +import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; +import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; const expensifyCardFeatures: FeatureListItem[] = [ { @@ -27,13 +34,24 @@ const expensifyCardFeatures: FeatureListItem[] = [ translationKey: 'workspace.moreFeatures.expensifyCard.feed.features.spend', }, ]; -type WorkspaceExpensifyCardPageEmptyStateProps = {route: StackScreenProps['route']}; +type WorkspaceExpensifyCardPageEmptyStateProps = { + route: StackScreenProps['route']; +} & WithPolicyAndFullscreenLoadingProps; -function WorkspaceExpensifyCardPageEmptyState({route}: WorkspaceExpensifyCardPageEmptyStateProps) { +function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensifyCardPageEmptyStateProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); const {shouldUseNarrowLayout} = useResponsiveLayout(); + const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); + + const startFlow = () => { + if (isEmptyObject(bankAccountList)) { + Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('new', policy?.id, ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policy?.id ?? '-1'))); + } else { + Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.getRoute(policy?.id ?? '-1')); + } + }; return ( {}} + onCtaPress={startFlow} illustrationBackgroundColor={theme.fallbackIconColor} illustration={Illustrations.ExpensifyCardIllustration} illustrationStyle={styles.expensifyCardIllustrationContainer} @@ -65,4 +83,4 @@ function WorkspaceExpensifyCardPageEmptyState({route}: WorkspaceExpensifyCardPag WorkspaceExpensifyCardPageEmptyState.displayName = 'WorkspaceExpensifyCardPageEmptyState'; -export default WorkspaceExpensifyCardPageEmptyState; +export default withPolicyAndFullscreenLoading(WorkspaceExpensifyCardPageEmptyState); From 1d212170316ee8dd47db6ff1c092b2b25e44dc8f Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 9 Jul 2024 08:02:15 +0200 Subject: [PATCH 065/137] feat: create page content --- src/languages/en.ts | 4 ++ src/languages/es.ts | 4 ++ .../WorkspaceExpensifyCardBankAccounts.tsx | 45 ++++++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 543dfbf5e541..38d664abec7b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1214,6 +1214,10 @@ export default { updateAddress: 'Update address', }, cardDetailsLoadingFailure: 'An error occurred while loading the card details. Please check your internet connection and try again.', + chooseBankAccount: 'Choose bank account', + chooseExistingBank: 'Choose an existing business bank account to pay your Expensify Card balance, or add a new bank account', + accountEndingIn: 'Account ending in', + addNewBankAccount: 'Add a new bank account', }, workflowsPage: { workflowTitle: 'Spend', diff --git a/src/languages/es.ts b/src/languages/es.ts index e7f4faab2725..fb0d9c082807 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1219,6 +1219,10 @@ export default { updateAddress: 'Actualizar dirección', }, cardDetailsLoadingFailure: 'Se ha producido un error al cargar los datos de la tarjeta. Comprueba tu conexión a Internet e inténtalo de nuevo.', + chooseBankAccount: 'Elegir cuenta bancaria', + chooseExistingBank: 'Elige una cuenta bancaria comercial existente para pagar el saldo de su Tarjeta Expensify o añade una nueva cuenta bancaria.', + accountEndingIn: 'Cuenta terminada en', + addNewBankAccount: 'Añadir nueva cuenta bancaria', }, workflowsPage: { workflowTitle: 'Gasto', diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx index 83cdc9d02b83..38a42bce2bc8 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx @@ -1,8 +1,49 @@ import React from 'react'; -import {View} from 'react-native'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import * as Expensicons from '@components/Icon/Expensicons'; +import MenuItem from '@components/MenuItem'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import ScreenWrapper from '@components/ScreenWrapper'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@navigation/Navigation'; function WorkspaceExpensifyCardBankAccounts() { - return ; + const {translate} = useLocalize(); + const styles = useThemeStyles(); + + return ( + + Navigation.goBack()} + title={translate('cardPage.chooseBankAccount')} + /> + {`${translate('cardPage.chooseExistingBank')}:`} + {}} + icon={Expensicons.Bank} + /> + {}} + icon={Expensicons.Bank} + /> + {}} + /> + + ); } WorkspaceExpensifyCardBankAccounts.displayName = 'WorkspaceExpensifyCardBankAccounts'; From ca879b8b7b7388d10eab8af6f5e59aee0124c0bb Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Tue, 9 Jul 2024 17:43:34 +0800 Subject: [PATCH 066/137] update the selection only if the prop is updated --- src/components/Composer/index.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/Composer/index.tsx b/src/components/Composer/index.tsx index a41f983434d8..9e8de034186d 100755 --- a/src/components/Composer/index.tsx +++ b/src/components/Composer/index.tsx @@ -116,12 +116,10 @@ function Composer( }, [shouldClear, onClear]); useEffect(() => { - setSelection((prevSelection) => { - if (!!prevSelection && selectionProp.start === prevSelection.start && selectionProp.end === prevSelection.end) { - return; - } - return selectionProp; - }); + if (!!selection && selectionProp.start === selection.start && selectionProp.end === selection.end) { + return; + } + setSelection(selectionProp); }, [selectionProp]); /** From d75e8a819171c0d72fe2cacc7642a6cc85e51dce Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Tue, 9 Jul 2024 11:29:36 +0100 Subject: [PATCH 067/137] Update src/libs/Fullstory/index.native.ts Co-authored-by: Puneet Lath --- src/libs/Fullstory/index.native.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Fullstory/index.native.ts b/src/libs/Fullstory/index.native.ts index 52c70d1700b8..345f4139ae6c 100644 --- a/src/libs/Fullstory/index.native.ts +++ b/src/libs/Fullstory/index.native.ts @@ -16,7 +16,7 @@ const FS = { */ init: () => { Environment.getEnvironment().then((envName: string) => { - // We only want to start fullstory if the app is running in + // We only want to start fullstory if the app is running in production // production if(envName !== CONST.ENVIRONMENT.PRODUCTION) { return; From 9bf1902a5e3af6fed9b5e00196c1c298b5c6ffa2 Mon Sep 17 00:00:00 2001 From: Daniel Silva Date: Tue, 9 Jul 2024 11:29:42 +0100 Subject: [PATCH 068/137] Update src/libs/Fullstory/index.native.ts Co-authored-by: Puneet Lath --- src/libs/Fullstory/index.native.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Fullstory/index.native.ts b/src/libs/Fullstory/index.native.ts index 345f4139ae6c..032465c353aa 100644 --- a/src/libs/Fullstory/index.native.ts +++ b/src/libs/Fullstory/index.native.ts @@ -18,7 +18,7 @@ const FS = { Environment.getEnvironment().then((envName: string) => { // We only want to start fullstory if the app is running in production // production - if(envName !== CONST.ENVIRONMENT.PRODUCTION) { + if (envName !== CONST.ENVIRONMENT.PRODUCTION) { return; } FullStory.restart(); From 78490f480bffdc4e661c313c334e838a7e795e75 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 9 Jul 2024 13:41:41 +0200 Subject: [PATCH 069/137] feat: render proper bank info --- src/libs/Navigation/types.ts | 6 +- .../WorkspaceExpensifyCardBankAccounts.tsx | 68 ++++++++++++++----- .../WorkspaceExpensifyCardPage.tsx | 20 ++++-- 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index ffd347e176b7..14ef02feade8 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -542,6 +542,9 @@ type SettingsNavigatorParamList = { policyID: string; taxID: string; }; + [SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: { + policyID: string; + }; } & ReimbursementAccountNavigatorParamList; type NewChatNavigatorParamList = { @@ -993,9 +996,6 @@ type FullScreenNavigatorParamList = { [SCREENS.WORKSPACE.DISTANCE_RATES]: { policyID: string; }; - [SCREENS.WORKSPACE.EXPENSIFY_CARD_BANK_ACCOUNT]: { - policyID: string; - }; [SCREENS.WORKSPACE.ACCOUNTING.ROOT]: { policyID: string; }; diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx index 38a42bce2bc8..1d7d0e6992c6 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx @@ -1,17 +1,64 @@ +import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; +import {useOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import getBankIcon from '@components/Icon/BankIcons'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; -import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@navigation/types'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; +import type {BankName} from '@src/types/onyx/Bank'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; -function WorkspaceExpensifyCardBankAccounts() { +type WorkspaceExpensifyCardBankAccountsProps = StackScreenProps; + +function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankAccountsProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); + const [bankAccountsList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); + + const policyID = route.params.policyID ?? '-1'; + + const handleAddBankAccount = () => { + Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('new', policyID, ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID))); + }; + + const handleSelectBankAccount = () => { + Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID)); + }; + + const renderBankOptions = () => { + if (!bankAccountsList || isEmptyObject(bankAccountsList)) { + return null; + } + + // const eligibleBankAccounts = Object.values(bankAccountsList).filter((bankAccount) => bankAccount.accountData.allowDebit || bankAccount.accountData.type === 'BUSINESS'); + const eligibleBankAccounts = Object.values(bankAccountsList); + return eligibleBankAccounts.map((bankAccount) => { + const bankName = (bankAccount.accountData?.addressName ?? '') as BankName; + const {icon, iconSize, iconStyles} = getBankIcon({bankName, styles}); + + return ( + + ); + }); + }; return ( Navigation.goBack()} title={translate('cardPage.chooseBankAccount')} /> - {`${translate('cardPage.chooseExistingBank')}:`} - {}} - icon={Expensicons.Bank} - /> - {}} - icon={Expensicons.Bank} - /> + {translate('cardPage.chooseExistingBank')} + {renderBankOptions()} {}} + onPress={handleAddBankAccount} /> ); diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx index 25be3775964c..ec410bfc4288 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx @@ -19,16 +19,22 @@ function WorkspaceExpensifyCardPage({route}: WorkspaceExpensifyCardPageProps) { // const policyID = route.params.policyID ?? '-1'; // const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${policyID}_${CONST.EXPENSIFY_CARD.BANK}`); + // return ( + // + // {/* After BE will be implemented we will probably want to have ActivityIndicator during fetch for cardsList */} + // {isEmptyObject(cardsList) && } + // {!isEmptyObject(cardsList) && } + // + // ); return ( - - {/* After BE will be implemented we will probably want to have ActivityIndicator during fetch for cardsList */} + <> {isEmptyObject(cardsList) && } {!isEmptyObject(cardsList) && } - + ); } From 82fc0971a7837042d9418bb3b28c08c1c095d914 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Tue, 9 Jul 2024 17:25:44 +0530 Subject: [PATCH 070/137] minor update. Signed-off-by: krishna2323 --- src/pages/iou/request/step/IOURequestStepDistance.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index ba0abaf65e54..2a84ea5fc8c6 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -361,10 +361,12 @@ function IOURequestStepDistance({ data.forEach((waypoint, index) => { newWaypoints[`waypoint${index}`] = waypoints[waypoint] ?? {}; // Find waypoint that BECOMES empty after dragging - const {keyForList, ...newWaypointsWithoutKey} = newWaypoints[`waypoint${index}`]; - const {keyForList: waypointKey, ...waypointWithoutKey} = waypoints[`waypoint${index}`]; - if (isEmpty(newWaypointsWithoutKey) && !isEmpty(waypointWithoutKey ?? {})) { - emptyWaypointIndex = index; + if (newWaypoints[`waypoint${index}`] && waypoints[`waypoint${index}`]) { + const {keyForList, ...newWaypointsWithoutKey} = newWaypoints[`waypoint${index}`]; + const {keyForList: waypointKey, ...waypointWithoutKey} = waypoints[`waypoint${index}`]; + if (isEmpty(newWaypointsWithoutKey) && !isEmpty(waypointWithoutKey ?? {})) { + emptyWaypointIndex = index; + } } }); From 2bc06c976f637c046361a2cd258fd04a27894f3c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 9 Jul 2024 15:31:34 +0300 Subject: [PATCH 071/137] add control policy access variant --- src/CONST.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CONST.ts b/src/CONST.ts index caf0b1453fae..c5953fb74a03 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2048,6 +2048,7 @@ const CONST = { ACCESS_VARIANTS: { PAID: 'paid', ADMIN: 'admin', + CONTROL: 'control', }, DEFAULT_MAX_EXPENSE_AGE: 90, DEFAULT_MAX_EXPENSE_AMOUNT: 200000, From 89fec2f10faf9fd2be5cc5b1dcf24d8494a3d8db Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 9 Jul 2024 15:31:43 +0300 Subject: [PATCH 072/137] add control policy access variant --- src/libs/PolicyUtils.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index fc9a04e2507c..74709faedc9c 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -305,6 +305,10 @@ function isPaidGroupPolicy(policy: OnyxEntry): boolean { return policy?.type === CONST.POLICY.TYPE.TEAM || policy?.type === CONST.POLICY.TYPE.CORPORATE; } +function isControlPolicy(policy: OnyxEntry): boolean { + return policy?.type === CONST.POLICY.TYPE.CORPORATE; +} + function isTaxTrackingEnabled(isPolicyExpenseChat: boolean, policy: OnyxEntry, isDistanceRequest: boolean): boolean { const distanceUnit = getCustomUnit(policy); const customUnitID = distanceUnit?.customUnitID ?? 0; @@ -727,6 +731,7 @@ export { getIntegrationLastSuccessfulDate, getCurrentConnectionName, getCustomersOrJobsLabelNetSuite, + isControlPolicy, }; export type {MemberEmailsToAccountIDs}; From d884e041c1c797476281e83d56f2715fe3f605c2 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 9 Jul 2024 15:31:54 +0300 Subject: [PATCH 073/137] add control policy access variant --- src/pages/workspace/AccessOrNotFoundWrapper.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index c7f89559fdda..351bd36fbb34 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -23,6 +23,7 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; const ACCESS_VARIANTS = { [CONST.POLICY.ACCESS_VARIANTS.PAID]: (policy: OnyxEntry) => PolicyUtils.isPaidGroupPolicy(policy), + [CONST.POLICY.ACCESS_VARIANTS.CONTROL]: (policy: OnyxEntry) => PolicyUtils.isControlPolicy(policy), [CONST.POLICY.ACCESS_VARIANTS.ADMIN]: (policy: OnyxEntry, login: string) => PolicyUtils.isPolicyAdmin(policy, login), [CONST.IOU.ACCESS_VARIANTS.CREATE]: ( policy: OnyxEntry, From 39f60d525bb77081054c5bab2f2cc8fd932c9ff2 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 9 Jul 2024 15:32:09 +0300 Subject: [PATCH 074/137] add control policy access variant --- src/pages/workspace/categories/CategoryPayrollCodePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx index 85aa031d3fc4..8028906401fb 100644 --- a/src/pages/workspace/categories/CategoryPayrollCodePage.tsx +++ b/src/pages/workspace/categories/CategoryPayrollCodePage.tsx @@ -45,7 +45,7 @@ function CategoryPayrollCodePage({route}: EditCategoryPageProps) { return ( From e2ac2e0c1e52f5df7b16c77cf7c0f230b8c06889 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Tue, 9 Jul 2024 15:36:34 +0300 Subject: [PATCH 075/137] spanish translation --- src/languages/es.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 576837421c39..ee77c030f054 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2540,8 +2540,8 @@ export default { existingCategoryError: 'Ya existe una categoría con este nombre.', invalidCategoryName: 'Lo nombre de la categoría es invalido.', importedFromAccountingSoftware: 'Categorías importadas desde', - payrollCode: 'Payroll code', - updatePayrollCodeFailureMessage: 'An error occurred while updating the payroll code, please try again.', + payrollCode: 'Código de nómina', + updatePayrollCodeFailureMessage: 'Se produjo un error al actualizar el código de nómina, por favor intente nuevamente.', }, moreFeatures: { spendSection: { From 3e64e94ead573e0ca8374a9a24fb9b8e0eecf5db Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Tue, 9 Jul 2024 15:00:45 +0200 Subject: [PATCH 076/137] chore: cleanup --- src/CONST.ts | 2 ++ src/languages/en.ts | 10 +++++---- src/languages/es.ts | 10 +++++---- .../WorkspaceExpensifyCardBankAccounts.tsx | 17 +++++++++----- .../WorkspaceExpensifyCardPage.tsx | 20 ++++++----------- .../WorkspaceExpensifyCardPageEmptyState.tsx | 22 +++++++++++++++---- 6 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 13d44ee883be..e8519745716b 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -335,6 +335,8 @@ const CONST = { VERIFICATION_MAX_ATTEMPTS: 7, STATE: { VERIFYING: 'VERIFYING', + VALIDATING: 'VALIDATING', + SETUP: 'SETUP', PENDING: 'PENDING', OPEN: 'OPEN', }, diff --git a/src/languages/en.ts b/src/languages/en.ts index 38d664abec7b..56ec57b47715 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1214,10 +1214,6 @@ export default { updateAddress: 'Update address', }, cardDetailsLoadingFailure: 'An error occurred while loading the card details. Please check your internet connection and try again.', - chooseBankAccount: 'Choose bank account', - chooseExistingBank: 'Choose an existing business bank account to pay your Expensify Card balance, or add a new bank account', - accountEndingIn: 'Account ending in', - addNewBankAccount: 'Add a new bank account', }, workflowsPage: { workflowTitle: 'Spend', @@ -2472,6 +2468,12 @@ export default { 'We consider a number of factors when calculating your remaining limit: your tenure as a customer, the business-related information you provided during signup, and the available cash in your business bank account. Your remaining limit can fluctuate on a daily basis.', cashBack: 'Cash back', cashBackDescription: 'Cash back balance is based on settled monthly Expensify Card spend across your workspace.', + issueNewCard: 'Issue new card', + finishSetup: 'Finish setup', + chooseBankAccount: 'Choose bank account', + chooseExistingBank: 'Choose an existing business bank account to pay your Expensify Card balance, or add a new bank account', + accountEndingIn: 'Account ending in', + addNewBankAccount: 'Add a new bank account', }, categories: { deleteCategories: 'Delete categories', diff --git a/src/languages/es.ts b/src/languages/es.ts index fb0d9c082807..e13fc02ae452 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1219,10 +1219,6 @@ export default { updateAddress: 'Actualizar dirección', }, cardDetailsLoadingFailure: 'Se ha producido un error al cargar los datos de la tarjeta. Comprueba tu conexión a Internet e inténtalo de nuevo.', - chooseBankAccount: 'Elegir cuenta bancaria', - chooseExistingBank: 'Elige una cuenta bancaria comercial existente para pagar el saldo de su Tarjeta Expensify o añade una nueva cuenta bancaria.', - accountEndingIn: 'Cuenta terminada en', - addNewBankAccount: 'Añadir nueva cuenta bancaria', }, workflowsPage: { workflowTitle: 'Gasto', @@ -2516,6 +2512,12 @@ export default { 'A la hora de calcular tu límite restante, tenemos en cuenta una serie de factores: su antigüedad como cliente, la información relacionada con tu negocio que nos facilitaste al darte de alta y el efectivo disponible en tu cuenta bancaria comercial. Tu límite restante puede fluctuar a diario.', cashBack: 'Reembolso', cashBackDescription: 'El saldo de devolución se basa en el gasto mensual realizado con la tarjeta Expensify en tu espacio de trabajo.', + issueNewCard: '', + finishSetup: 'Terminar configuración', + chooseBankAccount: 'Elegir cuenta bancaria', + chooseExistingBank: 'Elige una cuenta bancaria comercial existente para pagar el saldo de su Tarjeta Expensify o añade una nueva cuenta bancaria.', + accountEndingIn: 'Cuenta terminada en', + addNewBankAccount: 'Añadir nueva cuenta bancaria', }, categories: { deleteCategories: 'Eliminar categorías', diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx index 1d7d0e6992c6..f639d8414017 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx @@ -31,7 +31,9 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA }; const handleSelectBankAccount = () => { - Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW); + // TODO: replace the previous line with this one after #44741 is merged + // Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID)); }; const renderBankOptions = () => { @@ -39,16 +41,19 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA return null; } - // const eligibleBankAccounts = Object.values(bankAccountsList).filter((bankAccount) => bankAccount.accountData.allowDebit || bankAccount.accountData.type === 'BUSINESS'); + // const eligibleBankAccounts = Object.values(bankAccountsList).filter((bankAccount) => bankAccount.accountData.allowDebit || bankAccount.accountData.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS); const eligibleBankAccounts = Object.values(bankAccountsList); + return eligibleBankAccounts.map((bankAccount) => { const bankName = (bankAccount.accountData?.addressName ?? '') as BankName; + const bankAccountNumber = bankAccount.accountData?.accountNumber ?? ''; + const {icon, iconSize, iconStyles} = getBankIcon({bankName, styles}); return ( Navigation.goBack()} - title={translate('cardPage.chooseBankAccount')} + title={translate('workspace.expensifyCard.chooseBankAccount')} /> - {translate('cardPage.chooseExistingBank')} + {translate('workspace.expensifyCard.chooseExistingBank')} {renderBankOptions()} diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx index ec410bfc4288..25be3775964c 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPage.tsx @@ -19,22 +19,16 @@ function WorkspaceExpensifyCardPage({route}: WorkspaceExpensifyCardPageProps) { // const policyID = route.params.policyID ?? '-1'; // const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${policyID}_${CONST.EXPENSIFY_CARD.BANK}`); - // return ( - // - // {/* After BE will be implemented we will probably want to have ActivityIndicator during fetch for cardsList */} - // {isEmptyObject(cardsList) && } - // {!isEmptyObject(cardsList) && } - // - // ); return ( - <> + + {/* After BE will be implemented we will probably want to have ActivityIndicator during fetch for cardsList */} {isEmptyObject(cardsList) && } {!isEmptyObject(cardsList) && } - + ); } diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx index 05e5857963ea..458b2802da5a 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx @@ -1,5 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; +import React, {useCallback} from 'react'; import {View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import FeatureList from '@components/FeatureList'; @@ -44,14 +44,28 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif const theme = useTheme(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); + const [reimbursementAccount] = useOnyx(ONYXKEYS.REIMBURSEMENT_ACCOUNT); - const startFlow = () => { + const reimbursementAccountStatus = reimbursementAccount?.achData?.state ?? ''; + + const getTranslationForCta = useCallback(() => { + switch (reimbursementAccountStatus) { + case CONST.BANK_ACCOUNT.STATE.VERIFYING: + case CONST.BANK_ACCOUNT.STATE.SETUP: + case CONST.BANK_ACCOUNT.STATE.VALIDATING: + return 'workspace.expensifyCard.finishSetup'; + default: + return 'workspace.expensifyCard.issueNewCard'; + } + }, [reimbursementAccountStatus]); + + const startFlow = useCallback(() => { if (isEmptyObject(bankAccountList)) { Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('new', policy?.id, ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policy?.id ?? '-1'))); } else { Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.getRoute(policy?.id ?? '-1')); } - }; + }, [bankAccountList]); return ( Date: Tue, 9 Jul 2024 22:11:40 +0530 Subject: [PATCH 077/137] feat: added api --- .../parameters/UpdateNetSuiteCustomersJobsParams.ts | 10 ++++++++++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 src/libs/API/parameters/UpdateNetSuiteCustomersJobsParams.ts diff --git a/src/libs/API/parameters/UpdateNetSuiteCustomersJobsParams.ts b/src/libs/API/parameters/UpdateNetSuiteCustomersJobsParams.ts new file mode 100644 index 000000000000..c29b503a9acf --- /dev/null +++ b/src/libs/API/parameters/UpdateNetSuiteCustomersJobsParams.ts @@ -0,0 +1,10 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type UpdateNetSuiteCustomersJobsParams = { + policyID: string; + customersMapping: ValueOf; + jobsMapping: ValueOf; +}; + +export default UpdateNetSuiteCustomersJobsParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index ff8465cfeec7..88dfbaf299ee 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -254,3 +254,4 @@ export type {default as RequestExpensifyCardLimitIncreaseParams} from './Request export type {default as UpdateNetSuiteGenericTypeParams} from './UpdateNetSuiteGenericTypeParams'; export type {default as UpdateNetSuiteCustomFormIDParams} from './UpdateNetSuiteCustomFormIDParams'; export type {default as UpdateSageIntacctGenericTypeParams} from './UpdateSageIntacctGenericTypeParams'; +export type {default as UpdateNetSuiteCustomersJobsParams} from './UpdateNetSuiteCustomersJobsParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index e1647faf0d56..fd4431503ebd 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -249,6 +249,7 @@ const WRITE_COMMANDS = { UPDATE_NETSUITE_LOCATIONS_MAPPING: 'UpdateNetSuiteLocationsMapping', UPDATE_NETSUITE_CUSTOMERS_MAPPING: 'UpdateNetSuiteCustomersMapping', UPDATE_NETSUITE_JOBS_MAPPING: 'UpdateNetSuiteJobsMapping', + UPDATE_NETSUITE_CUSTOMERS_JOBS_MAPPING: 'UpdateNetSuiteCustomersJobsMapping', UPDATE_NETSUITE_EXPORTER: 'UpdateNetSuiteExporter', UPDATE_NETSUITE_EXPORT_DATE: 'UpdateNetSuiteExportDate', UPDATE_NETSUITE_REIMBURSABLE_EXPENSES_EXPORT_DESTINATION: 'UpdateNetSuiteReimbursableExpensesExportDestination', @@ -557,6 +558,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_NETSUITE_LOCATIONS_MAPPING]: Parameters.UpdateNetSuiteGenericTypeParams<'mapping', ValueOf>; [WRITE_COMMANDS.UPDATE_NETSUITE_CUSTOMERS_MAPPING]: Parameters.UpdateNetSuiteGenericTypeParams<'mapping', ValueOf>; [WRITE_COMMANDS.UPDATE_NETSUITE_JOBS_MAPPING]: Parameters.UpdateNetSuiteGenericTypeParams<'mapping', ValueOf>; + [WRITE_COMMANDS.UPDATE_NETSUITE_CUSTOMERS_JOBS_MAPPING]: Parameters.UpdateNetSuiteCustomersJobsParams; [WRITE_COMMANDS.UPDATE_NETSUITE_EXPORTER]: Parameters.UpdateNetSuiteGenericTypeParams<'email', string>; [WRITE_COMMANDS.UPDATE_NETSUITE_EXPORT_DATE]: Parameters.UpdateNetSuiteGenericTypeParams<'value', ValueOf>; [WRITE_COMMANDS.UPDATE_NETSUITE_REIMBURSABLE_EXPENSES_EXPORT_DESTINATION]: Parameters.UpdateNetSuiteGenericTypeParams<'value', ValueOf>; From 62b23ab093e2605eb999568bcc9829889ea33725 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Tue, 9 Jul 2024 22:56:38 +0530 Subject: [PATCH 078/137] refactor: update api call for customers and jobs --- .../actions/connections/NetSuiteCommands.ts | 115 +++++++++++++++++- ...uiteImportCustomersOrProjectSelectPage.tsx | 23 ++-- src/types/onyx/Policy.ts | 1 + 3 files changed, 129 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/connections/NetSuiteCommands.ts b/src/libs/actions/connections/NetSuiteCommands.ts index 66bf482d6ef2..093c22d33b42 100644 --- a/src/libs/actions/connections/NetSuiteCommands.ts +++ b/src/libs/actions/connections/NetSuiteCommands.ts @@ -7,7 +7,7 @@ import {WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Connections, NetSuiteCustomFormID} from '@src/types/onyx/Policy'; +import type {Connections, NetSuiteCustomFormID, NetSuiteMappingValues} from '@src/types/onyx/Policy'; import type {OnyxData} from '@src/types/onyx/Request'; type SubsidiaryParam = { @@ -402,6 +402,118 @@ function updateNetSuiteImportMapping; + value: NetSuiteMappingValues; }; function NetSuiteImportCustomersOrProjectSelectPage({policy}: WithPolicyConnectionsProps) { @@ -39,12 +39,17 @@ function NetSuiteImportCustomersOrProjectSelectPage({policy}: WithPolicyConnecti const updateImportMapping = useCallback( ({value}: ImportListItem) => { if (value !== importedValue) { - if (importJobs !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT) { - updateNetSuiteImportMapping(policyID, CONST.NETSUITE_CONFIG.SYNC_OPTIONS.CUSTOMER_MAPPINGS.JOBS, value, importMappings?.jobs); - } - if (importCustomer !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT) { - updateNetSuiteImportMapping(policyID, CONST.NETSUITE_CONFIG.SYNC_OPTIONS.CUSTOMER_MAPPINGS.CUSTOMERS, value, importMappings?.customers); - } + updateNetSuiteCustomersJobsMapping( + policyID, + { + customersMapping: importCustomer !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT ? value : CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT, + jobsMapping: importJobs !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT ? value : CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT, + }, + { + customersMapping: importMappings?.customers, + jobsMapping: importMappings?.jobs, + }, + ); } Navigation.goBack(); }, diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 67225d299ed6..b838ff5e72a1 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1427,4 +1427,5 @@ export type { NetSuiteCustomFormIDOptions, NetSuiteCustomFormID, SageIntacctDataElementWithValue, + NetSuiteMappingValues, }; From 1b04a52ea66ac658a8b1d6c7355b4e0cff58b307 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 9 Jul 2024 12:29:06 -0600 Subject: [PATCH 079/137] fix to field on reportListItem --- src/libs/SearchUtils.ts | 17 +++++++++++------ src/types/onyx/SearchResults.ts | 5 ++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts index cb579e44b95d..089451cdc585 100644 --- a/src/libs/SearchUtils.ts +++ b/src/libs/SearchUtils.ts @@ -161,15 +161,20 @@ function getReportSections(data: OnyxTypes.SearchResults['data'], metadata: Onyx const reportIDToTransactions: Record = {}; for (const key in data) { if (key.startsWith(ONYXKEYS.COLLECTION.REPORT)) { - const value = {...data[key]}; - const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${value.reportID}`; + const reportItem = {...data[key]}; + const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${reportItem.reportID}`; const transactions = reportIDToTransactions[reportKey]?.transactions ?? []; + const isExpenseReport = reportItem.type === CONST.REPORT.TYPE.EXPENSE; + + const to = isExpenseReport + ? (data[`${ONYXKEYS.COLLECTION.POLICY}${reportItem.policyID}`] as SearchAccountDetails) + : (data.personalDetailsList?.[reportItem.managerID] as SearchAccountDetails); reportIDToTransactions[reportKey] = { - ...value, - keyForList: value.reportID, - from: data.personalDetailsList?.[value.accountID], - to: data.personalDetailsList?.[value.managerID], + ...reportItem, + keyForList: reportItem.reportID, + from: data.personalDetailsList?.[reportItem.accountID], + to, transactions, }; } else if (key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION)) { diff --git a/src/types/onyx/SearchResults.ts b/src/types/onyx/SearchResults.ts index 89d1b6c72566..3b7bc594aaad 100644 --- a/src/types/onyx/SearchResults.ts +++ b/src/types/onyx/SearchResults.ts @@ -108,7 +108,7 @@ type SearchReport = { currency?: string; /** The report type */ - type?: string; + type?: ValueOf(); /** The accountID of the report manager */ managerID?: number; @@ -116,6 +116,9 @@ type SearchReport = { /** The accountID of the user who created the report */ accountID?: number; + /** The policyID of the report */ + policyID?: ValueOf; + /** The date the report was created */ created?: string; From c70c70285284602e7ee4b153d3690018b0c7caf0 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 9 Jul 2024 15:23:26 -0600 Subject: [PATCH 080/137] fix types --- .../SelectionList/Search/TransactionListItemRow.tsx | 2 +- src/libs/SearchUtils.ts | 2 +- src/types/onyx/SearchResults.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/SelectionList/Search/TransactionListItemRow.tsx b/src/components/SelectionList/Search/TransactionListItemRow.tsx index 23f9234819c3..ec112e43fb3c 100644 --- a/src/components/SelectionList/Search/TransactionListItemRow.tsx +++ b/src/components/SelectionList/Search/TransactionListItemRow.tsx @@ -155,7 +155,7 @@ function TotalCell({showTooltip, isLargeScreenWidth, transactionItem}: TotalCell function TypeCell({transactionItem, isLargeScreenWidth}: TransactionCellProps) { const theme = useTheme(); - const typeIcon = getTypeIcon(transactionItem.type); + const typeIcon = getTypeIcon(transactionItem.transactionType); return ( ; /** The accountID of the report manager */ managerID?: number; @@ -117,7 +117,7 @@ type SearchReport = { accountID?: number; /** The policyID of the report */ - policyID?: ValueOf; + policyID?: string; /** The date the report was created */ created?: string; @@ -180,7 +180,7 @@ type SearchTransaction = { category: string; /** The type of request */ - type: ValueOf; + transactionType: ValueOf; /** The type of report the transaction is associated with */ reportType: string; From b9119364c79e070701919f999f734908fb908119 Mon Sep 17 00:00:00 2001 From: dominictb Date: Wed, 10 Jul 2024 04:25:28 +0700 Subject: [PATCH 081/137] feat use StyleUtils.getColorStyle to get linkHover --- src/components/Button/index.tsx | 2 +- src/styles/index.ts | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index 0a3f1ee6eeda..f8acec2b07dd 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -235,7 +235,7 @@ function Button( !!icon && styles.textAlignLeft, textStyles, link && styles.link, - link && isHovered && styles.linkHover, + link && isHovered && StyleUtils.getColorStyle(theme.linkHover), link && styles.fontWeightNormal, link && styles.fontSizeLabel, ]} diff --git a/src/styles/index.ts b/src/styles/index.ts index 1686e9338409..7ae805093caa 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -588,10 +588,6 @@ const styles = (theme: ThemeColors) => borderRadius: variables.buttonBorderRadius, }, - linkHover: { - color: theme.linkHover, - }, - buttonText: { color: theme.text, fontFamily: FontUtils.fontFamily.platform.EXP_NEUE_BOLD, From 16de7cf5464a5c27277a52ebe340328ff218bbe9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 9 Jul 2024 15:28:42 -0600 Subject: [PATCH 082/137] fix lint --- src/libs/SearchUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts index 64449f4ebd96..22e75d4f8718 100644 --- a/src/libs/SearchUtils.ts +++ b/src/libs/SearchUtils.ts @@ -167,8 +167,8 @@ function getReportSections(data: OnyxTypes.SearchResults['data'], metadata: Onyx const isExpenseReport = reportItem.type === CONST.REPORT.TYPE.EXPENSE; const to = isExpenseReport - ? (data[`${ONYXKEYS.COLLECTION.POLICY}${reportItem.policyID}`] as SearchAccountDetails) - : (data.personalDetailsList?.[reportItem.managerID] as SearchAccountDetails); + ? (data[`${ONYXKEYS.COLLECTION.POLICY}${reportItem.policyID}`] as SearchAccountDetails) + : (data.personalDetailsList?.[reportItem.managerID] as SearchAccountDetails); reportIDToTransactions[reportKey] = { ...reportItem, From 7e3dce3a5d89f32f7a15e623df68845a55806870 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 10 Jul 2024 11:45:48 +0800 Subject: [PATCH 083/137] suppress lint --- src/components/Composer/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Composer/index.tsx b/src/components/Composer/index.tsx index 9e8de034186d..3889c8597843 100755 --- a/src/components/Composer/index.tsx +++ b/src/components/Composer/index.tsx @@ -120,6 +120,7 @@ function Composer( return; } setSelection(selectionProp); + // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, [selectionProp]); /** From 8887a464c7e1dc40e10e23221c289625632f22f7 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 10 Jul 2024 11:48:09 +0800 Subject: [PATCH 084/137] prettier --- src/components/ReportActionItem/ReportPreview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 3e0111a3e63e..a435a5723670 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -214,7 +214,7 @@ function ReportPreview({ } return CurrencyUtils.convertToDisplayString(reimbursableSpend, iouReport?.currency); - } + }; const getDisplayAmount = (): string => { if (totalDisplaySpend) { From 3ba56cb996d6cf6594274885dc1596721a0dca24 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 10 Jul 2024 10:03:30 +0200 Subject: [PATCH 085/137] fix: minor improvements --- .../expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx | 5 ++--- .../expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx index f639d8414017..6696e09437ac 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardBankAccounts.tsx @@ -27,13 +27,12 @@ function WorkspaceExpensifyCardBankAccounts({route}: WorkspaceExpensifyCardBankA const policyID = route.params.policyID ?? '-1'; const handleAddBankAccount = () => { + // TODO: call to API - UpdateCardSettlementAccount Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('new', policyID, ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID))); }; const handleSelectBankAccount = () => { - Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW); - // TODO: replace the previous line with this one after #44741 is merged - // Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID)); + Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_ISSUE_NEW.getRoute(policyID)); }; const renderBankOptions = () => { diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx index 458b2802da5a..15efb927a7d6 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardPageEmptyState.tsx @@ -65,7 +65,7 @@ function WorkspaceExpensifyCardPageEmptyState({route, policy}: WorkspaceExpensif } else { Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD_BANK_ACCOUNT.getRoute(policy?.id ?? '-1')); } - }, [bankAccountList]); + }, [bankAccountList, policy?.id]); return ( Date: Wed, 10 Jul 2024 17:40:36 +0700 Subject: [PATCH 086/137] fix update logic after big changes are merged in latest main --- .../SelectionList/Search/ActionCell.tsx | 28 +++++++++++++------ .../Search/ExpenseItemHeaderNarrow.tsx | 1 + 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/components/SelectionList/Search/ActionCell.tsx b/src/components/SelectionList/Search/ActionCell.tsx index 49e4d8c2ebee..7888a8b26114 100644 --- a/src/components/SelectionList/Search/ActionCell.tsx +++ b/src/components/SelectionList/Search/ActionCell.tsx @@ -63,13 +63,11 @@ function ActionCell({ } }, [action, currentSearchHash, transactionID]); - if (!isLargeScreenWidth) { - return null; - } - const text = translate(actionTranslationsMap[action]); - if ((parentAction !== CONST.SEARCH.ACTION_TYPES.PAI && action === CONST.SEARCH.ACTION_TYPES.PAID) || action === CONST.SEARCH.ACTION_TYPES.DONE) { + const shouldUseViewAction = action === CONST.SEARCH.ACTION_TYPES.VIEW || (parentAction === CONST.SEARCH.ACTION_TYPES.PAID && action === CONST.SEARCH.ACTION_TYPES.PAID); + + if ((parentAction !== CONST.SEARCH.ACTION_TYPES.PAID && action === CONST.SEARCH.ACTION_TYPES.PAID) || action === CONST.SEARCH.ACTION_TYPES.DONE) { return ( + ) : null; + } + + if (action === CONST.SEARCH.ACTION_TYPES.REVIEW) { return (