From 53828c7b306c4fa136db7e270ee1890ba248127c Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 28 Aug 2024 14:00:45 +0200 Subject: [PATCH 001/104] Add WorkspaceMembersSelectionList --- .../WorkspaceMembersSelectionList.tsx | 115 ++++++++++++++++++ .../categories/CategoryApproverPage.tsx | 60 +++++++++ 2 files changed, 175 insertions(+) create mode 100644 src/components/WorkspaceMembersSelectionList.tsx create mode 100644 src/pages/workspace/categories/CategoryApproverPage.tsx diff --git a/src/components/WorkspaceMembersSelectionList.tsx b/src/components/WorkspaceMembersSelectionList.tsx new file mode 100644 index 000000000000..f2ce215fc500 --- /dev/null +++ b/src/components/WorkspaceMembersSelectionList.tsx @@ -0,0 +1,115 @@ +import React, {useMemo} from 'react'; +import type {SectionListData} from 'react-native'; +import useDebouncedState from '@hooks/useDebouncedState'; +import useLocalize from '@hooks/useLocalize'; +import usePolicy from '@hooks/usePolicy'; +import useScreenWrapperTranstionStatus from '@hooks/useScreenWrapperTransitionStatus'; +import * as DeviceCapabilities from '@libs/DeviceCapabilities'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; +import CONST from '@src/CONST'; +import type {Icon} from '@src/types/onyx/OnyxCommon'; +import Badge from './Badge'; +import {FallbackAvatar} from './Icon/Expensicons'; +import {usePersonalDetails} from './OnyxProvider'; +import SelectionList from './SelectionList'; +import InviteMemberListItem from './SelectionList/InviteMemberListItem'; +import type {Section} from './SelectionList/types'; + +type WorkspaceMembersSelectionListProps = { + policyID: string; + selectedApprover: string; + setApprover: (email: string) => void; +}; + +type SelectionListApprover = { + text: string; + alternateText: string; + keyForList: string; + isSelected: boolean; + login: string; + rightElement?: React.ReactNode; + icons: Icon[]; +}; +type ApproverSection = SectionListData>; + +function WorkspaceMembersSelectionList({policyID, selectedApprover, setApprover}: WorkspaceMembersSelectionListProps) { + const {translate} = useLocalize(); + const {didScreenTransitionEnd} = useScreenWrapperTranstionStatus(); + const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState(''); + const personalDetails = usePersonalDetails(); + const policy = usePolicy(policyID); + + const sections: ApproverSection[] = useMemo(() => { + const approvers: SelectionListApprover[] = []; + + if (policy?.employeeList) { + const availableApprovers = Object.values(policy.employeeList) + .map((employee): SelectionListApprover | null => { + const isAdmin = employee?.role === CONST.REPORT.ROLE.ADMIN; + const email = employee.email; + + if (!email) { + return null; + } + + const policyMemberEmailsToAccountIDs = PolicyUtils.getMemberAccountIDsForWorkspace(policy?.employeeList); + const accountID = Number(policyMemberEmailsToAccountIDs[email] ?? ''); + const {avatar, displayName = email} = personalDetails?.[accountID] ?? {}; + + return { + text: displayName, + alternateText: email, + keyForList: email, + isSelected: selectedApprover === email, + login: email, + icons: [{source: avatar ?? FallbackAvatar, type: CONST.ICON_TYPE_AVATAR, name: displayName, id: accountID}], + rightElement: isAdmin ? : undefined, + }; + }) + .filter((approver): approver is SelectionListApprover => !!approver); + + approvers.push(...availableApprovers); + } + + const filteredApprovers = + debouncedSearchTerm !== '' + ? approvers.filter((option) => { + const searchValue = OptionsListUtils.getSearchValueForPhoneOrEmail(debouncedSearchTerm); + const isPartOfSearchTerm = !!option.text?.toLowerCase().includes(searchValue) || !!option.login?.toLowerCase().includes(searchValue); + return isPartOfSearchTerm; + }) + : approvers; + + return [ + { + title: undefined, + data: OptionsListUtils.sortAlphabetically(filteredApprovers, 'text'), + shouldShow: true, + }, + ]; + }, [debouncedSearchTerm, personalDetails, policy?.employeeList, selectedApprover, translate]); + + const handleOnSelectRow = (approver: SelectionListApprover) => { + setApprover(approver.login); + }; + + const headerMessage = useMemo(() => (searchTerm && !sections[0].data.length ? translate('common.noResultsFound') : ''), [searchTerm, sections, translate]); + + return ( + + ); +} + +export default WorkspaceMembersSelectionList; diff --git a/src/pages/workspace/categories/CategoryApproverPage.tsx b/src/pages/workspace/categories/CategoryApproverPage.tsx new file mode 100644 index 000000000000..ae882ceef149 --- /dev/null +++ b/src/pages/workspace/categories/CategoryApproverPage.tsx @@ -0,0 +1,60 @@ +import type {StackScreenProps} from '@react-navigation/stack'; +import React from 'react'; +import {useOnyx} from 'react-native-onyx'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import ScreenWrapper from '@components/ScreenWrapper'; +import WorkspaceMembersSelectionList from '@components/WorkspaceMembersSelectionList'; +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'; + +type EditCategoryPageProps = StackScreenProps; + +function CategoryApproverPage({ + route: { + params: {policyID, categoryName}, + }, +}: EditCategoryPageProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); + + return ( + + + Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))} + /> + { + Category.setPolicyCategoryApprover(policyID, categoryName, email); + Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))); + }} + /> + + + ); +} + +CategoryApproverPage.displayName = 'CategoryApproverPage'; + +export default CategoryApproverPage; From 374f29870cdc8c0ca00c6218b8ab8e161925cb07 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 28 Aug 2024 21:52:34 +0200 Subject: [PATCH 002/104] add interface for tag edit --- src/languages/en.ts | 2 + src/languages/es.ts | 130 ++---------------- .../categories/CategoryApproverPage.tsx | 110 +++++++-------- src/pages/workspace/tags/TagSettingsPage.tsx | 17 +++ 4 files changed, 82 insertions(+), 177 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index afa501c0b6bc..fb496e870e4b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2999,6 +2999,8 @@ export default { importedFromAccountingSoftware: 'The tags below are imported from your', glCode: 'GL code', updateGLCodeFailureMessage: 'An error occurred while updating the GL code, please try again.', + tagRules: 'Tag rules', + approverDescription: 'Approver', }, taxes: { subtitle: 'Add tax names, rates, and set defaults.', diff --git a/src/languages/es.ts b/src/languages/es.ts index 941592276dd7..062a57395c4f 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1,125 +1,8 @@ -import {Str} from 'expensify-common'; +import { Str } from 'expensify-common'; import CONST from '@src/CONST'; -import type {ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName} from '@src/types/onyx/Policy'; -import type { - AddressLineParams, - AdminCanceledRequestParams, - AlreadySignedInParams, - ApprovalWorkflowErrorParams, - ApprovedAmountParams, - BeginningOfChatHistoryAdminRoomPartOneParams, - BeginningOfChatHistoryAnnounceRoomPartOneParams, - BeginningOfChatHistoryAnnounceRoomPartTwo, - BeginningOfChatHistoryDomainRoomPartOneParams, - CanceledRequestParams, - ChangeFieldParams, - ChangePolicyParams, - ChangeTypeParams, - CharacterLimitParams, - ConfirmHoldExpenseParams, - ConfirmThatParams, - DateShouldBeAfterParams, - DateShouldBeBeforeParams, - DelegateSubmitParams, - DeleteActionParams, - DeleteConfirmationParams, - DeleteExpenseTranslationParams, - DidSplitAmountMessageParams, - DistanceRateOperationsParams, - EditActionParams, - ElectronicFundsParams, - EnglishTranslation, - EnterMagicCodeParams, - ExportedToIntegrationParams, - FormattedMaxLengthParams, - ForwardedAmountParams, - GoBackMessageParams, - GoToRoomParams, - InstantSummaryParams, - IssueVirtualCardParams, - LocalTimeParams, - LoggedInAsParams, - LogSizeParams, - ManagerApprovedAmountParams, - ManagerApprovedParams, - MarkedReimbursedParams, - MarkReimbursedFromIntegrationParams, - NoLongerHaveAccessParams, - NotAllowedExtensionParams, - NotYouParams, - OOOEventSummaryFullDayParams, - OOOEventSummaryPartialDayParams, - OurEmailProviderParams, - PaidElsewhereWithAmountParams, - PaidWithExpensifyWithAmountParams, - ParentNavigationSummaryParams, - PayerOwesAmountParams, - PayerOwesParams, - PayerPaidAmountParams, - PayerPaidParams, - PayerSettledParams, - PaySomeoneParams, - ReimbursementRateParams, - RemovedTheRequestParams, - RemoveMembersWarningPrompt, - RenamedRoomActionParams, - ReportArchiveReasonsClosedParams, - ReportArchiveReasonsMergedParams, - ReportArchiveReasonsPolicyDeletedParams, - ReportArchiveReasonsRemovedFromPolicyParams, - RequestAmountParams, - RequestCountParams, - RequestedAmountMessageParams, - ResolutionConstraintsParams, - RoomNameReservedErrorParams, - RoomRenamedToParams, - SetTheDistanceParams, - SetTheRequestParams, - SettledAfterAddedBankAccountParams, - SettleExpensifyCardParams, - ShareParams, - SignUpNewFaceCodeParams, - SizeExceededParams, - SplitAmountParams, - StepCounterParams, - StripePaidParams, - TaskCreatedActionParams, - TermsParams, - ThreadRequestReportNameParams, - ThreadSentMoneyReportNameParams, - ToValidateLoginParams, - TransferParams, - UnapprovedParams, - UnshareParams, - UntilTimeParams, - UpdatedTheDistanceParams, - UpdatedTheRequestParams, - UsePlusButtonParams, - UserIsAlreadyMemberParams, - UserSplitParams, - ViolationsAutoReportedRejectedExpenseParams, - ViolationsCashExpenseWithNoReceiptParams, - ViolationsConversionSurchargeParams, - ViolationsInvoiceMarkupParams, - ViolationsMaxAgeParams, - ViolationsMissingTagParams, - ViolationsModifiedAmountParams, - ViolationsOverAutoApprovalLimitParams, - ViolationsOverCategoryLimitParams, - ViolationsOverLimitParams, - ViolationsPerDayLimitParams, - ViolationsReceiptRequiredParams, - ViolationsRterParams, - ViolationsTagOutOfPolicyParams, - ViolationsTaxOutOfPolicyParams, - WaitingOnBankAccountParams, - WalletProgramParams, - WelcomeEnterMagicCodeParams, - WelcomeNoteParams, - WelcomeToRoomParams, - WeSentYouMagicSignInLinkParams, - ZipCodeExampleFormatParams, -} from './types'; +import type { ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName } from '@src/types/onyx/Policy'; +import type { AddressLineParams, AdminCanceledRequestParams, AlreadySignedInParams, ApprovalWorkflowErrorParams, ApprovedAmountParams, BeginningOfChatHistoryAdminRoomPartOneParams, BeginningOfChatHistoryAnnounceRoomPartOneParams, BeginningOfChatHistoryAnnounceRoomPartTwo, BeginningOfChatHistoryDomainRoomPartOneParams, CanceledRequestParams, ChangeFieldParams, ChangePolicyParams, ChangeTypeParams, CharacterLimitParams, ConfirmHoldExpenseParams, ConfirmThatParams, DateShouldBeAfterParams, DateShouldBeBeforeParams, DelegateSubmitParams, DeleteActionParams, DeleteConfirmationParams, DeleteExpenseTranslationParams, DidSplitAmountMessageParams, DistanceRateOperationsParams, EditActionParams, ElectronicFundsParams, EnglishTranslation, EnterMagicCodeParams, ExportedToIntegrationParams, FormattedMaxLengthParams, ForwardedAmountParams, GoBackMessageParams, GoToRoomParams, InstantSummaryParams, IssueVirtualCardParams, LocalTimeParams, LoggedInAsParams, LogSizeParams, ManagerApprovedAmountParams, ManagerApprovedParams, MarkedReimbursedParams, MarkReimbursedFromIntegrationParams, NoLongerHaveAccessParams, NotAllowedExtensionParams, NotYouParams, OOOEventSummaryFullDayParams, OOOEventSummaryPartialDayParams, OurEmailProviderParams, PaidElsewhereWithAmountParams, PaidWithExpensifyWithAmountParams, ParentNavigationSummaryParams, PayerOwesAmountParams, PayerOwesParams, PayerPaidAmountParams, PayerPaidParams, PayerSettledParams, PaySomeoneParams, ReimbursementRateParams, RemovedTheRequestParams, RemoveMembersWarningPrompt, RenamedRoomActionParams, ReportArchiveReasonsClosedParams, ReportArchiveReasonsMergedParams, ReportArchiveReasonsPolicyDeletedParams, ReportArchiveReasonsRemovedFromPolicyParams, RequestAmountParams, RequestCountParams, RequestedAmountMessageParams, ResolutionConstraintsParams, RoomNameReservedErrorParams, RoomRenamedToParams, SetTheDistanceParams, SetTheRequestParams, SettledAfterAddedBankAccountParams, SettleExpensifyCardParams, ShareParams, SignUpNewFaceCodeParams, SizeExceededParams, SplitAmountParams, StepCounterParams, StripePaidParams, TaskCreatedActionParams, TermsParams, ThreadRequestReportNameParams, ThreadSentMoneyReportNameParams, ToValidateLoginParams, TransferParams, UnapprovedParams, UnshareParams, UntilTimeParams, UpdatedTheDistanceParams, UpdatedTheRequestParams, UsePlusButtonParams, UserIsAlreadyMemberParams, UserSplitParams, ViolationsAutoReportedRejectedExpenseParams, ViolationsCashExpenseWithNoReceiptParams, ViolationsConversionSurchargeParams, ViolationsInvoiceMarkupParams, ViolationsMaxAgeParams, ViolationsMissingTagParams, ViolationsModifiedAmountParams, ViolationsOverAutoApprovalLimitParams, ViolationsOverCategoryLimitParams, ViolationsOverLimitParams, ViolationsPerDayLimitParams, ViolationsReceiptRequiredParams, ViolationsRterParams, ViolationsTagOutOfPolicyParams, ViolationsTaxOutOfPolicyParams, WaitingOnBankAccountParams, WalletProgramParams, WelcomeEnterMagicCodeParams, WelcomeNoteParams, WelcomeToRoomParams, WeSentYouMagicSignInLinkParams, ZipCodeExampleFormatParams } from './types'; + /* eslint-disable max-len */ export default { @@ -3047,6 +2930,8 @@ export default { importedFromAccountingSoftware: 'Etiquetas importadas desde', glCode: 'Código de Libro Mayor', updateGLCodeFailureMessage: 'Se produjo un error al actualizar el código de Libro Mayor. Por favor, inténtelo nuevamente.', + tagRules: 'Tag rules', + approverDescription: 'Approver', }, taxes: { subtitle: 'Añade nombres, tasas y establezca valores por defecto para los impuestos.', @@ -3771,6 +3656,7 @@ export default { pleaseEnterTaskName: 'Por favor, introduce un título', pleaseEnterTaskDestination: 'Por favor, selecciona dónde deseas compartir esta tarea.', }, + task: { task: 'Tarea', title: 'Título', @@ -5010,4 +4896,4 @@ export default { updateRoomDescription: 'establece la descripción de la sala a:', clearRoomDescription: 'la descripción de la habitación ha sido borrada', }, -} satisfies EnglishTranslation; +} satisfies EnglishTranslation; \ No newline at end of file diff --git a/src/pages/workspace/categories/CategoryApproverPage.tsx b/src/pages/workspace/categories/CategoryApproverPage.tsx index ae882ceef149..b02abd7f8524 100644 --- a/src/pages/workspace/categories/CategoryApproverPage.tsx +++ b/src/pages/workspace/categories/CategoryApproverPage.tsx @@ -1,60 +1,60 @@ -import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; -import {useOnyx} from 'react-native-onyx'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import WorkspaceMembersSelectionList from '@components/WorkspaceMembersSelectionList'; -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 type {StackScreenProps} from '@react-navigation/stack'; +// import React from 'react'; +// import {useOnyx} from 'react-native-onyx'; +// import HeaderWithBackButton from '@components/HeaderWithBackButton'; +// import ScreenWrapper from '@components/ScreenWrapper'; +// import WorkspaceMembersSelectionList from '@components/WorkspaceMembersSelectionList'; +// 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'; -type EditCategoryPageProps = StackScreenProps; +// type EditCategoryPageProps = StackScreenProps; -function CategoryApproverPage({ - route: { - params: {policyID, categoryName}, - }, -}: EditCategoryPageProps) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); +// function CategoryApproverPage({ +// route: { +// params: {policyID, categoryName}, +// }, +// }: EditCategoryPageProps) { +// const styles = useThemeStyles(); +// const {translate} = useLocalize(); +// const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); - return ( - - - Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))} - /> - { - Category.setPolicyCategoryApprover(policyID, categoryName, email); - Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))); - }} - /> - - - ); -} +// return ( +// +// +// Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))} +// /> +// { +// Category.setPolicyCategoryApprover(policyID, categoryName, email); +// Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))); +// }} +// /> +// +// +// ); +// } -CategoryApproverPage.displayName = 'CategoryApproverPage'; +// CategoryApproverPage.displayName = 'CategoryApproverPage'; -export default CategoryApproverPage; +// export default CategoryApproverPage; diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index a0f98ef699ed..c4dbd85a0821 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -85,6 +85,10 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) Navigation.navigate(ROUTES.WORKSPACE_TAG_GL_CODE.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); }; + const navigateToEditTagApprover = () => { + Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); + }; + const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; const isMultiLevelTags = PolicyUtils.isMultiLevelTags(policyTags); @@ -150,6 +154,19 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) shouldShowRightIcon /> + + + {translate('workspace.tags.tagRules')} + + + + + {shouldShowDeleteMenuItem && ( Date: Thu, 29 Aug 2024 12:38:52 +0200 Subject: [PATCH 003/104] wire up the tags --- src/ROUTES.ts | 4 ++ src/SCREENS.ts | 1 + .../WorkspaceMembersSelectionList.tsx | 2 +- .../parameters/SetPolicyTagApproverParams.ts | 7 ++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 11 ++-- .../ModalStackNavigators/index.tsx | 1 + .../FULL_SCREEN_TO_RHP_MAPPING.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 7 ++ src/libs/Navigation/types.ts | 5 ++ src/libs/actions/Policy/Tag.ts | 12 ++++ src/pages/workspace/tags/TagApproverPage.tsx | 64 +++++++++++++++++++ src/pages/workspace/tags/TagSettingsPage.tsx | 28 ++++---- src/types/onyx/Policy.ts | 52 +++++++++++++++ 14 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 src/libs/API/parameters/SetPolicyTagApproverParams.ts create mode 100644 src/pages/workspace/tags/TagApproverPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 6f9289e0b283..4fc164d91830 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -786,6 +786,10 @@ const ROUTES = { route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName', getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${encodeURIComponent(tagName)}` as const, }, + WORKSPACE_TAG_APPROVER: { + route: 'settings/workspaces/:policyID/tag/:orderWeight/:tagName/approver', + getRoute: (policyID: string, orderWeight: number, tagName: string) => `settings/workspaces/${policyID}/tag/${orderWeight}/${tagName}/approver` as const, + }, WORKSPACE_TAG_LIST_VIEW: { route: 'settings/workspaces/:policyID/tag-list/:orderWeight', getRoute: (policyID: string, orderWeight: number) => `settings/workspaces/${policyID}/tag-list/${orderWeight}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index e8c1f71b9db0..d2ec2e6b249a 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -408,6 +408,7 @@ const SCREENS = { TAX_CREATE: 'Workspace_Tax_Create', TAG_CREATE: 'Tag_Create', TAG_SETTINGS: 'Tag_Settings', + TAG_APPROVER: 'Tag_Approver', TAG_LIST_VIEW: 'Tag_List_View', TAG_GL_CODE: 'Tag_GL_Code', CURRENCY: 'Workspace_Profile_Currency', diff --git a/src/components/WorkspaceMembersSelectionList.tsx b/src/components/WorkspaceMembersSelectionList.tsx index f2ce215fc500..fb98fe9fb447 100644 --- a/src/components/WorkspaceMembersSelectionList.tsx +++ b/src/components/WorkspaceMembersSelectionList.tsx @@ -84,7 +84,7 @@ function WorkspaceMembersSelectionList({policyID, selectedApprover, setApprover} return [ { title: undefined, - data: OptionsListUtils.sortAlphabetically(filteredApprovers, 'text'), + data: filteredApprovers, shouldShow: true, }, ]; diff --git a/src/libs/API/parameters/SetPolicyTagApproverParams.ts b/src/libs/API/parameters/SetPolicyTagApproverParams.ts new file mode 100644 index 000000000000..fbd086dfebed --- /dev/null +++ b/src/libs/API/parameters/SetPolicyTagApproverParams.ts @@ -0,0 +1,7 @@ +type SetPolicyTagApproverParams = { + policyID: string; + tagName: string; + email: string; +}; + +export default SetPolicyTagApproverParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index fe2e89faa7f0..537897514f87 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -289,3 +289,4 @@ export type {default as OpenCardDetailsPageParams} from './OpenCardDetailsPagePa export type {default as EnablePolicyCompanyCardsParams} from './EnablePolicyCompanyCardsParams'; export type {default as ToggleCardContinuousReconciliationParams} from './ToggleCardContinuousReconciliationParams'; export type {default as UpdateExpensifyCardLimitTypeParams} from './UpdateExpensifyCardLimitTypeParams'; +export type {default as SetPolicyTagApproverParams} from './SetPolicyTagApproverParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 5dad9820ea19..f892de8d3e89 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -1,11 +1,12 @@ -import type {ValueOf} from 'type-fest'; +import type { ValueOf } from 'type-fest'; import type CONST from '@src/CONST'; -import type {SageIntacctMappingValue} from '@src/types/onyx/Policy'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; +import type { SageIntacctMappingValue } from '@src/types/onyx/Policy'; +import type { EmptyObject } from '@src/types/utils/EmptyObject'; import type * as Parameters from './parameters'; import type SignInUserParams from './parameters/SignInUserParams'; import type UpdateBeneficialOwnersForBankAccountParams from './parameters/UpdateBeneficialOwnersForBankAccountParams'; + type ApiRequestType = ValueOf; const WRITE_COMMANDS = { @@ -345,6 +346,7 @@ const WRITE_COMMANDS = { CREATE_EXPENSIFY_CARD: 'CreateExpensifyCard', CREATE_ADMIN_ISSUED_VIRTUAL_CARD: 'CreateAdminIssuedVirtualCard', TOGGLE_CARD_CONTINUOUS_RECONCILIATION: 'ToggleCardContinuousReconciliation', + SET_POLICY_TAG_APPROVER: 'SetPolicyTagApprover', } as const; type WriteCommand = ValueOf; @@ -557,6 +559,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.DECLINE_JOIN_REQUEST]: Parameters.DeclineJoinRequestParams; [WRITE_COMMANDS.SET_POLICY_TAXES_CURRENCY_DEFAULT]: Parameters.SetPolicyCurrencyDefaultParams; [WRITE_COMMANDS.SET_POLICY_CUSTOM_TAX_NAME]: Parameters.SetPolicyCustomTaxNameParams; + [WRITE_COMMANDS.SET_POLICY_TAG_APPROVER]: Parameters.SetPolicyTagApproverParams; [WRITE_COMMANDS.SET_POLICY_TAXES_FOREIGN_CURRENCY_DEFAULT]: Parameters.SetPolicyForeignCurrencyDefaultParams; [WRITE_COMMANDS.CREATE_POLICY_TAX]: Parameters.CreatePolicyTaxParams; [WRITE_COMMANDS.SET_POLICY_TAXES_ENABLED]: Parameters.SetPolicyTaxesEnabledParams; @@ -854,4 +857,4 @@ type CommandOfType = TRequestType extends t ? ReadCommand : SideEffectRequestCommand; -export type {ApiCommand, ApiRequestType, ApiRequestCommandParameters, CommandOfType, WriteCommand, ReadCommand, SideEffectRequestCommand}; +export type {ApiCommand, ApiRequestType, ApiRequestCommandParameters, CommandOfType, WriteCommand, ReadCommand, SideEffectRequestCommand}; \ No newline at end of file diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 9c95edd8be9c..3564c6fd6774 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -260,6 +260,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/workspace/tags/WorkspaceEditTagsPage').default, [SCREENS.WORKSPACE.TAG_CREATE]: () => require('../../../../pages/workspace/tags/WorkspaceCreateTagPage').default, [SCREENS.WORKSPACE.TAG_EDIT]: () => require('../../../../pages/workspace/tags/EditTagPage').default, + [SCREENS.WORKSPACE.TAG_APPROVER]: () => require('../../../../pages/workspace/tags/TagApproverPage').default, [SCREENS.WORKSPACE.TAG_GL_CODE]: () => require('../../../../pages/workspace/tags/TagGLCodePage').default, [SCREENS.WORKSPACE.TAXES_SETTINGS]: () => require('../../../../pages/workspace/taxes/WorkspaceTaxesSettingsPage').default, [SCREENS.WORKSPACE.TAXES_SETTINGS_CUSTOM_TAX_NAME]: () => require('../../../../pages/workspace/taxes/WorkspaceTaxesSettingsCustomTaxName').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 72ce7d6d1058..156db729fb8b 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -133,6 +133,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.TAG_EDIT, SCREENS.WORKSPACE.TAG_LIST_VIEW, SCREENS.WORKSPACE.TAG_GL_CODE, + SCREENS.WORKSPACE.TAG_APPROVER, ], [SCREENS.WORKSPACE.CATEGORIES]: [ SCREENS.WORKSPACE.CATEGORY_CREATE, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 0db9c5833fd4..67b588c43148 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -626,6 +626,13 @@ const config: LinkingOptions['config'] = { tagName: (tagName: string) => decodeURIComponent(tagName), }, }, + [SCREENS.WORKSPACE.TAG_APPROVER]: { + path: ROUTES.WORKSPACE_TAG_APPROVER.route, + parse: { + orderWeight: Number, + tagName: (tagName: string) => decodeURIComponent(tagName), + }, + }, [SCREENS.WORKSPACE.TAG_GL_CODE]: { path: ROUTES.WORKSPACE_TAG_GL_CODE.route, parse: { diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index c856e7d89425..e55875c89b2d 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -274,6 +274,11 @@ type SettingsNavigatorParamList = { orderWeight: number; tagName: string; }; + [SCREENS.WORKSPACE.TAG_APPROVER]: { + policyID: string; + orderWeight: number; + tagName: string; + }; [SCREENS.WORKSPACE.TAG_GL_CODE]: { policyID: string; orderWeight: number; diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 49a285c12bbe..f6ab37dd1b98 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -6,6 +6,7 @@ import type { OpenPolicyTagsPageParams, RenamePolicyTaglistParams, RenamePolicyTagsParams, + SetPolicyTagApproverParams, SetPolicyTagsEnabled, SetPolicyTagsRequired, UpdatePolicyTagGLCodeParams, @@ -846,6 +847,16 @@ function setPolicyTagGLCode(policyID: string, tagName: string, tagListIndex: num API.write(WRITE_COMMANDS.UPDATE_POLICY_TAG_GL_CODE, parameters, onyxData); } +function setPolicyTagApprover(policyID: string, tag: string, approver: string) { + const parameters: SetPolicyTagApproverParams = { + policyID, + tagName: tag, + email: approver, + }; + + API.write(WRITE_COMMANDS.SET_POLICY_TAG_APPROVER, parameters); +} + export { buildOptimisticPolicyRecentlyUsedTags, setPolicyRequiresTag, @@ -861,6 +872,7 @@ export { renamePolicyTaglist, setWorkspaceTagEnabled, setPolicyTagGLCode, + setPolicyTagApprover, }; export type {NewCustomUnit}; diff --git a/src/pages/workspace/tags/TagApproverPage.tsx b/src/pages/workspace/tags/TagApproverPage.tsx new file mode 100644 index 000000000000..5f2f0a50fdc9 --- /dev/null +++ b/src/pages/workspace/tags/TagApproverPage.tsx @@ -0,0 +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 ScreenWrapper from '@components/ScreenWrapper'; +import WorkspaceMembersSelectionList from '@components/WorkspaceMembersSelectionList'; +import useLocalize from '@hooks/useLocalize'; +import usePolicy from '@hooks/usePolicy'; +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 Tag from '@userActions/Policy/Tag'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; + +type TagApproverPageProps = StackScreenProps; + +function TagApproverPage({route}: TagApproverPageProps) { + const {policyID, orderWeight, tagName} = route.params; + + const policy = usePolicy(policyID); + const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`); + + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + const policyExpenseRules = policy?.rules?.expenseRules; + // const tagExpenseRule = policyExpenseRules?.find(({applyWhen}) => applyWhen.some(({condition, field, value}) => condition === 'matches' && field === 'tag' && value === tagName)); + + console.log('POLICY EXPENSE RULES ', policyTags); + return ( + + + Navigation.goBack()} + /> + { + Tag.setPolicyTagApprover(policyID, tagName, email); + Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack); + }} + /> + + + ); +} + +TagApproverPage.displayName = 'TagApproverPage'; + +export default TagApproverPage; diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index c4dbd85a0821..103b7e659680 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -86,7 +86,7 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) }; const navigateToEditTagApprover = () => { - Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_APPROVER.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); }; const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; @@ -155,17 +155,21 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) /> - - {translate('workspace.tags.tagRules')} - - - - + {policy?.areRulesEnabled && ( + <> + + {translate('workspace.tags.tagRules')} + + + + + + )} {shouldShowDeleteMenuItem && ( ; }; +/** + * + */ +type ExpenseRule = { + /** Set of conditions under which the expense rule should be applied */ + applyWhen: ApplyRulesWhen[]; + + /** Policy tag approver */ + approver: string; + + /** An id of the rule */ + id: string; +}; + +/** Data informing when a given rule should be applied */ +type ApplyRulesWhen = { + /** The condition for applying the rule to the workspace */ + condition: 'matches'; + + /** The target field to which the rule is applied */ + field: 'category' | 'tag'; + + /** The value of the target field */ + value: string; +}; + +/** Approval rule data model */ +type ApprovalRule = { + /** The approver's email */ + approver: string; + + /** Set of conditions under which the approval rule should be applied */ + applyWhen: ApplyRulesWhen[]; + + /** An id of the rule */ + id: string; +}; + /** Model of policy data */ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< { @@ -1510,6 +1548,20 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** Collection of tax rates attached to a policy */ taxRates?: TaxRatesWithDefault; + /** A set of rules related to the workpsace */ + rules?: { + /** A set of rules related to the workpsace approvals */ + approvalRules?: ApprovalRule[]; + + /** A set of rules related to the workpsace expenses */ + expenseRules?: ExpenseRule[]; + }; + + /** + * + */ + expenseRules?: ExpenseRule[]; + /** ReportID of the admins room for this workspace */ chatReportIDAdmins?: number; From 4a3bfcc806c3d3f0bf52e5c59e71ad4a0c323bf2 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Fri, 30 Aug 2024 13:20:16 +0200 Subject: [PATCH 004/104] wire up action --- .../parameters/SetPolicyTagApproverParams.ts | 2 +- src/libs/PolicyUtils.ts | 10 +++ src/libs/actions/Policy/Tag.ts | 65 ++++++++++++++++++- src/pages/workspace/tags/TagApproverPage.tsx | 8 +-- src/pages/workspace/tags/TagSettingsPage.tsx | 5 +- src/types/onyx/Policy.ts | 4 +- 6 files changed, 83 insertions(+), 11 deletions(-) diff --git a/src/libs/API/parameters/SetPolicyTagApproverParams.ts b/src/libs/API/parameters/SetPolicyTagApproverParams.ts index fbd086dfebed..0e9b286ba816 100644 --- a/src/libs/API/parameters/SetPolicyTagApproverParams.ts +++ b/src/libs/API/parameters/SetPolicyTagApproverParams.ts @@ -1,7 +1,7 @@ type SetPolicyTagApproverParams = { policyID: string; tagName: string; - email: string; + approver: string; }; export default SetPolicyTagApproverParams; diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 3f3a2a96a1e1..b914f3d7816c 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -969,6 +969,15 @@ function getWorkspaceAccountID(policyID: string) { return policy.workspaceAccountID ?? 0; } +function getTagExpenseRule(policyID: string, tagName: string) { + const policy = getPolicy(policyID); + + const expenseRules = policy?.rules?.expenseRules ?? []; + const expenseRule = expenseRules.find((rule) => rule.applyWhen.find(({condition, field, value}) => condition === 'matches' && field === 'tag' && value === tagName)); + + return expenseRule; +} + export { canEditTaxRate, extractPolicyIDFromPath, @@ -1074,6 +1083,7 @@ export { getWorkspaceAccountID, getAllTaxRatesNamesAndKeys as getAllTaxRates, getTagNamesFromTagsLists, + getTagExpenseRule, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index f6ab37dd1b98..d02a42cccd98 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -848,13 +848,74 @@ function setPolicyTagGLCode(policyID: string, tagName: string, tagListIndex: num } function setPolicyTagApprover(policyID: string, tag: string, approver: string) { + const policy = PolicyUtils.getPolicy(policyID); + const prevExpenseRules = policy?.rules?.approvalRules ?? []; + const expenseRuleToUpdate = PolicyUtils.getTagExpenseRule(policyID, tag); + const filteredExpenseRules = expenseRuleToUpdate ? prevExpenseRules.filter((rule) => rule.id === expenseRuleToUpdate.id) : prevExpenseRules; + + const updatedExpenseRule = expenseRuleToUpdate + ? {...expenseRuleToUpdate, approver} + : { + applyWhen: [ + { + condition: 'matches', + field: 'tag', + value: tag, + }, + ], + approver, + id: '-1', + }; + + const onyxData: OnyxData = { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + rules: { + expenseRules: [...filteredExpenseRules, updatedExpenseRule], + }, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + pendingFields: {rules: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + }, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + rules: { + expenseRules: [...filteredExpenseRules, updatedExpenseRule], + }, + pendingAction: null, + pendingFields: {rules: null}, + }, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + rules: { + expenseRules: prevExpenseRules, + }, + pendingAction: null, + pendingFields: {rules: null}, + }, + }, + ], + }; + const parameters: SetPolicyTagApproverParams = { policyID, tagName: tag, - email: approver, + approver, }; - API.write(WRITE_COMMANDS.SET_POLICY_TAG_APPROVER, parameters); + API.write(WRITE_COMMANDS.SET_POLICY_TAG_APPROVER, parameters, onyxData); } export { diff --git a/src/pages/workspace/tags/TagApproverPage.tsx b/src/pages/workspace/tags/TagApproverPage.tsx index 5f2f0a50fdc9..ce3fa822e761 100644 --- a/src/pages/workspace/tags/TagApproverPage.tsx +++ b/src/pages/workspace/tags/TagApproverPage.tsx @@ -8,6 +8,7 @@ import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; +import * as PolicyUtils from '@libs/PolicyUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import * as Tag from '@userActions/Policy/Tag'; @@ -26,10 +27,9 @@ function TagApproverPage({route}: TagApproverPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const policyExpenseRules = policy?.rules?.expenseRules; - // const tagExpenseRule = policyExpenseRules?.find(({applyWhen}) => applyWhen.some(({condition, field, value}) => condition === 'matches' && field === 'tag' && value === tagName)); + const tagApprover = PolicyUtils.getTagExpenseRule(policyID, tagName)?.approver; - console.log('POLICY EXPENSE RULES ', policyTags); + console.log('POLICY ', policy); return ( { Tag.setPolicyTagApprover(policyID, tagName, email); Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack); diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index 103b7e659680..92166504dd7d 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -91,6 +91,7 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; const isMultiLevelTags = PolicyUtils.isMultiLevelTags(policyTags); + const tagApprover = PolicyUtils.getTagExpenseRule(route.params.policyID, currentPolicyTag.name)?.approver; const shouldShowDeleteMenuItem = !isThereAnyAccountingConnection && !isMultiLevelTags; @@ -160,9 +161,9 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) {translate('workspace.tags.tagRules')} - + Date: Sat, 7 Sep 2024 20:54:16 +0530 Subject: [PATCH 005/104] Implemented new page structure for export Sage Intacct --- src/ROUTES.ts | 8 + src/SCREENS.ts | 2 + .../ModalStackNavigators/index.tsx | 4 + .../FULL_SCREEN_TO_RHP_MAPPING.ts | 2 + src/libs/Navigation/linkingConfig/config.ts | 2 + src/libs/Navigation/types.ts | 6 + ...NonReimbursableExpensesDestinationPage.tsx | 69 ++++++ ...SageIntacctNonReimbursableExpensesPage.tsx | 220 ++++++++---------- ...cctReimbursableExpensesDestinationPage.tsx | 73 ++++++ .../SageIntacctReimbursableExpensesPage.tsx | 174 ++++++-------- .../workspace/accounting/intacct/types.ts | 30 +++ 11 files changed, 365 insertions(+), 225 deletions(-) create mode 100644 src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx create mode 100644 src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx create mode 100644 src/pages/workspace/accounting/intacct/types.ts diff --git a/src/ROUTES.ts b/src/ROUTES.ts index a28c2ef4fc57..951780c2b97c 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1399,6 +1399,14 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/sage-intacct/export/nonreimbursable', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/export/nonreimbursable` as const, }, + POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_DESTINATION: { + route: 'settings/workspaces/:policyID/accounting/sage-intacct/export/reimbursable/destination', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/export/reimbursable/destination` as const, + }, + POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION: { + route: 'settings/workspaces/:policyID/accounting/sage-intacct/export/nonreimbursable/destination', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/export/nonreimbursable/destination` as const, + }, POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR: { route: 'settings/workspaces/:policyID/accounting/sage-intacct/export/:reimbursable/default-vendor', getRoute: (policyID: string, reimbursable: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/export/${reimbursable}/default-vendor` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 67ba5b84c9ec..b59beece461c 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -354,6 +354,8 @@ const SCREENS = { SAGE_INTACCT_EXPORT_DATE: 'Policy_Accounting_Sage_Intacct_Export_Date', SAGE_INTACCT_REIMBURSABLE_EXPENSES: 'Policy_Accounting_Sage_Intacct_Reimbursable_Expenses', SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES: 'Policy_Accounting_Sage_Intacct_Non_Reimbursable_Expenses', + SAGE_INTACCT_REIMBURSABLE_DESTINATION: 'Policy_Accounting_Sage_Intacct_Reimbursable_Destination', + SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION: 'Policy_Accounting_Sage_Intacct_Non_Reimbursable_Destination', SAGE_INTACCT_DEFAULT_VENDOR: 'Policy_Accounting_Sage_Intacct_Default_Vendor', SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT: 'Policy_Accounting_Sage_Intacct_Non_Reimbursable_Credit_Card_Account', SAGE_INTACCT_ADVANCED: 'Policy_Accounting_Sage_Intacct_Advanced', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 1b2390b17c39..17e283d42bf1 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -405,6 +405,10 @@ const SettingsModalStackNavigator = createModalStackNavigator('../../../../pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage').default, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES]: () => require('../../../../pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_DESTINATION]: () => + require('../../../../pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION]: () => + require('../../../../pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage').default, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR]: () => require('../../../../pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage').default, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT]: () => 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 ef634d9cb615..6279cca48a4e 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -106,6 +106,8 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial> = { SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_EXPORT_DATE, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_EXPENSES, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES, + SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_DESTINATION, + SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT, SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_ADVANCED, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 65fb05f8d008..c209755f3348 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -456,6 +456,8 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_EXPORT_DATE]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT_DATE.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_EXPENSES]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_EXPENSES.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.route}, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_DESTINATION]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_DESTINATION.route}, + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR]: {path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.route}, [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT]: { path: ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT.route, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index ee46cbd238ef..1c64b9e78fe2 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -604,6 +604,12 @@ type SettingsNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_REIMBURSABLE_DESTINATION]: { + policyID: string; + }; + [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION]: { + policyID: string; + }; [SCREENS.WORKSPACE.ACCOUNTING.SAGE_INTACCT_DEFAULT_VENDOR]: { policyID: string; reimbursable: string; diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx new file mode 100644 index 000000000000..1355b07773ed --- /dev/null +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx @@ -0,0 +1,69 @@ +import React, {useCallback} from 'react'; +import type {ValueOf} from 'type-fest'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import SelectionScreen from '@components/SelectionScreen'; +import type {SelectorType} from '@components/SelectionScreen'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import {settingsPendingAction} from '@libs/PolicyUtils'; +import Navigation from '@navigation/Navigation'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {updateSageIntacctNonreimbursableExpensesExportDestination} from '@userActions/connections/SageIntacct'; +import * as Policy from '@userActions/Policy/Policy'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +type MenuListItem = ListItem & { + value: ValueOf; +}; + +function SageIntacctNonReimbursableExpensesDestinationPage({policy}: WithPolicyConnectionsProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const policyID = policy?.id ?? '-1'; + const {config} = policy?.connections?.intacct ?? {}; + + const data: MenuListItem[] = Object.values(CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE).map((expenseType) => ({ + value: expenseType, + text: translate(`workspace.sageIntacct.nonReimbursableExpenses.values.${expenseType}`), + keyForList: expenseType, + isSelected: config?.export.nonReimbursable === expenseType, + })); + + const selectDestination = useCallback( + (row: MenuListItem) => { + if (row.value !== config?.export.nonReimbursable) { + updateSageIntacctNonreimbursableExpensesExportDestination(policyID, row.value, config?.export.nonReimbursable); + } + Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); + }, + [config?.export.nonReimbursable, policyID], + ); + + return ( + selectDestination(selection as MenuListItem)} + initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} + policyID={policyID} + accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID))} + connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} + pendingAction={settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE], config?.pendingFields)} + errors={ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE)} + errorRowStyles={[styles.ph5, styles.pv3]} + onClose={() => Policy.clearNetSuiteErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE)} + /> + ); +} + +SageIntacctNonReimbursableExpensesDestinationPage.displayName = 'SageIntacctNonReimbursableExpensesDestinationPage'; + +export default withPolicyConnections(SageIntacctNonReimbursableExpensesDestinationPage); diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index 808c497c05da..b886ff5e43a2 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -1,173 +1,137 @@ -import React, {useCallback, useMemo} from 'react'; -import {View} from 'react-native'; -import type {ValueOf} from 'type-fest'; +import React from 'react'; import ConnectionLayout from '@components/ConnectionLayout'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import SelectionList from '@components/SelectionList'; -import RadioListItem from '@components/SelectionList/RadioListItem'; -import type {ListItem} from '@components/SelectionList/types'; -import type {SelectorType} from '@components/SelectionScreen'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; import {areSettingsInErrorFields, getSageIntacctNonReimbursableActiveDefaultVendor, settingsPendingAction} from '@libs/PolicyUtils'; -import Navigation from '@navigation/Navigation'; -import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import type {MenuItem, ToggleItem} from '@pages/workspace/accounting/intacct/types'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; -import {updateSageIntacctDefaultVendor, updateSageIntacctNonreimbursableExpensesExportDestination} from '@userActions/connections/SageIntacct'; +import {updateSageIntacctDefaultVendor} from '@userActions/connections/SageIntacct'; import * as Policy from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {SageIntacctDataElementWithValue} from '@src/types/onyx/Policy'; -type MenuListItem = ListItem & { - value: ValueOf; -}; +type MenuItemWithSubscribedSettings = Pick & {subscribedSettings?: string[]}; function getDefaultVendorName(defaultVendor?: string, vendors?: SageIntacctDataElementWithValue[]): string | undefined { return (vendors ?? []).find((vendor) => vendor.id === defaultVendor)?.value ?? defaultVendor; } -function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { +function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; const styles = useThemeStyles(); const {data: intacctData, config} = policy?.connections?.intacct ?? {}; - const data: MenuListItem[] = Object.values(CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE).map((expenseType) => ({ - value: expenseType, - text: translate(`workspace.sageIntacct.nonReimbursableExpenses.values.${expenseType}`), - keyForList: expenseType, - isSelected: config?.export.nonReimbursable === expenseType, - })); + const activeDefaultVendor = getSageIntacctNonReimbursableActiveDefaultVendor(policy); + const defaultVendorName = getDefaultVendorName(activeDefaultVendor, intacctData?.vendors); - const selectNonReimbursableExpense = useCallback( - (row: MenuListItem) => { - if (row.value === config?.export.nonReimbursable) { - return; - } - updateSageIntacctNonreimbursableExpensesExportDestination(policyID, row.value, config?.export.nonReimbursable); + const menuItems: Array = [ + { + type: 'menuitem', + title: config?.export.nonReimbursable + ? translate(`workspace.sageIntacct.nonReimbursableExpenses.values.${config?.export.nonReimbursable}`) + : translate('workspace.sageIntacct.notConfigured'), + description: translate('workspace.accounting.exportAs'), + onPress: () => { + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_DESTINATION.getRoute(policyID)); + }, + subscribedSettings: [CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE], }, - [config?.export.nonReimbursable, policyID], - ); - - const defaultVendor = useMemo(() => { - const activeDefaultVendor = getSageIntacctNonReimbursableActiveDefaultVendor(policy); - const defaultVendorName = getDefaultVendorName(activeDefaultVendor, intacctData?.vendors); - - const defaultVendorSection = { - description: translate('workspace.sageIntacct.defaultVendor'), - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE.toLowerCase())), + { + type: 'menuitem', + title: config?.export.nonReimbursableAccount ? config.export.nonReimbursableAccount : translate('workspace.sageIntacct.notConfigured'), + description: translate('workspace.sageIntacct.creditCardAccount'), + onPress: () => { + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT.getRoute(policyID)); + }, + subscribedSettings: [CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_ACCOUNT], + shouldHide: config?.export.nonReimbursable !== CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE, + }, + { + type: 'toggle', + title: translate('workspace.sageIntacct.defaultVendor'), + subtitle: translate('workspace.sageIntacct.defaultVendorDescription', false), + isActive: !!config?.export.nonReimbursableCreditCardChargeDefaultVendor, + switchAccessibilityLabel: translate('workspace.sageIntacct.defaultVendor'), + onToggle: (enabled) => { + const vendor = enabled ? policy?.connections?.intacct?.data?.vendors?.[0].id ?? '' : ''; + updateSageIntacctDefaultVendor(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR, vendor, config?.export.nonReimbursableCreditCardChargeDefaultVendor); + }, + onCloseError: () => Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR), + pendingAction: settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR], config?.pendingFields), + errors: ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR), + shouldHide: config?.export.nonReimbursable !== CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE, + }, + { + type: 'menuitem', title: defaultVendorName && defaultVendorName !== '' ? defaultVendorName : translate('workspace.sageIntacct.notConfigured'), + description: translate('workspace.sageIntacct.defaultVendor'), + onPress: () => { + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE.toLowerCase())); + }, subscribedSettings: [ config?.export.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL ? CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_VENDOR : CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR, ], - }; - - return ( - - - - ); - }, [config?.errorFields, config?.export.nonReimbursable, config?.pendingFields, intacctData?.vendors, policy, policyID, translate]); - - const creditCardAccount = useMemo(() => { - const creditCardAccountSection = { - description: translate('workspace.sageIntacct.creditCardAccount'), - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_CREDIT_CARD_ACCOUNT.getRoute(policyID)), - title: config?.export.nonReimbursableAccount ? config.export.nonReimbursableAccount : translate('workspace.sageIntacct.notConfigured'), - subscribedSettings: [CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_ACCOUNT], - }; - - return ( - - - - ); - }, [config?.errorFields, config?.export.nonReimbursableAccount, config?.pendingFields, policyID, translate]); + shouldHide: + !config?.export.nonReimbursable || + (config?.export.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE && !config?.export.nonReimbursableCreditCardChargeDefaultVendor), + }, + ]; return ( Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID))} accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} - featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} - displayName={SageIntacctNonReimbursableExpensesPage.displayName} policyID={policyID} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + contentContainerStyle={styles.pb2} + titleStyle={styles.ph5} connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} - shouldUseScrollView={false} - shouldIncludeSafeAreaPaddingBottom > - Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE)} - style={[styles.flexGrow1, styles.flexShrink1]} - contentContainerStyle={[styles.flexGrow1, styles.flexShrink1]} - > - selectNonReimbursableExpense(selection as MenuListItem)} - sections={[{data}]} - ListItem={RadioListItem} - showScrollIndicator - shouldShowTooltips={false} - containerStyle={[styles.flexReset, styles.flexGrow1, styles.flexShrink1, styles.pb0]} - /> - - - {config?.export.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL && defaultVendor} - {config?.export.nonReimbursable === CONST.SAGE_INTACCT_NON_REIMBURSABLE_EXPENSE_TYPE.CREDIT_CARD_CHARGE && ( - - {creditCardAccount} - { - const vendor = enabled ? policy?.connections?.intacct?.data?.vendors?.[0].id ?? '' : ''; - updateSageIntacctDefaultVendor( - policyID, - CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR, - vendor, - config?.export.nonReimbursableCreditCardChargeDefaultVendor, - ); - }} - wrapperStyle={[styles.ph5, styles.pv3]} - pendingAction={settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR], config?.pendingFields)} - errors={ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR)} - onCloseError={() => Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR)} - /> - {!!config?.export.nonReimbursableCreditCardChargeDefaultVendor && defaultVendor} - - )} - + {menuItems + .filter((item) => !item.shouldHide) + .map((item) => { + switch (item.type) { + case 'toggle': + // eslint-disable-next-line no-case-declarations + const {type, shouldHide, ...rest} = item; + return ( + + ); + default: + return ( + + + + ); + } + })} ); } diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx new file mode 100644 index 000000000000..aad242798324 --- /dev/null +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx @@ -0,0 +1,73 @@ +import React, {useCallback} from 'react'; +import type {ValueOf} from 'type-fest'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import SelectionScreen from '@components/SelectionScreen'; +import type {SelectorType} from '@components/SelectionScreen'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import {settingsPendingAction} from '@libs/PolicyUtils'; +import Navigation from '@navigation/Navigation'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {changeMappingsValueFromDefaultToTag, updateSageIntacctReimbursableExpensesExportDestination} from '@userActions/connections/SageIntacct'; +import * as Policy from '@userActions/Policy/Policy'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +type MenuListItem = ListItem & { + value: ValueOf; +}; + +function SageIntacctReimbursableExpensesDestinationPage({policy}: WithPolicyConnectionsProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const policyID = policy?.id ?? '-1'; + const {config} = policy?.connections?.intacct ?? {}; + + const data: MenuListItem[] = Object.values(CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE).map((expenseType) => ({ + value: expenseType, + text: translate(`workspace.sageIntacct.reimbursableExpenses.values.${expenseType}`), + keyForList: expenseType, + isSelected: config?.export.reimbursable === expenseType, + })); + + const selectDestination = useCallback( + (row: MenuListItem) => { + if (row.value !== config?.export.reimbursable) { + updateSageIntacctReimbursableExpensesExportDestination(policyID, row.value, config?.export.reimbursable); + if (row.value === CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL) { + // Employee default mapping value is not allowed when expense type is VENDOR_BILL, so we have to change mapping value to Tag + changeMappingsValueFromDefaultToTag(policyID, config?.mappings); + } + } + Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID)); + }, + [config?.export.reimbursable, config?.mappings, policyID], + ); + + return ( + selectDestination(selection as MenuListItem)} + initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} + policyID={policyID} + accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_NON_REIMBURSABLE_EXPENSES.getRoute(policyID))} + connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} + pendingAction={settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE], config?.pendingFields)} + errors={ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)} + errorRowStyles={[styles.ph5, styles.pv3]} + onClose={() => Policy.clearNetSuiteErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)} + /> + ); +} + +SageIntacctReimbursableExpensesDestinationPage.displayName = 'SageIntacctReimbursableExpensesDestinationPage'; + +export default withPolicyConnections(SageIntacctReimbursableExpensesDestinationPage); diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx index 360da1ac7a2d..d09b63915402 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx @@ -1,139 +1,119 @@ -import React, {useCallback, useMemo} from 'react'; -import {View} from 'react-native'; -import type {ValueOf} from 'type-fest'; +import React from 'react'; import ConnectionLayout from '@components/ConnectionLayout'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import SelectionList from '@components/SelectionList'; -import RadioListItem from '@components/SelectionList/RadioListItem'; -import type {ListItem} from '@components/SelectionList/types'; -import type {SelectorType} from '@components/SelectionScreen'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; import {areSettingsInErrorFields, settingsPendingAction} from '@libs/PolicyUtils'; -import Navigation from '@navigation/Navigation'; -import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import type {MenuItem, ToggleItem} from '@pages/workspace/accounting/intacct/types'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; -import {changeMappingsValueFromDefaultToTag, updateSageIntacctDefaultVendor, updateSageIntacctReimbursableExpensesExportDestination} from '@userActions/connections/SageIntacct'; +import {updateSageIntacctDefaultVendor} from '@userActions/connections/SageIntacct'; import * as Policy from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {SageIntacctDataElementWithValue} from '@src/types/onyx/Policy'; -type MenuListItem = ListItem & { - value: ValueOf; -}; +type MenuItemWithSubscribedSettings = Pick & {subscribedSettings?: string[]}; function getDefaultVendorName(defaultVendor?: string, vendors?: SageIntacctDataElementWithValue[]): string | undefined { return (vendors ?? []).find((vendor) => vendor.id === defaultVendor)?.value ?? defaultVendor; } -function SageIntacctReimbursableExpensesPage({policy}: WithPolicyProps) { +function SageIntacctReimbursableExpensesPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; const styles = useThemeStyles(); const {data: intacctData, config} = policy?.connections?.intacct ?? {}; const {reimbursable, reimbursableExpenseReportDefaultVendor} = policy?.connections?.intacct?.config?.export ?? {}; - const data: MenuListItem[] = Object.values(CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE).map((expenseType) => ({ - value: expenseType, - text: translate(`workspace.sageIntacct.reimbursableExpenses.values.${expenseType}`), - keyForList: expenseType, - isSelected: reimbursable === expenseType, - })); + const defaultVendorName = getDefaultVendorName(reimbursableExpenseReportDefaultVendor, intacctData?.vendors); - const selectReimbursableDestination = useCallback( - (row: MenuListItem) => { - if (row.value !== reimbursable) { - updateSageIntacctReimbursableExpensesExportDestination(policyID, row.value, reimbursable); - } - if (row.value === CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.VENDOR_BILL) { - // Employee default mapping value is not allowed when expense type is VENDOR_BILL, so we have to change mapping value to Tag - changeMappingsValueFromDefaultToTag(policyID, config?.mappings); - Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID)); - } + const menuItems: Array = [ + { + type: 'menuitem', + title: reimbursable ? translate(`workspace.sageIntacct.reimbursableExpenses.values.${reimbursable}`) : translate('workspace.sageIntacct.notConfigured'), + description: translate('workspace.accounting.exportAs'), + onPress: () => { + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_REIMBURSABLE_DESTINATION.getRoute(policyID)); + }, + subscribedSettings: [CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE], }, - [reimbursable, policyID, config?.mappings], - ); - - const defaultVendor = useMemo(() => { - const defaultVendorName = getDefaultVendorName(reimbursableExpenseReportDefaultVendor, intacctData?.vendors); - const defaultVendorSection = { - description: translate('workspace.sageIntacct.defaultVendor'), - action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)), + { + type: 'toggle', + title: translate('workspace.sageIntacct.defaultVendor'), + subtitle: translate('workspace.sageIntacct.defaultVendorDescription', true), + isActive: !!config?.export.reimbursableExpenseReportDefaultVendor, + switchAccessibilityLabel: translate('workspace.sageIntacct.defaultVendor'), + onToggle: (enabled) => { + const vendor = enabled ? policy?.connections?.intacct?.data?.vendors?.[0].id ?? '' : ''; + updateSageIntacctDefaultVendor(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR, vendor, config?.export.reimbursableExpenseReportDefaultVendor); + }, + onCloseError: () => Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR), + pendingAction: settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR], config?.pendingFields), + errors: ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR), + shouldHide: reimbursable !== CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT, + }, + { + type: 'menuitem', title: defaultVendorName && defaultVendorName !== '' ? defaultVendorName : translate('workspace.sageIntacct.notConfigured'), + description: translate('workspace.sageIntacct.defaultVendor'), + onPress: () => { + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_DEFAULT_VENDOR.getRoute(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)); + }, subscribedSettings: [CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR], - }; - - return ( - - - - ); - }, [config?.errorFields, config?.pendingFields, intacctData?.vendors, policyID, reimbursableExpenseReportDefaultVendor, translate]); + shouldHide: reimbursable !== CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT || !reimbursableExpenseReportDefaultVendor, + }, + ]; return ( Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_EXPORT.getRoute(policyID))} accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]} - featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} - displayName={SageIntacctReimbursableExpensesPage.displayName} policyID={policyID} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + contentContainerStyle={styles.pb2} + titleStyle={styles.ph5} connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT} - shouldUseScrollView={false} - shouldIncludeSafeAreaPaddingBottom > - Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)} - style={[styles.flexGrow1, styles.flexShrink1]} - contentContainerStyle={[styles.flexGrow1, styles.flexShrink1]} - > - selectReimbursableDestination(selection as MenuListItem)} - sections={[{data}]} - ListItem={RadioListItem} - showScrollIndicator - shouldShowTooltips={false} - containerStyle={[styles.flexReset, styles.flexGrow1, styles.flexShrink1, styles.pb0]} - /> - - {reimbursable === CONST.SAGE_INTACCT_REIMBURSABLE_EXPENSE_TYPE.EXPENSE_REPORT && ( - - { - const vendor = enabled ? policy?.connections?.intacct?.data?.vendors?.[0].id ?? '' : ''; - updateSageIntacctDefaultVendor(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR, vendor, reimbursableExpenseReportDefaultVendor); - }} - pendingAction={settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR], config?.pendingFields)} - errors={ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR)} - wrapperStyle={[styles.ph5, styles.pv3]} - onCloseError={() => Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE_VENDOR)} - /> - {!!reimbursableExpenseReportDefaultVendor && defaultVendor} - - )} + {menuItems + .filter((item) => !item.shouldHide) + .map((item) => { + switch (item.type) { + case 'toggle': + // eslint-disable-next-line no-case-declarations + const {type, shouldHide, ...rest} = item; + return ( + + ); + default: + return ( + + + + ); + } + })} ); } diff --git a/src/pages/workspace/accounting/intacct/types.ts b/src/pages/workspace/accounting/intacct/types.ts new file mode 100644 index 000000000000..79883a0c9104 --- /dev/null +++ b/src/pages/workspace/accounting/intacct/types.ts @@ -0,0 +1,30 @@ +import type {MenuItemProps} from '@components/MenuItem'; +import type {OfflineWithFeedbackProps} from '@components/OfflineWithFeedback'; +import type {ToggleSettingOptionRowProps} from '@pages/workspace/workflows/ToggleSettingsOptionRow'; + +type MenuItem = MenuItemProps & { + /** Type of the item */ + type: 'menuitem'; + + /** The type of action that's pending */ + pendingAction: OfflineWithFeedbackProps['pendingAction']; + + /** Whether the item should be hidden */ + shouldHide?: boolean; + + /** Any error message to show */ + errors: OfflineWithFeedbackProps['errors']; + + /** Callback to close the error messages */ + onCloseError: OfflineWithFeedbackProps['onClose']; +}; + +type ToggleItem = ToggleSettingOptionRowProps & { + /** Type of the item */ + type: 'toggle'; + + /** Whether the item should be hidden */ + shouldHide?: boolean; +}; + +export type {MenuItem, ToggleItem}; From 10dbc8e493eefe537070a0b25b0ca7c3b2559893 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Mon, 9 Sep 2024 11:19:14 +0200 Subject: [PATCH 006/104] cleanup, modify action --- src/libs/PolicyUtils.ts | 10 ++-- src/libs/actions/Policy/Tag.ts | 16 ++--- .../categories/CategoryApproverPage.tsx | 60 ------------------- src/pages/workspace/tags/TagApproverPage.tsx | 11 +--- src/pages/workspace/tags/TagSettingsPage.tsx | 2 +- src/types/onyx/Policy.ts | 22 ------- 6 files changed, 16 insertions(+), 105 deletions(-) delete mode 100644 src/pages/workspace/categories/CategoryApproverPage.tsx diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 37e204ef3567..688813d43632 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -978,13 +978,13 @@ function getWorkspaceAccountID(policyID: string) { return policy.workspaceAccountID ?? 0; } -function getTagExpenseRule(policyID: string, tagName: string) { +function getTagApproverRule(policyID: string, tagName: string) { const policy = getPolicy(policyID); - const expenseRules = policy?.rules?.expenseRules ?? []; - const expenseRule = expenseRules.find((rule) => rule.applyWhen.find(({condition, field, value}) => condition === 'matches' && field === 'tag' && value === tagName)); + const approvalRules = policy?.rules?.approvalRules ?? []; + const approverRule = approvalRules.find((rule) => rule.applyWhen.find(({condition, field, value}) => condition === 'matches' && field === 'tag' && value === tagName)); - return expenseRule; + return approverRule; } function getDomainNameForPolicy(policyID?: string): string { @@ -1105,7 +1105,7 @@ export { getWorkspaceAccountID, getAllTaxRatesNamesAndKeys as getAllTaxRates, getTagNamesFromTagsLists, - getTagExpenseRule, + getTagApproverRule, getDomainNameForPolicy, getWorkflowApprovalsUnavailable, }; diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index d02a42cccd98..8166d594aaa6 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -849,12 +849,12 @@ function setPolicyTagGLCode(policyID: string, tagName: string, tagListIndex: num function setPolicyTagApprover(policyID: string, tag: string, approver: string) { const policy = PolicyUtils.getPolicy(policyID); - const prevExpenseRules = policy?.rules?.approvalRules ?? []; - const expenseRuleToUpdate = PolicyUtils.getTagExpenseRule(policyID, tag); - const filteredExpenseRules = expenseRuleToUpdate ? prevExpenseRules.filter((rule) => rule.id === expenseRuleToUpdate.id) : prevExpenseRules; + const prevApprovalRules = policy?.rules?.approvalRules ?? []; + const approverRuleToUpdate = PolicyUtils.getTagApproverRule(policyID, tag); + const filteredApprovalRules = approverRuleToUpdate ? prevApprovalRules.filter((rule) => rule.id !== approverRuleToUpdate.id) : prevApprovalRules; - const updatedExpenseRule = expenseRuleToUpdate - ? {...expenseRuleToUpdate, approver} + const updatedApproverRule = approverRuleToUpdate + ? {...approverRuleToUpdate, approver} : { applyWhen: [ { @@ -874,7 +874,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { rules: { - expenseRules: [...filteredExpenseRules, updatedExpenseRule], + approvalRules: [...filteredApprovalRules, updatedApproverRule], }, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, pendingFields: {rules: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, @@ -887,7 +887,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { rules: { - expenseRules: [...filteredExpenseRules, updatedExpenseRule], + approvalRules: [...filteredApprovalRules, updatedApproverRule], }, pendingAction: null, pendingFields: {rules: null}, @@ -900,7 +900,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { rules: { - expenseRules: prevExpenseRules, + approvalRules: prevApprovalRules, }, pendingAction: null, pendingFields: {rules: null}, diff --git a/src/pages/workspace/categories/CategoryApproverPage.tsx b/src/pages/workspace/categories/CategoryApproverPage.tsx deleted file mode 100644 index b02abd7f8524..000000000000 --- a/src/pages/workspace/categories/CategoryApproverPage.tsx +++ /dev/null @@ -1,60 +0,0 @@ -// import type {StackScreenProps} from '@react-navigation/stack'; -// import React from 'react'; -// import {useOnyx} from 'react-native-onyx'; -// import HeaderWithBackButton from '@components/HeaderWithBackButton'; -// import ScreenWrapper from '@components/ScreenWrapper'; -// import WorkspaceMembersSelectionList from '@components/WorkspaceMembersSelectionList'; -// 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'; - -// type EditCategoryPageProps = StackScreenProps; - -// function CategoryApproverPage({ -// route: { -// params: {policyID, categoryName}, -// }, -// }: EditCategoryPageProps) { -// const styles = useThemeStyles(); -// const {translate} = useLocalize(); -// const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); - -// return ( -// -// -// Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))} -// /> -// { -// Category.setPolicyCategoryApprover(policyID, categoryName, email); -// Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.goBack(ROUTES.WORKSPACE_CATEGORY_SETTINGS.getRoute(policyID, categoryName))); -// }} -// /> -// -// -// ); -// } - -// CategoryApproverPage.displayName = 'CategoryApproverPage'; - -// export default CategoryApproverPage; diff --git a/src/pages/workspace/tags/TagApproverPage.tsx b/src/pages/workspace/tags/TagApproverPage.tsx index ce3fa822e761..874754b2cf4b 100644 --- a/src/pages/workspace/tags/TagApproverPage.tsx +++ b/src/pages/workspace/tags/TagApproverPage.tsx @@ -1,11 +1,9 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; -import {useOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import WorkspaceMembersSelectionList from '@components/WorkspaceMembersSelectionList'; import useLocalize from '@hooks/useLocalize'; -import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; @@ -13,23 +11,18 @@ import type {SettingsNavigatorParamList} from '@navigation/types'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import * as Tag from '@userActions/Policy/Tag'; import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; type TagApproverPageProps = StackScreenProps; function TagApproverPage({route}: TagApproverPageProps) { - const {policyID, orderWeight, tagName} = route.params; - - const policy = usePolicy(policyID); - const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`); + const {policyID, tagName} = route.params; const styles = useThemeStyles(); const {translate} = useLocalize(); - const tagApprover = PolicyUtils.getTagExpenseRule(policyID, tagName)?.approver; + const tagApprover = PolicyUtils.getTagApproverRule(policyID, tagName)?.approver; - console.log('POLICY ', policy); return ( ; }; -/** - * - */ -type ExpenseRule = { - /** Set of conditions under which the expense rule should be applied */ - applyWhen: ApplyRulesWhen[]; - - /** Policy tag approver */ - approver: string; - - /** An id of the rule */ - id: string; -}; - /** Data informing when a given rule should be applied */ type ApplyRulesWhen = { /** The condition for applying the rule to the workspace */ @@ -1585,16 +1571,8 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< rules?: { /** A set of rules related to the workpsace approvals */ approvalRules?: ApprovalRule[]; - - /** A set of rules related to the workpsace expenses */ - expenseRules?: ExpenseRule[]; }; - /** - * - */ - expenseRules?: ExpenseRule[]; - /** ReportID of the admins room for this workspace */ chatReportIDAdmins?: number; From e9dbc5ce87b30459839b82a65d68d703c64b3a16 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Mon, 9 Sep 2024 11:24:01 +0200 Subject: [PATCH 007/104] change translations --- src/languages/es.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index cc0fb7bee6d9..07ef49748ba9 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3159,8 +3159,8 @@ export default { importedFromAccountingSoftware: 'Etiquetas importadas desde', glCode: 'Código de Libro Mayor', updateGLCodeFailureMessage: 'Se produjo un error al actualizar el código de Libro Mayor. Por favor, inténtelo nuevamente.', - tagRules: 'Tag rules', - approverDescription: 'Approver', + tagRules: 'Reglas de etiquetas', + approverDescription: 'Aprobador', }, taxes: { subtitle: 'Añade nombres, tasas y establezca valores por defecto para los impuestos.', @@ -3899,7 +3899,6 @@ export default { pleaseEnterTaskName: 'Por favor, introduce un título', pleaseEnterTaskDestination: 'Por favor, selecciona dónde deseas compartir esta tarea.', }, - task: { task: 'Tarea', title: 'Título', From 78df9712c9fceb5d5e2e291ee4ce8b4cfba52c04 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Tue, 10 Sep 2024 10:18:47 +0200 Subject: [PATCH 008/104] add remove approver option --- src/libs/API/parameters/SetPolicyTagApproverParams.ts | 2 +- src/libs/actions/Policy/Tag.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libs/API/parameters/SetPolicyTagApproverParams.ts b/src/libs/API/parameters/SetPolicyTagApproverParams.ts index 0e9b286ba816..48112b323fad 100644 --- a/src/libs/API/parameters/SetPolicyTagApproverParams.ts +++ b/src/libs/API/parameters/SetPolicyTagApproverParams.ts @@ -1,7 +1,7 @@ type SetPolicyTagApproverParams = { policyID: string; tagName: string; - approver: string; + approver: string | null; }; export default SetPolicyTagApproverParams; diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 8166d594aaa6..3e7a1cc998d8 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -852,6 +852,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { const prevApprovalRules = policy?.rules?.approvalRules ?? []; const approverRuleToUpdate = PolicyUtils.getTagApproverRule(policyID, tag); const filteredApprovalRules = approverRuleToUpdate ? prevApprovalRules.filter((rule) => rule.id !== approverRuleToUpdate.id) : prevApprovalRules; + const toBeUnselected = approverRuleToUpdate?.approver === approver; const updatedApproverRule = approverRuleToUpdate ? {...approverRuleToUpdate, approver} @@ -867,6 +868,8 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { id: '-1', }; + const updatedApprovalRules = toBeUnselected ? filteredApprovalRules : [...filteredApprovalRules, updatedApproverRule]; + const onyxData: OnyxData = { optimisticData: [ { @@ -874,7 +877,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { rules: { - approvalRules: [...filteredApprovalRules, updatedApproverRule], + approvalRules: updatedApprovalRules, }, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, pendingFields: {rules: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, @@ -887,7 +890,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { rules: { - approvalRules: [...filteredApprovalRules, updatedApproverRule], + approvalRules: updatedApprovalRules, }, pendingAction: null, pendingFields: {rules: null}, @@ -912,7 +915,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { const parameters: SetPolicyTagApproverParams = { policyID, tagName: tag, - approver, + approver: toBeUnselected ? null : approver, }; API.write(WRITE_COMMANDS.SET_POLICY_TAG_APPROVER, parameters, onyxData); From 7f792c8a737096fa6e2f461bd631faefd7c1255c Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Tue, 10 Sep 2024 22:46:34 +0200 Subject: [PATCH 009/104] disable when workflows are disabled --- src/pages/workspace/tags/TagSettingsPage.tsx | 49 ++++++++++++-------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index 296e26e170a1..97e2456734a8 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -12,6 +12,7 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import Switch from '@components/Switch'; import Text from '@components/Text'; +import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import usePolicy from '@hooks/usePolicy'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -37,68 +38,65 @@ type TagSettingsPageOnyxProps = { type TagSettingsPageProps = TagSettingsPageOnyxProps & StackScreenProps; function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) { + const {orderWeight, policyID, tagName} = route.params; const styles = useThemeStyles(); const {translate} = useLocalize(); - const policyTag = useMemo(() => PolicyUtils.getTagList(policyTags, route.params.orderWeight), [policyTags, route.params.orderWeight]); - const policy = usePolicy(route.params.policyID); + const policyTag = useMemo(() => PolicyUtils.getTagList(policyTags, orderWeight), [policyTags, orderWeight]); + const policy = usePolicy(policyID); const [isDeleteTagModalOpen, setIsDeleteTagModalOpen] = React.useState(false); - const currentPolicyTag = policyTag.tags[route.params.tagName] ?? Object.values(policyTag.tags ?? {}).find((tag) => tag.previousTagName === route.params.tagName); + const currentPolicyTag = policyTag.tags[tagName] ?? Object.values(policyTag.tags ?? {}).find((tag) => tag.previousTagName === tagName); useEffect(() => { - if (currentPolicyTag?.name === route.params.tagName || !currentPolicyTag) { + if (currentPolicyTag?.name === tagName || !currentPolicyTag) { return; } navigation.setParams({tagName: currentPolicyTag?.name}); - }, [route.params.tagName, currentPolicyTag, navigation]); + }, [tagName, currentPolicyTag, navigation]); if (!currentPolicyTag) { return ; } const deleteTagAndHideModal = () => { - Tag.deletePolicyTags(route.params.policyID, [currentPolicyTag.name]); + Tag.deletePolicyTags(policyID, [currentPolicyTag.name]); setIsDeleteTagModalOpen(false); Navigation.goBack(); }; const updateWorkspaceTagEnabled = (value: boolean) => { - setWorkspaceTagEnabled(route.params.policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}}, policyTag.orderWeight); + setWorkspaceTagEnabled(policyID, {[currentPolicyTag.name]: {name: currentPolicyTag.name, enabled: value}}, policyTag.orderWeight); }; const navigateToEditTag = () => { - Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_EDIT.getRoute(policyID, orderWeight, currentPolicyTag.name)); }; const navigateToEditGlCode = () => { if (!PolicyUtils.isControlPolicy(policy)) { Navigation.navigate( - ROUTES.WORKSPACE_UPGRADE.getRoute( - route.params.policyID, - CONST.UPGRADE_FEATURE_INTRO_MAPPING.glCodes.alias, - ROUTES.WORKSPACE_TAG_GL_CODE.getRoute(policy?.id ?? '', route.params.orderWeight, route.params.tagName), - ), + ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.glCodes.alias, ROUTES.WORKSPACE_TAG_GL_CODE.getRoute(policy?.id ?? '', orderWeight, tagName)), ); return; } - Navigation.navigate(ROUTES.WORKSPACE_TAG_GL_CODE.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_GL_CODE.getRoute(policyID, orderWeight, currentPolicyTag.name)); }; const navigateToEditTagApprover = () => { - Navigation.navigate(ROUTES.WORKSPACE_TAG_APPROVER.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name)); + Navigation.navigate(ROUTES.WORKSPACE_TAG_APPROVER.getRoute(policyID, orderWeight, currentPolicyTag.name)); }; const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; const isMultiLevelTags = PolicyUtils.isMultiLevelTags(policyTags); - const tagApprover = PolicyUtils.getTagApproverRule(route.params.policyID, currentPolicyTag.name)?.approver; + const tagApprover = PolicyUtils.getTagApproverRule(policyID, currentPolicyTag.name)?.approver; const shouldShowDeleteMenuItem = !isThereAnyAccountingConnection && !isMultiLevelTags; return ( Tag.clearPolicyTagErrors(route.params.policyID, route.params.tagName, route.params.orderWeight)} + onClose={() => Tag.clearPolicyTagErrors(policyID, tagName, orderWeight)} > @@ -167,8 +165,21 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) description={translate(`workspace.tags.approverDescription`)} onPress={navigateToEditTagApprover} shouldShowRightIcon + disabled={!policy?.areWorkflowsEnabled} /> + {!policy?.areWorkflowsEnabled && ( + + {translate('workspace.rules.categoryRules.goTo')}{' '} + Navigation.navigate(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID))} + > + {translate('workspace.common.moreFeatures')} + {' '} + {translate('workspace.rules.categoryRules.andEnableWorkflows')} + + )} )} From 6163fe5edcd843349fabad96f27e0d7b71a0c93e Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Tue, 10 Sep 2024 22:49:46 +0200 Subject: [PATCH 010/104] add approver conditon --- src/pages/workspace/tags/TagSettingsPage.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index 97e2456734a8..6ff81af80edf 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -92,6 +92,8 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) const tagApprover = PolicyUtils.getTagApproverRule(policyID, currentPolicyTag.name)?.approver; const shouldShowDeleteMenuItem = !isThereAnyAccountingConnection && !isMultiLevelTags; + const workflowApprovalsUnavailable = PolicyUtils.getWorkflowApprovalsUnavailable(policy); + const approverDisabled = !policy?.areWorkflowsEnabled || workflowApprovalsUnavailable; return ( - {!policy?.areWorkflowsEnabled && ( + {approverDisabled && ( {translate('workspace.rules.categoryRules.goTo')}{' '} Date: Tue, 10 Sep 2024 22:55:53 +0200 Subject: [PATCH 011/104] add approver conditon to category settings --- src/pages/workspace/categories/CategorySettingsPage.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 0cac6b8a7bda..7c7ed08b911a 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -22,6 +22,7 @@ import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import {isControlPolicy} from '@libs/PolicyUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; @@ -133,6 +134,8 @@ function CategorySettingsPage({ }; const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; + const workflowApprovalsUnavailable = PolicyUtils.getWorkflowApprovalsUnavailable(policy); + const approverDisabled = !policy?.areWorkflowsEnabled || workflowApprovalsUnavailable; return ( - {!policy?.areWorkflowsEnabled && ( + {approverDisabled && ( {translate('workspace.rules.categoryRules.goTo')}{' '} Date: Wed, 11 Sep 2024 12:41:11 +0200 Subject: [PATCH 012/104] replace values with const --- src/CONST.ts | 8 +++++- src/libs/PolicyUtils.ts | 4 ++- src/libs/actions/Policy/Category.ts | 4 +-- src/libs/actions/Policy/Policy.ts | 26 +++++++++---------- src/libs/actions/Policy/Tag.ts | 4 +-- .../rules/ExpenseReportRulesSection.tsx | 12 ++++----- .../workspace/rules/RulesCustomNamePage.tsx | 2 +- 7 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index cf3facb0d1d8..95f2b97e297d 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2143,7 +2143,13 @@ const CONST = { // Often referred to as "collect" workspaces TEAM: 'team', }, - FIELD_LIST_TITLE_FIELD_ID: 'text_title', + RULE_CONDITIONS: { + MATCHES: 'matches', + }, + FIELDS: { + TAG: 'tag', + TITLE: 'text_title', + }, DEFAULT_REPORT_NAME_PATTERN: '{report:type} {report:startdate}', ROLE: { ADMIN: 'admin', diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 688813d43632..46914be44f38 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -982,7 +982,9 @@ function getTagApproverRule(policyID: string, tagName: string) { const policy = getPolicy(policyID); const approvalRules = policy?.rules?.approvalRules ?? []; - const approverRule = approvalRules.find((rule) => rule.applyWhen.find(({condition, field, value}) => condition === 'matches' && field === 'tag' && value === tagName)); + const approverRule = approvalRules.find((rule) => + rule.applyWhen.find(({condition, field, value}) => condition === CONST.POLICY.RULE_CONDITIONS.MATCHES && field === CONST.POLICY.FIELDS.TAG && value === tagName), + ); return approverRule; } diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 501b7cbbe1e5..1d331d841195 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1158,7 +1158,7 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro approver, applyWhen: [ { - condition: 'matches', + condition: CONST.POLICY.RULE_CONDITIONS.MATCHES, field: 'category', value: categoryName, }, @@ -1241,7 +1241,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str }, applyWhen: [ { - condition: 'matches', + condition: CONST.POLICY.RULE_CONDITIONS.MATCHES, field: 'category', value: categoryName, }, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 7bb66d02d79f..eca47005857e 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -3891,8 +3891,8 @@ function enablePolicyDefaultReportTitle(policyID: string, enabled: boolean) { return; } - const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID] ?? {}; - const titleFieldValues = enabled ? {} : {fieldList: {[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: {...previousReportTitleField, defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN}}}; + const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE] ?? {}; + const titleFieldValues = enabled ? {} : {fieldList: {[CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN}}}; const optimisticData: OnyxUpdate[] = [ { @@ -3928,7 +3928,7 @@ function enablePolicyDefaultReportTitle(policyID: string, enabled: boolean) { value: { shouldShowCustomReportTitleOption: !!policy?.shouldShowCustomReportTitleOption, fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: previousReportTitleField, + [CONST.POLICY.FIELDS.TITLE]: previousReportTitleField, }, pendingFields: { shouldShowCustomReportTitleOption: null, @@ -3960,11 +3960,11 @@ function enablePolicyDefaultReportTitle(policyID: string, enabled: boolean) { function setPolicyDefaultReportTitle(policyID: string, customName: string) { const policy = getPolicy(policyID); - if (customName === policy?.fieldList?.[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]?.defaultValue) { + if (customName === policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE]?.defaultValue) { return; } - const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID] ?? {}; + const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE] ?? {}; const optimisticData: OnyxUpdate[] = [ { @@ -3972,7 +3972,7 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: { + [CONST.POLICY.FIELDS.TITLE]: { defaultValue: customName, pendingFields: {defaultValue: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, @@ -3987,7 +3987,7 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: {pendingFields: {defaultValue: null}}, + [CONST.POLICY.FIELDS.TITLE]: {pendingFields: {defaultValue: null}}, }, errorFields: null, }, @@ -4000,7 +4000,7 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: {...previousReportTitleField, pendingFields: {defaultValue: null}}, + [CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, pendingFields: {defaultValue: null}}, }, errorFields: { fieldList: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), @@ -4029,11 +4029,11 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) { const policy = getPolicy(policyID); - if (!enforced === policy?.fieldList?.[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID].deletable) { + if (!enforced === policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE].deletable) { return; } - const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID] ?? {}; + const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE] ?? {}; const optimisticData: OnyxUpdate[] = [ { @@ -4041,7 +4041,7 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: {...previousReportTitleField, deletable: !enforced, pendingFields: {deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}, + [CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, deletable: !enforced, pendingFields: {deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}, }, }, }, @@ -4053,7 +4053,7 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: {pendingFields: {deletable: null}}, + [CONST.POLICY.FIELDS.TITLE]: {pendingFields: {deletable: null}}, }, errorFields: null, }, @@ -4066,7 +4066,7 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID]: {...previousReportTitleField, pendingFields: {deletable: null}}, + [CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, pendingFields: {deletable: null}}, }, errorFields: { fieldList: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 3e7a1cc998d8..2853f1b96273 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -859,8 +859,8 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { : { applyWhen: [ { - condition: 'matches', - field: 'tag', + condition: CONST.POLICY.RULE_CONDITIONS.MATCHES, + field: CONST.POLICY.FIELDS.TAG, value: tag, }, ], diff --git a/src/pages/workspace/rules/ExpenseReportRulesSection.tsx b/src/pages/workspace/rules/ExpenseReportRulesSection.tsx index 71fdc0a29eeb..e18f155b77a1 100644 --- a/src/pages/workspace/rules/ExpenseReportRulesSection.tsx +++ b/src/pages/workspace/rules/ExpenseReportRulesSection.tsx @@ -54,15 +54,15 @@ function ExpenseReportRulesSection({policyID}: ExpenseReportRulesSectionProps) { subMenuItems: [ Navigation.navigate(ROUTES.RULES_CUSTOM_NAME.getRoute(policyID))} @@ -70,8 +70,8 @@ function ExpenseReportRulesSection({policyID}: ExpenseReportRulesSectionProps) { , PolicyActions.setPolicyPreventMemberCreatedTitle(policyID, isEnabled)} />, ], diff --git a/src/pages/workspace/rules/RulesCustomNamePage.tsx b/src/pages/workspace/rules/RulesCustomNamePage.tsx index afd8f455fee5..42b9cfe96488 100644 --- a/src/pages/workspace/rules/RulesCustomNamePage.tsx +++ b/src/pages/workspace/rules/RulesCustomNamePage.tsx @@ -39,7 +39,7 @@ function RulesCustomNamePage({route}: RulesCustomNamePageProps) { translate('workspace.rules.expenseReportRules.customNameTotalExample'), ] as const satisfies string[]; - const customNameDefaultValue = policy?.fieldList?.[CONST.POLICY.FIELD_LIST_TITLE_FIELD_ID].defaultValue; + const customNameDefaultValue = policy?.fieldList?.[CONST.POLICY.FIELDS_TITLE].defaultValue; const validateCustomName = ({customName}: FormOnyxValues) => { const errors: FormInputErrors = {}; From d7cb9646c5008b4836ecb5fce341d50eb64b7124 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 11 Sep 2024 13:17:42 +0200 Subject: [PATCH 013/104] change conditon for find category approver --- src/CONST.ts | 1 + src/libs/CategoryUtils.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index 95f2b97e297d..2e91ec48901f 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2148,6 +2148,7 @@ const CONST = { }, FIELDS: { TAG: 'tag', + CATEGORY: 'category', TITLE: 'text_title', }, DEFAULT_REPORT_NAME_PATTERN: '{report:type} {report:startdate}', diff --git a/src/libs/CategoryUtils.ts b/src/libs/CategoryUtils.ts index 7f971f37d3fa..6ca4d0ae39bf 100644 --- a/src/libs/CategoryUtils.ts +++ b/src/libs/CategoryUtils.ts @@ -45,7 +45,10 @@ function formatRequireReceiptsOverText(translate: LocaleContextProps['translate' } function getCategoryApprover(approvalRules: ApprovalRule[], categoryName: string) { - return approvalRules?.find((rule) => rule.applyWhen.some((when) => when.value === categoryName))?.approver; + const approverRule = approvalRules?.find((rule) => + rule.applyWhen.find(({condition, field, value}) => condition === CONST.POLICY.RULE_CONDITIONS.MATCHES && field === CONST.POLICY.FIELDS.CATEGORY && value === categoryName), + ); + return approverRule?.approver; } function getCategoryDefaultTaxRate(expenseRules: ExpenseRule[], categoryName: string, defaultTaxRate?: string) { From 5c0b778b0e755fe1b2010580dc3bce94aa9ba092 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 11 Sep 2024 13:24:54 +0200 Subject: [PATCH 014/104] ts fix --- src/pages/workspace/rules/RulesCustomNamePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/rules/RulesCustomNamePage.tsx b/src/pages/workspace/rules/RulesCustomNamePage.tsx index 42b9cfe96488..738ac2e0cf3e 100644 --- a/src/pages/workspace/rules/RulesCustomNamePage.tsx +++ b/src/pages/workspace/rules/RulesCustomNamePage.tsx @@ -39,7 +39,7 @@ function RulesCustomNamePage({route}: RulesCustomNamePageProps) { translate('workspace.rules.expenseReportRules.customNameTotalExample'), ] as const satisfies string[]; - const customNameDefaultValue = policy?.fieldList?.[CONST.POLICY.FIELDS_TITLE].defaultValue; + const customNameDefaultValue = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE].defaultValue; const validateCustomName = ({customName}: FormOnyxValues) => { const errors: FormInputErrors = {}; From 9c7cd5eaec0ace14152f347c950dfbc9cfe4b9ee Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 12 Sep 2024 14:04:07 +0500 Subject: [PATCH 015/104] perf: avoid bundling wdyr in JS bundle --- config/webpack/webpack.common.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/webpack/webpack.common.ts b/config/webpack/webpack.common.ts index 33fd9131eca0..2b2da879b880 100644 --- a/config/webpack/webpack.common.ts +++ b/config/webpack/webpack.common.ts @@ -128,6 +128,13 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment): resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, }), + ...(file === '.env.production' || file === '.env.staging' + ? [ + new IgnorePlugin({ + resourceRegExp: /@welldone-software\/why-did-you-render/, + }), + ] + : []), ...(platform === 'web' ? [new CustomVersionFilePlugin()] : []), new DefinePlugin({ ...(platform === 'desktop' ? {} : {process: {env: {}}}), From 012557cb67415bcb498a5d3a72de7ef111e7e0b0 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 12 Sep 2024 14:05:35 +0500 Subject: [PATCH 016/104] perf: use specific imports from lodash --- src/components/MapView/PendingMapView.tsx | 4 ++-- src/hooks/useHandleExceedMaxCommentLength.ts | 4 ++-- src/libs/CardUtils.ts | 4 ++-- src/libs/Middleware/HandleUnusedOptimisticID.ts | 4 ++-- src/libs/ReceiptUtils.ts | 4 ++-- src/libs/ReportActionsUtils.ts | 11 ++++++----- src/libs/StringUtils.ts | 4 ++-- .../RemoveEmptyReportActionsDrafts.ts | 4 ++-- .../PersonalDetails/StateSelectionPage.tsx | 6 +++--- .../settings/Wallet/WalletPage/WalletPage.tsx | 17 +++++++++-------- 10 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/components/MapView/PendingMapView.tsx b/src/components/MapView/PendingMapView.tsx index cc9829517154..dc84af0b395e 100644 --- a/src/components/MapView/PendingMapView.tsx +++ b/src/components/MapView/PendingMapView.tsx @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React from 'react'; import {View} from 'react-native'; import BlockingView from '@components/BlockingViews/BlockingView'; @@ -10,7 +10,7 @@ import variables from '@styles/variables'; import type {PendingMapViewProps} from './MapViewTypes'; function PendingMapView({title = '', subtitle = '', style, isSmallerIcon = false}: PendingMapViewProps) { - const hasTextContent = !_.isEmpty(title) || !_.isEmpty(subtitle); + const hasTextContent = !isEmpty(title) || !isEmpty(subtitle); const styles = useThemeStyles(); const theme = useTheme(); const iconSize = isSmallerIcon ? variables.iconSizeSuperLarge : variables.iconSizeUltraLarge; diff --git a/src/hooks/useHandleExceedMaxCommentLength.ts b/src/hooks/useHandleExceedMaxCommentLength.ts index 69c1d7597164..8afa88da38b5 100644 --- a/src/hooks/useHandleExceedMaxCommentLength.ts +++ b/src/hooks/useHandleExceedMaxCommentLength.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import debounce from 'lodash/debounce'; import {useCallback, useMemo, useState} from 'react'; import * as ReportUtils from '@libs/ReportUtils'; import type {ParsingDetails} from '@libs/ReportUtils'; @@ -20,7 +20,7 @@ const useHandleExceedMaxCommentLength = () => { [hasExceededMaxCommentLength], ); - const validateCommentMaxLength = useMemo(() => _.debounce(handleValueChange, 1500, {leading: true}), [handleValueChange]); + const validateCommentMaxLength = useMemo(() => debounce(handleValueChange, 1500, {leading: true}), [handleValueChange]); return {hasExceededMaxCommentLength, validateCommentMaxLength}; }; diff --git a/src/libs/CardUtils.ts b/src/libs/CardUtils.ts index 2398bc1e729a..e85b9bb4a044 100644 --- a/src/libs/CardUtils.ts +++ b/src/libs/CardUtils.ts @@ -1,4 +1,4 @@ -import lodash from 'lodash'; +import groupBy from 'lodash/groupBy'; import Onyx from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; @@ -106,7 +106,7 @@ function getDomainCards(cardList: OnyxEntry): Record { // Check for domainName to filter out personal credit cards. const activeCards = Object.values(cardList ?? {}).filter((card) => !!card?.domainName && CONST.EXPENSIFY_CARD.ACTIVE_STATES.some((element) => element === card.state)); - return lodash.groupBy(activeCards, (card) => card.domainName); + return groupBy(activeCards, (card) => card.domainName); } /** diff --git a/src/libs/Middleware/HandleUnusedOptimisticID.ts b/src/libs/Middleware/HandleUnusedOptimisticID.ts index db726855d075..ad010880bdf7 100644 --- a/src/libs/Middleware/HandleUnusedOptimisticID.ts +++ b/src/libs/Middleware/HandleUnusedOptimisticID.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import clone from 'lodash/clone'; import deepReplaceKeysAndValues from '@libs/deepReplaceKeysAndValues'; import type {Middleware} from '@libs/Request'; import * as PersistedRequests from '@userActions/PersistedRequests'; @@ -38,7 +38,7 @@ const handleUnusedOptimisticID: Middleware = (requestResponse, request, isFromSe PersistedRequests.getAll() .slice(offset) .forEach((persistedRequest, index) => { - const persistedRequestClone = _.clone(persistedRequest); + const persistedRequestClone = clone(persistedRequest); persistedRequestClone.data = deepReplaceKeysAndValues(persistedRequest.data, oldReportID as string, preexistingReportID); PersistedRequests.update(index + offset, persistedRequestClone); }); diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts index 49c275278c46..ed7def2ed1ec 100644 --- a/src/libs/ReceiptUtils.ts +++ b/src/libs/ReceiptUtils.ts @@ -1,5 +1,5 @@ import {Str} from 'expensify-common'; -import _ from 'lodash'; +import findLast from 'lodash/findLast'; import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; @@ -30,7 +30,7 @@ function getThumbnailAndImageURIs(transaction: OnyxEntry, receiptPa return {isThumbnail: true, isLocalFile: true}; } // If there're errors, we need to display them in preview. We can store many files in errors, but we just need to get the last one - const errors = _.findLast(transaction?.errors) as ReceiptError | undefined; + const errors = findLast(transaction?.errors) as ReceiptError | undefined; // URI to image, i.e. blob:new.expensify.com/9ef3a018-4067-47c6-b29f-5f1bd35f213d or expensify.com/receipts/w_e616108497ef940b7210ec6beb5a462d01a878f4.jpg const path = errors?.source ?? transaction?.receipt?.source ?? receiptPath ?? ''; // filename of uploaded image or last part of remote URI diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 5a7f6602795c..1f44456d0d96 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1,5 +1,6 @@ import {fastMerge, Str} from 'expensify-common'; -import _ from 'lodash'; +import isEmpty from 'lodash/isEmpty'; +import clone from 'lodash/clone'; import lodashFindLast from 'lodash/findLast'; import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; @@ -409,7 +410,7 @@ function getCombinedReportActions( const isSentMoneyReport = reportActions.some((action) => isSentMoneyReportAction(action)); // We don't want to combine report actions of transaction thread in iou report of send money request because we display the transaction report of send money request as a normal thread - if (_.isEmpty(transactionThreadReportID) || isSentMoneyReport) { + if (isEmpty(transactionThreadReportID) || isSentMoneyReport) { return reportActions; } @@ -709,7 +710,7 @@ function replaceBaseURLInPolicyChangeLogAction(reportAction: ReportAction): Repo return reportAction; } - const updatedReportAction = _.clone(reportAction); + const updatedReportAction = clone(reportAction); if (!updatedReportAction.message) { return updatedReportAction; @@ -724,7 +725,7 @@ function replaceBaseURLInPolicyChangeLogAction(reportAction: ReportAction): Repo function getLastVisibleAction(reportID: string, actionsToMerge: Record | null> = {}): OnyxEntry { let reportActions: Array = []; - if (!_.isEmpty(actionsToMerge)) { + if (!isEmpty(actionsToMerge)) { reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge ?? {}, true)) as Array< ReportAction | null | undefined >; @@ -1376,7 +1377,7 @@ function getActionableMentionWhisperMessage(reportAction: OnyxEntry { const personalDetail = personalDetails.find((personal) => personal.accountID === accountID); const displayName = PersonalDetailsUtils.getEffectiveDisplayName(personalDetail); - const handleText = _.isEmpty(displayName) ? Localize.translateLocal('common.hidden') : displayName; + const handleText = isEmpty(displayName) ? Localize.translateLocal('common.hidden') : displayName; return `@${handleText}`; }); const preMentionsText = 'Heads up, '; diff --git a/src/libs/StringUtils.ts b/src/libs/StringUtils.ts index 5cc80a9a9005..10730150489c 100644 --- a/src/libs/StringUtils.ts +++ b/src/libs/StringUtils.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import deburr from 'lodash/deburr'; import CONST from '@src/CONST'; /** @@ -7,7 +7,7 @@ import CONST from '@src/CONST'; * @returns The sanitized string */ function sanitizeString(str: string): string { - return _.deburr(str).toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''); + return deburr(str).toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''); } /** diff --git a/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts b/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts index ce2f8de77634..5dc1ada1947d 100644 --- a/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts +++ b/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import type {OnyxInputValue} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; @@ -38,7 +38,7 @@ export default function (): Promise { hasUnmigratedDraft = true; Log.info(`[Migrate Onyx] Migrating draft for report action ${reportActionID}`); - if (_.isEmpty(reportActionDraft)) { + if (isEmpty(reportActionDraft)) { Log.info(`[Migrate Onyx] Removing draft for report action ${reportActionID}`); return; } diff --git a/src/pages/settings/Profile/PersonalDetails/StateSelectionPage.tsx b/src/pages/settings/Profile/PersonalDetails/StateSelectionPage.tsx index c04e631bd13f..2a42f1922bf8 100644 --- a/src/pages/settings/Profile/PersonalDetails/StateSelectionPage.tsx +++ b/src/pages/settings/Profile/PersonalDetails/StateSelectionPage.tsx @@ -1,6 +1,6 @@ import {useNavigation, useRoute} from '@react-navigation/native'; import {CONST as COMMON_CONST} from 'expensify-common'; -import _ from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {useCallback, useMemo, useState} from 'react'; import {View} from 'react-native'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -60,14 +60,14 @@ function StateSelectionPage() { // Determine navigation action based on "backTo" presence and route stack length. if (navigation.getState()?.routes.length === 1) { // If this is the only page in the navigation stack (examples include direct navigation to this page via URL or page reload). - if (_.isEmpty(backTo)) { + if (isEmpty(backTo)) { // No "backTo": default back navigation. Navigation.goBack(); } else { // "backTo" provided: navigate back to "backTo" with state parameter. Navigation.goBack(appendParam(backTo, 'state', option.value)); } - } else if (!_.isEmpty(backTo)) { + } else if (!isEmpty(backTo)) { // Most common case: Navigation stack has multiple routes and "backTo" is defined: navigate to "backTo" with state parameter. Navigation.navigate(appendParam(backTo, 'state', option.value)); } else { diff --git a/src/pages/settings/Wallet/WalletPage/WalletPage.tsx b/src/pages/settings/Wallet/WalletPage/WalletPage.tsx index 49c27d4e3c67..386c61303338 100644 --- a/src/pages/settings/Wallet/WalletPage/WalletPage.tsx +++ b/src/pages/settings/Wallet/WalletPage/WalletPage.tsx @@ -1,4 +1,5 @@ -import _ from 'lodash'; +import isEmpty from 'lodash/isEmpty'; +import debounce from 'lodash/debounce'; import type {ForwardedRef, RefObject} from 'react'; import React, {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react'; import type {GestureResponderEvent} from 'react-native'; @@ -94,10 +95,10 @@ function WalletPage({shouldListenForResize = false}: WalletPageProps) { }); const [showConfirmDeleteModal, setShowConfirmDeleteModal] = useState(false); - const hasBankAccount = !_.isEmpty(bankAccountList) || !_.isEmpty(fundList); - const hasWallet = !_.isEmpty(userWallet); + const hasBankAccount = !isEmpty(bankAccountList) || !isEmpty(fundList); + const hasWallet = !isEmpty(userWallet); const hasActivatedWallet = ([CONST.WALLET.TIER_NAME.GOLD, CONST.WALLET.TIER_NAME.PLATINUM] as string[]).includes(userWallet?.tierName ?? ''); - const hasAssignedCard = !_.isEmpty(cardList); + const hasAssignedCard = !isEmpty(cardList); const shouldShowEmptyState = !hasBankAccount && !hasWallet && !hasAssignedCard; const isPendingOnfidoResult = userWallet?.isPendingOnfidoResult ?? false; @@ -111,7 +112,7 @@ function WalletPage({shouldListenForResize = false}: WalletPageProps) { } }, [isLoadingPaymentMethods, network.isOffline, shouldShowLoadingSpinner]); - const debounceSetShouldShowLoadingSpinner = _.debounce(updateShouldShowLoadingSpinner, CONST.TIMING.SHOW_LOADING_SPINNER_DEBOUNCE_TIME); + const debounceSetShouldShowLoadingSpinner = debounce(updateShouldShowLoadingSpinner, CONST.TIMING.SHOW_LOADING_SPINNER_DEBOUNCE_TIME); /** * Set position of the payment menu @@ -308,7 +309,7 @@ function WalletPage({shouldListenForResize = false}: WalletPageProps) { return; } if (shouldShowAddPaymentMenu) { - _.debounce(setMenuPosition, CONST.TIMING.RESIZE_DEBOUNCE_TIME)(); + debounce(setMenuPosition, CONST.TIMING.RESIZE_DEBOUNCE_TIME)(); return; } setMenuPosition(); @@ -329,9 +330,9 @@ function WalletPage({shouldListenForResize = false}: WalletPageProps) { // We should reset selected payment method state values and close corresponding modals if the selected payment method is deleted let shouldResetPaymentMethodData = false; - if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT && _.isEmpty(bankAccountList?.[paymentMethod.methodID])) { + if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT &&isEmpty(bankAccountList?.[paymentMethod.methodID])) { shouldResetPaymentMethodData = true; - } else if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD && _.isEmpty(fundList?.[paymentMethod.methodID])) { + } else if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD && isEmpty(fundList?.[paymentMethod.methodID])) { shouldResetPaymentMethodData = true; } if (shouldResetPaymentMethodData) { From 120073c3a91c9f320368928a8f9b1cea305b5cd0 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 12 Sep 2024 14:13:53 +0500 Subject: [PATCH 017/104] perf: use lodash-es to allow tree-shaking unused functions from lodash --- config/webpack/webpack.common.ts | 1 + package-lock.json | 18 ++++++++++++++++-- package.json | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/config/webpack/webpack.common.ts b/config/webpack/webpack.common.ts index 2b2da879b880..737ab055760e 100644 --- a/config/webpack/webpack.common.ts +++ b/config/webpack/webpack.common.ts @@ -222,6 +222,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment): }, resolve: { alias: { + lodash: 'lodash-es', // eslint-disable-next-line @typescript-eslint/naming-convention 'react-native-config': 'react-web-config', // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/package-lock.json b/package-lock.json index 9ebd32061ab9..9deb55fefe6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,7 @@ "idb-keyval": "^6.2.1", "jest-expo": "51.0.3", "jest-when": "^3.5.2", - "lodash": "4.17.21", + "lodash-es": "4.17.21", "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", @@ -183,7 +183,7 @@ "@types/jest": "^29.5.2", "@types/jest-when": "^3.5.2", "@types/js-yaml": "^4.0.5", - "@types/lodash": "^4.14.195", + "@types/lodash-es": "4.17.12", "@types/mapbox-gl": "^2.7.13", "@types/node": "^20.11.5", "@types/pusher-js": "^5.1.0", @@ -15510,6 +15510,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mapbox-gl": { "version": "2.7.13", "license": "MIT", @@ -30469,6 +30478,11 @@ "version": "4.17.21", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "dev": true, diff --git a/package.json b/package.json index 5b50764cda22..34124107e436 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "idb-keyval": "^6.2.1", "jest-expo": "51.0.3", "jest-when": "^3.5.2", - "lodash": "4.17.21", + "lodash-es": "4.17.21", "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", @@ -240,7 +240,7 @@ "@types/jest": "^29.5.2", "@types/jest-when": "^3.5.2", "@types/js-yaml": "^4.0.5", - "@types/lodash": "^4.14.195", + "@types/lodash-es": "4.17.12", "@types/mapbox-gl": "^2.7.13", "@types/node": "^20.11.5", "@types/pusher-js": "^5.1.0", From 956d6fd0dcad2d1731bbe404c590e52917f8ba0d Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 12 Sep 2024 14:17:00 +0500 Subject: [PATCH 018/104] perf: set target to preset-env to reduce the JS bundle size --- babel.config.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/babel.config.js b/babel.config.js index dcf12ba4d91e..776ea1d84178 100644 --- a/babel.config.js +++ b/babel.config.js @@ -8,7 +8,12 @@ const ReactCompilerConfig = { enableTreatRefLikeIdentifiersAsRefs: true, }, }; -const defaultPresets = ['@babel/preset-react', '@babel/preset-env', '@babel/preset-flow', '@babel/preset-typescript']; +/** + * Setting targets to node 20 to reduce JS bundle size + * It is also recommended by babel: + * https://babeljs.io/docs/options#no-targets + */ +const defaultPresets = ['@babel/preset-react', ['@babel/preset-env', {targets: {node: 20}}], '@babel/preset-flow', '@babel/preset-typescript']; const defaultPlugins = [ ['babel-plugin-react-compiler', ReactCompilerConfig], // must run first! // Adding the commonjs: true option to react-native-web plugin can cause styling conflicts From 53ac8123a87a99fef5a3de7c6e08483da0a976e1 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 12 Sep 2024 14:33:51 +0500 Subject: [PATCH 019/104] perf: use specific imports from lodash --- src/libs/ReportActionsUtils.ts | 2 +- src/pages/settings/Wallet/WalletPage/WalletPage.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 1f44456d0d96..6e5dd0ff5cb2 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1,7 +1,7 @@ import {fastMerge, Str} from 'expensify-common'; -import isEmpty from 'lodash/isEmpty'; import clone from 'lodash/clone'; import lodashFindLast from 'lodash/findLast'; +import isEmpty from 'lodash/isEmpty'; import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; diff --git a/src/pages/settings/Wallet/WalletPage/WalletPage.tsx b/src/pages/settings/Wallet/WalletPage/WalletPage.tsx index 386c61303338..0eae84bb7c37 100644 --- a/src/pages/settings/Wallet/WalletPage/WalletPage.tsx +++ b/src/pages/settings/Wallet/WalletPage/WalletPage.tsx @@ -1,5 +1,5 @@ -import isEmpty from 'lodash/isEmpty'; import debounce from 'lodash/debounce'; +import isEmpty from 'lodash/isEmpty'; import type {ForwardedRef, RefObject} from 'react'; import React, {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react'; import type {GestureResponderEvent} from 'react-native'; @@ -330,7 +330,7 @@ function WalletPage({shouldListenForResize = false}: WalletPageProps) { // We should reset selected payment method state values and close corresponding modals if the selected payment method is deleted let shouldResetPaymentMethodData = false; - if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT &&isEmpty(bankAccountList?.[paymentMethod.methodID])) { + if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT && isEmpty(bankAccountList?.[paymentMethod.methodID])) { shouldResetPaymentMethodData = true; } else if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD && isEmpty(fundList?.[paymentMethod.methodID])) { shouldResetPaymentMethodData = true; From 804c601bb8f39e282ecf17bf27dd5a5d3212e537 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 12 Sep 2024 11:47:37 +0200 Subject: [PATCH 020/104] use getCategoryApproverRule in the actions --- src/libs/CategoryUtils.ts | 6 +++--- src/libs/actions/Policy/Category.ts | 4 +++- src/pages/workspace/categories/CategoryApproverPage.tsx | 2 +- src/pages/workspace/categories/CategorySettingsPage.tsx | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libs/CategoryUtils.ts b/src/libs/CategoryUtils.ts index 6ca4d0ae39bf..7b2f71dbd101 100644 --- a/src/libs/CategoryUtils.ts +++ b/src/libs/CategoryUtils.ts @@ -44,11 +44,11 @@ function formatRequireReceiptsOverText(translate: LocaleContextProps['translate' ); } -function getCategoryApprover(approvalRules: ApprovalRule[], categoryName: string) { +function getCategoryApproverRule(approvalRules: ApprovalRule[], categoryName: string) { const approverRule = approvalRules?.find((rule) => rule.applyWhen.find(({condition, field, value}) => condition === CONST.POLICY.RULE_CONDITIONS.MATCHES && field === CONST.POLICY.FIELDS.CATEGORY && value === categoryName), ); - return approverRule?.approver; + return approverRule; } function getCategoryDefaultTaxRate(expenseRules: ExpenseRule[], categoryName: string, defaultTaxRate?: string) { @@ -62,4 +62,4 @@ function getCategoryDefaultTaxRate(expenseRules: ExpenseRule[], categoryName: st return categoryDefaultTaxRate; } -export {formatDefaultTaxRateText, formatRequireReceiptsOverText, getCategoryApprover, getCategoryDefaultTaxRate}; +export {formatDefaultTaxRateText, formatRequireReceiptsOverText, getCategoryApproverRule, getCategoryDefaultTaxRate}; diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 1d331d841195..ec9457e36071 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -18,6 +18,7 @@ import type { } from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ApiUtils from '@libs/ApiUtils'; +import * as CategoryUtils from '@libs/CategoryUtils'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import fileDownload from '@libs/fileDownload'; @@ -1150,7 +1151,8 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; const approvalRules = policy?.rules?.approvalRules ?? []; let updatedApprovalRules: ApprovalRule[] = lodashCloneDeep(approvalRules); - const existingCategoryApproverRule = updatedApprovalRules.find((rule) => rule.applyWhen.some((when) => when.value === categoryName)); + const existingCategoryApproverRule = CategoryUtils.getCategoryApproverRule(updatedApprovalRules, categoryName); + let newApprover = approver; if (!existingCategoryApproverRule) { diff --git a/src/pages/workspace/categories/CategoryApproverPage.tsx b/src/pages/workspace/categories/CategoryApproverPage.tsx index 390a577d9cf8..649681db6155 100644 --- a/src/pages/workspace/categories/CategoryApproverPage.tsx +++ b/src/pages/workspace/categories/CategoryApproverPage.tsx @@ -26,7 +26,7 @@ function CategoryApproverPage({ const {translate} = useLocalize(); const policy = usePolicy(policyID); - const selectedApprover = CategoryUtils.getCategoryApprover(policy?.rules?.approvalRules ?? [], categoryName) ?? ''; + const selectedApprover = CategoryUtils.getCategoryApproverRule(policy?.rules?.approvalRules ?? [], categoryName)?.approver ?? ''; return ( { - const categoryApprover = CategoryUtils.getCategoryApprover(policy?.rules?.approvalRules ?? [], categoryName); + const categoryApprover = CategoryUtils.getCategoryApproverRule(policy?.rules?.approvalRules ?? [], categoryName)?.approver; return categoryApprover ?? ''; }, [categoryName, policy?.rules?.approvalRules]); From c43913b251cf7fd98212184235c08cdbbae1dfa8 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 12 Sep 2024 12:14:57 +0200 Subject: [PATCH 021/104] change offline pattern for tags --- src/libs/actions/Policy/Category.ts | 36 +++++++++++-------- src/libs/actions/Policy/Tag.ts | 21 +++++++---- .../categories/CategorySettingsPage.tsx | 4 +-- src/pages/workspace/tags/TagSettingsPage.tsx | 2 +- src/types/onyx/Policy.ts | 19 ++++++++-- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index ec9457e36071..1b571e4d6bdb 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1182,8 +1182,10 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro value: { rules: { approvalRules: updatedApprovalRules, - pendingFields: { - approvalRules: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + pendingRulesUpdates: { + [categoryName]: { + approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, }, @@ -1194,9 +1196,9 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - rules: { - pendingFields: { - approvalRules: null, + pendingRulesUpdates: { + [categoryName]: { + approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, }, @@ -1209,8 +1211,10 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro value: { rules: { approvalRules, - pendingFields: { - approvalRules: null, + }, + pendingRulesUpdates: { + [categoryName]: { + approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, }, @@ -1262,8 +1266,10 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str value: { rules: { expenseRules: updatedExpenseRules, - pendingFields: { - expenseRules: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + pendingRulesUpdates: { + [categoryName]: { + expenseRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, }, @@ -1274,9 +1280,9 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - rules: { - pendingFields: { - expenseRules: null, + pendingRulesUpdates: { + [categoryName]: { + expenseRule: null, }, }, }, @@ -1289,8 +1295,10 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str value: { rules: { expenseRules, - pendingFields: { - expenseRules: null, + }, + pendingRulesUpdates: { + [categoryName]: { + expenseRule: null, }, }, }, diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 2853f1b96273..d126cf9e58e0 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -879,8 +879,11 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { rules: { approvalRules: updatedApprovalRules, }, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - pendingFields: {rules: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + pendingRulesUpdates: { + [tag]: { + approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, + }, }, }, ], @@ -892,8 +895,11 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { rules: { approvalRules: updatedApprovalRules, }, - pendingAction: null, - pendingFields: {rules: null}, + pendingRulesUpdates: { + [tag]: { + approvalRule: null, + }, + }, }, }, ], @@ -905,8 +911,11 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { rules: { approvalRules: prevApprovalRules, }, - pendingAction: null, - pendingFields: {rules: null}, + pendingRulesUpdates: { + [tag]: { + approvalRule: null, + }, + }, }, }, ], diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 180941329a86..cd8a462f7bb6 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -260,7 +260,7 @@ function CategorySettingsPage({ /> )} - + )} {policy?.tax?.trackingEnabled && ( - + {translate('workspace.tags.tagRules')} - + ; + }; /** ReportID of the admins room for this workspace */ chatReportIDAdmins?: number; @@ -1683,6 +1686,18 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** Workspace account ID configured for Expensify Card */ workspaceAccountID?: number; + + /** Information about rules being updated */ + pendingRulesUpdates: Record< + CategoryOrTagName, + { + /** Indicates whether the approval rule is updated for the given category or tag */ + approvalRule: OnyxCommon.PendingAction; + + /** Indicates whether the expense rule is updated for the given category or tag */ + expenseRule: OnyxCommon.PendingAction; + } + >; } & Partial, 'addWorkspaceRoom' | keyof ACHAccount | keyof Attributes >; From 477079229b38bab88ba19090d11128c803d5c873 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 12 Sep 2024 12:23:31 +0200 Subject: [PATCH 022/104] ts fix --- src/types/onyx/Policy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 41a8b0cb8b0c..006a4a42cf04 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1688,7 +1688,7 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< workspaceAccountID?: number; /** Information about rules being updated */ - pendingRulesUpdates: Record< + pendingRulesUpdates?: Record< CategoryOrTagName, { /** Indicates whether the approval rule is updated for the given category or tag */ From e331603cf3cf8e14f8ad115c80302d814ba869a1 Mon Sep 17 00:00:00 2001 From: daledah Date: Thu, 12 Sep 2024 17:49:45 +0700 Subject: [PATCH 023/104] fix: app crash on signout --- src/pages/home/ReportScreen.tsx | 232 ++++++++++++++------------------ 1 file changed, 99 insertions(+), 133 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 4491a12e6bbd..f0e0a9e55282 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -71,7 +71,7 @@ const defaultReportMetadata = { /** Get the currently viewed report ID as number */ function getReportID(route: ReportScreenNavigationProps['route']): string { // The report ID is used in an onyx key. If it's an empty string, onyx will return - // a collection instead of an individual report. + // a collection instead of an individual report?. return String(route.params?.reportID || 0); } @@ -82,7 +82,7 @@ function getReportID(route: ReportScreenNavigationProps['route']): string { * * @param report */ -function isEmpty(report: OnyxTypes.Report): boolean { +function isEmpty(report: OnyxEntry): boolean { if (isEmptyObject(report)) { return true; } @@ -167,91 +167,51 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro * put this into onyx selector as it will be the same. */ const report = useMemo( - (): OnyxTypes.Report => ({ - lastReadTime: reportOnyx?.lastReadTime, - reportID: reportOnyx?.reportID ?? '', - policyID: reportOnyx?.policyID, - lastVisibleActionCreated: reportOnyx?.lastVisibleActionCreated, - statusNum: reportOnyx?.statusNum, - stateNum: reportOnyx?.stateNum, - writeCapability: reportOnyx?.writeCapability, - type: reportOnyx?.type, - errorFields: reportOnyx?.errorFields, - isPolicyExpenseChat: reportOnyx?.isPolicyExpenseChat, - parentReportID: reportOnyx?.parentReportID, - parentReportActionID: reportOnyx?.parentReportActionID, - chatType: reportOnyx?.chatType, - pendingFields: reportOnyx?.pendingFields, - isDeletedParentAction: reportOnyx?.isDeletedParentAction, - reportName: reportOnyx?.reportName, - description: reportOnyx?.description, - managerID: reportOnyx?.managerID, - total: reportOnyx?.total, - nonReimbursableTotal: reportOnyx?.nonReimbursableTotal, - fieldList: reportOnyx?.fieldList, - ownerAccountID: reportOnyx?.ownerAccountID, - currency: reportOnyx?.currency, - unheldTotal: reportOnyx?.unheldTotal, - participants: reportOnyx?.participants, - isWaitingOnBankAccount: reportOnyx?.isWaitingOnBankAccount, - iouReportID: reportOnyx?.iouReportID, - isOwnPolicyExpenseChat: reportOnyx?.isOwnPolicyExpenseChat, - isPinned: reportOnyx?.isPinned, - chatReportID: reportOnyx?.chatReportID, - visibility: reportOnyx?.visibility, - oldPolicyName: reportOnyx?.oldPolicyName, - policyName: reportOnyx?.policyName, - // eslint-disable-next-line @typescript-eslint/naming-convention - private_isArchived: reportOnyx?.private_isArchived, - isOptimisticReport: reportOnyx?.isOptimisticReport, - lastMentionedTime: reportOnyx?.lastMentionedTime, - avatarUrl: reportOnyx?.avatarUrl, - permissions, - invoiceReceiver: reportOnyx?.invoiceReceiver, - policyAvatar: reportOnyx?.policyAvatar, - }), - [ - reportOnyx?.lastReadTime, - reportOnyx?.reportID, - reportOnyx?.policyID, - reportOnyx?.lastVisibleActionCreated, - reportOnyx?.statusNum, - reportOnyx?.stateNum, - reportOnyx?.writeCapability, - reportOnyx?.type, - reportOnyx?.errorFields, - reportOnyx?.isPolicyExpenseChat, - reportOnyx?.parentReportID, - reportOnyx?.parentReportActionID, - reportOnyx?.chatType, - reportOnyx?.pendingFields, - reportOnyx?.isDeletedParentAction, - reportOnyx?.reportName, - reportOnyx?.description, - reportOnyx?.managerID, - reportOnyx?.total, - reportOnyx?.nonReimbursableTotal, - reportOnyx?.fieldList, - reportOnyx?.ownerAccountID, - reportOnyx?.currency, - reportOnyx?.unheldTotal, - reportOnyx?.participants, - reportOnyx?.isWaitingOnBankAccount, - reportOnyx?.iouReportID, - reportOnyx?.isOwnPolicyExpenseChat, - reportOnyx?.isPinned, - reportOnyx?.chatReportID, - reportOnyx?.visibility, - reportOnyx?.oldPolicyName, - reportOnyx?.policyName, - reportOnyx?.private_isArchived, - reportOnyx?.isOptimisticReport, - reportOnyx?.lastMentionedTime, - reportOnyx?.avatarUrl, - permissions, - reportOnyx?.invoiceReceiver, - reportOnyx?.policyAvatar, - ], + (): OnyxEntry => + reportOnyx && { + lastReadTime: reportOnyx?.lastReadTime, + reportID: reportOnyx?.reportID ?? '', + policyID: reportOnyx?.policyID, + lastVisibleActionCreated: reportOnyx?.lastVisibleActionCreated, + statusNum: reportOnyx?.statusNum, + stateNum: reportOnyx?.stateNum, + writeCapability: reportOnyx?.writeCapability, + type: reportOnyx?.type, + errorFields: reportOnyx?.errorFields, + isPolicyExpenseChat: reportOnyx?.isPolicyExpenseChat, + parentReportID: reportOnyx?.parentReportID, + parentReportActionID: reportOnyx?.parentReportActionID, + chatType: reportOnyx?.chatType, + pendingFields: reportOnyx?.pendingFields, + isDeletedParentAction: reportOnyx?.isDeletedParentAction, + reportName: reportOnyx?.reportName, + description: reportOnyx?.description, + managerID: reportOnyx?.managerID, + total: reportOnyx?.total, + nonReimbursableTotal: reportOnyx?.nonReimbursableTotal, + fieldList: reportOnyx?.fieldList, + ownerAccountID: reportOnyx?.ownerAccountID, + currency: reportOnyx?.currency, + unheldTotal: reportOnyx?.unheldTotal, + participants: reportOnyx?.participants, + isWaitingOnBankAccount: reportOnyx?.isWaitingOnBankAccount, + iouReportID: reportOnyx?.iouReportID, + isOwnPolicyExpenseChat: reportOnyx?.isOwnPolicyExpenseChat, + isPinned: reportOnyx?.isPinned, + chatReportID: reportOnyx?.chatReportID, + visibility: reportOnyx?.visibility, + oldPolicyName: reportOnyx?.oldPolicyName, + policyName: reportOnyx?.policyName, + // eslint-disable-next-line @typescript-eslint/naming-convention + private_isArchived: reportOnyx?.private_isArchived, + isOptimisticReport: reportOnyx?.isOptimisticReport, + lastMentionedTime: reportOnyx?.lastMentionedTime, + avatarUrl: reportOnyx?.avatarUrl, + permissions, + invoiceReceiver: reportOnyx?.invoiceReceiver, + policyAvatar: reportOnyx?.policyAvatar, + }, + [reportOnyx, permissions], ); const prevReport = usePrevious(report); @@ -259,7 +219,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const [isLinkingToMessage, setIsLinkingToMessage] = useState(!!reportActionIDFromRoute); const [currentUserAccountID = -1] = useOnyx(ONYXKEYS.SESSION, {selector: (value) => value?.accountID}); - const {reportActions, linkedAction, sortedAllReportActions} = usePaginatedReportActions(report.reportID, reportActionIDFromRoute); + const {reportActions, linkedAction, sortedAllReportActions} = usePaginatedReportActions(report?.reportID, reportActionIDFromRoute); const [isBannerVisible, setIsBannerVisible] = useState(true); const [scrollPosition, setScrollPosition] = useState({}); @@ -276,7 +236,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const {reportPendingAction, reportErrors} = ReportUtils.getReportOfflinePendingActionAndErrors(report); const screenWrapperStyle: ViewStyle[] = [styles.appContent, styles.flex1, {marginTop: viewportOffsetTop}]; const isEmptyChat = useMemo(() => ReportUtils.isEmptyReport(report), [report]); - const isOptimisticDelete = report.statusNum === CONST.REPORT.STATUS_NUM.CLOSED; + const isOptimisticDelete = report?.statusNum === CONST.REPORT.STATUS_NUM.CLOSED; const indexOfLinkedMessage = useMemo( (): number => reportActions.findIndex((obj) => String(obj.reportActionID) === String(reportActionIDFromRoute)), [reportActions, reportActionIDFromRoute], @@ -295,17 +255,17 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const hasHelpfulErrors = Object.keys(report?.errorFields ?? {}).some((key) => key !== 'notFound'); const shouldHideReport = !hasHelpfulErrors && !ReportUtils.canAccessReport(report, policies, betas); - const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(report.reportID, reportActions ?? [], isOffline); + const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(report?.reportID ?? '', reportActions ?? [], isOffline); const [transactionThreadReportActions = {}] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID}`); const combinedReportActions = ReportActionsUtils.getCombinedReportActions(reportActions, transactionThreadReportID ?? null, Object.values(transactionThreadReportActions)); const lastReportAction = [...combinedReportActions, parentReportAction].find((action) => ReportUtils.canEditReportAction(action) && !ReportActionsUtils.isMoneyRequestAction(action)); const isSingleTransactionView = ReportUtils.isMoneyRequest(report) || ReportUtils.isTrackExpenseReport(report); - const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`]; + const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? '-1'}`]; const isTopMostReportId = currentReportID === reportIDFromRoute; const didSubscribeToReportLeavingEvents = useRef(false); useEffect(() => { - if (!report.reportID || shouldHideReport) { + if (!report?.reportID || shouldHideReport) { wasReportAccessibleRef.current = false; return; } @@ -320,7 +280,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro Navigation.goBack(undefined, false, true); }, [isInNarrowPaneModal]); - let headerView = ( + let headerView = report && ( ); - if (isSingleTransactionView) { + if (isSingleTransactionView && report) { headerView = ( { - if (!transactionThreadReportID || !route?.params?.reportActionID || !ReportUtils.isOneTransactionThread(linkedAction?.childReportID ?? '-1', report.reportID, linkedAction)) { + if ( + !transactionThreadReportID || + !route?.params?.reportActionID || + !report?.reportID || + !ReportUtils.isOneTransactionThread(linkedAction?.childReportID ?? '-1', report?.reportID, linkedAction) + ) { return; } Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(route?.params?.reportID)); - }, [transactionThreadReportID, route?.params?.reportActionID, route?.params?.reportID, linkedAction, report.reportID]); + }, [transactionThreadReportID, route?.params?.reportActionID, route?.params?.reportID, linkedAction, report?.reportID]); - if (ReportUtils.isMoneyRequestReport(report) || ReportUtils.isInvoiceReport(report)) { + if (report && (ReportUtils.isMoneyRequestReport(report) || ReportUtils.isInvoiceReport(report))) { headerView = ( { // This is necessary so that when we are retrieving the next report data from Onyx the ReportActionsView will remount completely - const isTransitioning = report && report.reportID !== reportIDFromRoute; - return reportIDFromRoute !== '' && !!report.reportID && !isTransitioning; + const isTransitioning = report && report?.reportID !== reportIDFromRoute; + return reportIDFromRoute !== '' && !!report?.reportID && !isTransitioning; }, [report, reportIDFromRoute]); const isInitialPageReady = isOffline @@ -416,13 +381,13 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return false; } - // If we just finished loading the app, we still need to try fetching the report. Wait until that's done before + // If we just finished loading the app, we still need to try fetching the report?. Wait until that's done before // showing the Not Found page if (finishedLoadingApp) { return false; } - if (!wasReportAccessibleRef.current && !firstRenderRef.current && !report.reportID && !isOptimisticDelete && !reportMetadata?.isLoadingInitialReportActions && !userLeavingStatus) { + if (!wasReportAccessibleRef.current && !firstRenderRef.current && !report?.reportID && !isOptimisticDelete && !reportMetadata?.isLoadingInitialReportActions && !userLeavingStatus) { return true; } @@ -434,7 +399,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro shouldShowNotFoundLinkedAction, isLoadingApp, finishedLoadingApp, - report.reportID, + report?.reportID, isOptimisticDelete, reportMetadata?.isLoadingInitialReportActions, userLeavingStatus, @@ -447,11 +412,11 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro }, [reportIDFromRoute, reportActionIDFromRoute]); useEffect(() => { - if (!report.reportID || !isFocused) { + if (!report?.reportID || !isFocused) { return; } - Report.updateLastVisitTime(report.reportID); - }, [report.reportID, isFocused]); + Report.updateLastVisitTime(report?.reportID); + }, [report?.reportID, isFocused]); const fetchReportIfNeeded = useCallback(() => { // Report ID will be empty when the reports collection is empty. @@ -462,7 +427,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro /** * Since OpenReport is a write, the response from OpenReport will get dropped while the app is - * still loading. This usually happens when signing in and deeplinking to a report. Instead, + * still loading. This usually happens when signing in and deeplinking to a report?. Instead, * we'll fetch the report after the app finishes loading. * * This needs to be a strict equality check since isLoadingApp is initially undefined until the @@ -472,7 +437,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } - if (!shouldFetchReport(report) && (isInitialPageReady || isLinkedMessagePageReady)) { + if (report && !shouldFetchReport(report) && (isInitialPageReady || isLinkedMessagePageReady)) { return; } @@ -490,12 +455,12 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro // Clear notifications for the current report when it's opened and re-focused const clearNotifications = useCallback(() => { // Check if this is the top-most ReportScreen since the Navigator preserves multiple at a time - if (!isTopMostReportId) { + if (!isTopMostReportId || !report?.reportID) { return; } - clearReportNotifications(report.reportID); - }, [report.reportID, isTopMostReportId]); + clearReportNotifications(report?.reportID); + }, [report?.reportID, isTopMostReportId]); useEffect(clearNotifications, [clearNotifications]); useAppFocusEvent(clearNotifications); @@ -513,7 +478,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } - Report.unsubscribeFromLeavingRoomReportChannel(report.reportID); + Report.unsubscribeFromLeavingRoomReportChannel(report?.reportID ?? ''); }; // I'm disabling the warning, as it expects to use exhaustive deps, even though we want this useEffect to run only on the first render. @@ -534,7 +499,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } - // This function is triggered when a user clicks on a link to navigate to a report. + // This function is triggered when a user clicks on a link to navigate to a report?. // For each link click, we retrieve the report data again, even though it may already be cached. // There should be only one openReport execution per page start or navigating fetchReportIfNeeded(); @@ -549,16 +514,17 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro prevIsFocused || !ReportUtils.isChatThread(report) || ReportUtils.getReportNotificationPreference(report) !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN || - isSingleTransactionView + isSingleTransactionView || + !report?.reportID ) { return; } - Report.openReport(report.reportID); + Report.openReport(report?.reportID); // We don't want to run this useEffect every time `report` is changed // Excluding shouldUseNarrowLayout from the dependency list to prevent re-triggering on screen resize events. // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, [prevIsFocused, report.participants, isFocused, isSingleTransactionView]); + }, [prevIsFocused, report?.participants, isFocused, isSingleTransactionView, report?.reportID]); useEffect(() => { // We don't want this effect to run on the first render. @@ -567,14 +533,14 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } - const onyxReportID = report.reportID; - const prevOnyxReportID = prevReport.reportID; + const onyxReportID = report?.reportID; + const prevOnyxReportID = prevReport?.reportID; const wasReportRemoved = !!prevOnyxReportID && prevOnyxReportID === reportIDFromRoute && !onyxReportID; const isRemovalExpectedForReportType = isEmpty(report) && (ReportUtils.isMoneyRequest(prevReport) || ReportUtils.isMoneyRequestReport(prevReport) || ReportUtils.isPolicyExpenseChat(prevReport) || ReportUtils.isGroupChat(prevReport)); - const didReportClose = wasReportRemoved && prevReport.statusNum === CONST.REPORT.STATUS_NUM.OPEN && report.statusNum === CONST.REPORT.STATUS_NUM.CLOSED; - const isTopLevelPolicyRoomWithNoStatus = !report.statusNum && !prevReport.parentReportID && prevReport.chatType === CONST.REPORT.CHAT_TYPE.POLICY_ROOM; + const didReportClose = wasReportRemoved && prevReport.statusNum === CONST.REPORT.STATUS_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.CLOSED; + const isTopLevelPolicyRoomWithNoStatus = !report?.statusNum && !prevReport?.parentReportID && prevReport?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_ROOM; const isClosedTopLevelPolicyRoom = wasReportRemoved && prevReport.statusNum === CONST.REPORT.STATUS_NUM.OPEN && isTopLevelPolicyRoomWithNoStatus; // Navigate to the Concierge chat if the room was removed from another device (e.g. user leaving a room or removed from a room) if ( @@ -595,7 +561,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro Navigation.setShouldPopAllStateOnUP(true); Navigation.goBack(undefined, false, true); } - if (prevReport.parentReportID) { + if (prevReport?.parentReportID) { // Prevent navigation to the IOU/Expense Report if it is pending deletion. if (ReportUtils.isMoneyRequestReportPendingDeletion(prevReport.parentReportID)) { return; @@ -612,7 +578,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro // the ReportScreen never actually unmounts and the reportID in the route also doesn't change. // Therefore, we need to compare if the existing reportID is the same as the one in the route // before deciding that we shouldn't call OpenReport. - if (onyxReportID === prevReport.reportID && (!onyxReportID || onyxReportID === reportIDFromRoute)) { + if (onyxReportID === prevReport?.reportID && (!onyxReportID || onyxReportID === reportIDFromRoute)) { return; } @@ -624,12 +590,12 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro report, // errors, fetchReportIfNeeded, - prevReport.reportID, + prevReport?.reportID, prevUserLeavingStatus, userLeavingStatus, - prevReport.statusNum, - prevReport.parentReportID, - prevReport.chatType, + prevReport?.statusNum, + prevReport?.parentReportID, + prevReport?.chatType, prevReport, reportIDFromRoute, isFocused, @@ -642,14 +608,14 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } // Ensures the optimistic report is created successfully - if (reportIDFromRoute !== report.reportID) { + if (reportIDFromRoute !== report?.reportID) { return; } // Ensures subscription event succeeds when the report/workspace room is created optimistically. // Check if the optimistic `OpenReport` or `AddWorkspaceRoom` has succeeded by confirming // any `pendingFields.createChat` or `pendingFields.addWorkspaceRoom` fields are set to null. // Existing reports created will have empty fields for `pendingFields`. - const didCreateReportSuccessfully = !report.pendingFields || (!report.pendingFields.addWorkspaceRoom && !report.pendingFields.createChat); + const didCreateReportSuccessfully = !report?.pendingFields || (!report?.pendingFields.addWorkspaceRoom && !report?.pendingFields.createChat); let interactionTask: ReturnType | null = null; if (!didSubscribeToReportLeavingEvents.current && didCreateReportSuccessfully) { interactionTask = InteractionManager.runAfterInteractions(() => { @@ -713,11 +679,11 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro }, [isLinkedActionInaccessibleWhisper]); useEffect(() => { - if (!!report.lastReadTime || !ReportUtils.isTaskReport(report)) { + if (!!report?.lastReadTime || !ReportUtils.isTaskReport(report) || !report?.reportID) { return; } // After creating the task report then navigating to task detail we don't have any report actions and the last read time is empty so We need to update the initial last read time when opening the task report detail. - Report.readNewestAction(report.reportID); + Report.readNewestAction(report?.reportID); }, [report]); const firstReportAction = reportActions[0]; @@ -738,7 +704,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro navigation={navigation} style={screenWrapperStyle} shouldEnableKeyboardAvoidingView={isTopMostReportId || isInNarrowPaneModal} - testID={`report-screen-${report.reportID}`} + testID={`report-screen-${report?.reportID}`} > {headerView} - {ReportUtils.isTaskReport(report) && shouldUseNarrowLayout && ReportUtils.isOpenTaskReport(report, parentReportAction) && ( + {report && ReportUtils.isTaskReport(report) && shouldUseNarrowLayout && ReportUtils.isOpenTaskReport(report, parentReportAction) && ( @@ -781,7 +747,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro style={[styles.flex1, styles.justifyContentEnd, styles.overflowHidden]} testID="report-actions-view-wrapper" > - {!shouldShowSkeleton && ( + {!shouldShowSkeleton && report && ( - {!!firstReportAction && ( + {!!firstReportAction && report && ( Date: Thu, 12 Sep 2024 17:53:31 +0700 Subject: [PATCH 024/104] fix: remove unnecessary change --- src/pages/home/ReportScreen.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index f0e0a9e55282..2f36262eda78 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -71,7 +71,7 @@ const defaultReportMetadata = { /** Get the currently viewed report ID as number */ function getReportID(route: ReportScreenNavigationProps['route']): string { // The report ID is used in an onyx key. If it's an empty string, onyx will return - // a collection instead of an individual report?. + // a collection instead of an individual report. return String(route.params?.reportID || 0); } From 1b2b38df66a6d53291fc778c2927296072d47cf5 Mon Sep 17 00:00:00 2001 From: hurali97 Date: Thu, 12 Sep 2024 16:03:39 +0500 Subject: [PATCH 025/104] chore: move dev related libraries to devDeps --- package-lock.json | 454 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 28 +-- 2 files changed, 438 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9deb55fefe6c..6f5dbbc4c2bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,6 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@dotlottie/react-player": "^1.6.3", "@expensify/react-native-live-markdown": "0.1.120", "@expo/metro-runtime": "~3.1.1", @@ -20,14 +18,10 @@ "@formatjs/intl-locale": "^4.0.0", "@formatjs/intl-numberformat": "^8.10.3", "@formatjs/intl-pluralrules": "^5.2.14", - "@fullstory/babel-plugin-annotate-react": "github:fullstorydev/fullstory-babel-plugin-annotate-react#ryanwang/react-native-web-demo", - "@fullstory/babel-plugin-react-native": "^1.2.1", "@fullstory/browser": "^2.0.3", "@fullstory/react-native": "^1.4.2", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", - "@kie/act-js": "^2.6.2", - "@kie/mock-github": "2.0.1", "@onfido/react-native-sdk": "10.6.0", "@react-native-camera-roll/camera-roll": "7.4.0", "@react-native-clipboard/clipboard": "^1.13.2", @@ -45,9 +39,7 @@ "@react-ng/bounds-observer": "^0.2.1", "@rnmapbox/maps": "10.1.30", "@shopify/flash-list": "1.7.1", - "@types/mime-db": "^1.43.5", "@ua/react-native-airship": "19.2.1", - "@vue/preload-webpack-plugin": "^2.0.0", "awesome-phonenumber": "^5.4.0", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", @@ -65,8 +57,6 @@ "focus-trap-react": "^10.2.3", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", - "jest-expo": "51.0.3", - "jest-when": "^3.5.2", "lodash-es": "4.17.21", "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", @@ -76,7 +66,6 @@ "react": "18.3.1", "react-beautiful-dnd": "^13.1.1", "react-collapse": "^5.1.0", - "react-compiler-runtime": "file:./lib/react-compiler-runtime", "react-content-loader": "^7.0.0", "react-dom": "18.3.1", "react-error-boundary": "^4.0.11", @@ -132,9 +121,7 @@ "react-plaid-link": "3.3.2", "react-web-config": "^1.0.0", "react-webcam": "^7.1.1", - "react-window": "^1.8.9", - "semver": "^7.5.2", - "xlsx": "file:vendor/xlsx-0.20.3.tgz" + "react-window": "^1.8.9" }, "devDependencies": { "@actions/core": "1.10.0", @@ -143,6 +130,8 @@ "@babel/parser": "^7.22.16", "@babel/plugin-proposal-class-properties": "^7.12.1", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@babel/preset-env": "^7.20.0", "@babel/preset-flow": "^7.12.13", "@babel/preset-react": "^7.10.4", @@ -153,7 +142,11 @@ "@callstack/reassure-compare": "^1.0.0-rc.4", "@dword-design/eslint-plugin-import-alias": "^5.0.0", "@electron/notarize": "^2.1.0", + "@fullstory/babel-plugin-annotate-react": "github:fullstorydev/fullstory-babel-plugin-annotate-react#ryanwang/react-native-web-demo", + "@fullstory/babel-plugin-react-native": "^1.2.1", "@jest/globals": "^29.5.0", + "@kie/act-js": "^2.6.2", + "@kie/mock-github": "2.0.1", "@ngneat/falso": "^7.1.1", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", @@ -185,6 +178,7 @@ "@types/js-yaml": "^4.0.5", "@types/lodash-es": "4.17.12", "@types/mapbox-gl": "^2.7.13", + "@types/mime-db": "^1.43.5", "@types/node": "^20.11.5", "@types/pusher-js": "^5.1.0", "@types/react": "^18.2.6", @@ -201,6 +195,7 @@ "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", "@vercel/ncc": "0.38.1", + "@vue/preload-webpack-plugin": "^2.0.0", "@welldone-software/why-did-you-render": "7.0.1", "ajv-cli": "^5.0.0", "babel-jest": "29.4.1", @@ -237,7 +232,9 @@ "jest-circus": "29.4.1", "jest-cli": "29.4.1", "jest-environment-jsdom": "^29.4.1", + "jest-expo": "51.0.3", "jest-transformer-svg": "^2.0.1", + "jest-when": "^3.5.2", "link": "^2.1.1", "memfs": "^4.6.0", "onchange": "^7.1.0", @@ -248,10 +245,12 @@ "prettier": "^2.8.8", "pusher-js-mock": "^0.3.3", "react-compiler-healthcheck": "^0.0.0-experimental-ab3118d-20240725", + "react-compiler-runtime": "file:./lib/react-compiler-runtime", "react-is": "^18.3.1", "react-native-clean-project": "^4.0.0-alpha4.0", "react-test-renderer": "18.3.1", "reassure": "^1.0.0-rc.4", + "semver": "^7.5.2", "setimmediate": "^1.0.5", "shellcheck": "^1.1.0", "source-map": "^0.7.4", @@ -269,6 +268,7 @@ "webpack-cli": "^5.0.4", "webpack-dev-server": "^5.0.4", "webpack-merge": "^5.8.0", + "xlsx": "file:vendor/xlsx-0.20.3.tgz", "yaml": "^2.2.1" }, "engines": { @@ -278,6 +278,7 @@ }, "lib/react-compiler-runtime": { "version": "0.0.1", + "dev": true, "license": "MIT", "dependencies": { "react": "18.3.1" @@ -1345,6 +1346,7 @@ }, "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.18.6", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", @@ -1359,6 +1361,7 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.11", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -1385,6 +1388,7 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -2778,6 +2782,7 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", + "dev": true, "license": "MIT" }, "node_modules/@blakeembrey/deque": { @@ -2971,7 +2976,7 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -2982,7 +2987,7 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -5568,6 +5573,7 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -5582,6 +5588,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5589,6 +5596,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -5600,6 +5608,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -5610,6 +5619,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -5623,6 +5633,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -5633,6 +5644,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5640,6 +5652,7 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5647,6 +5660,7 @@ }, "node_modules/@jest/console": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -5662,6 +5676,7 @@ }, "node_modules/@jest/console/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5675,6 +5690,7 @@ }, "node_modules/@jest/console/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -5689,6 +5705,7 @@ }, "node_modules/@jest/console/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -5699,10 +5716,12 @@ }, "node_modules/@jest/console/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/console/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5710,6 +5729,7 @@ }, "node_modules/@jest/console/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -5720,6 +5740,7 @@ }, "node_modules/@jest/core": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -5765,6 +5786,7 @@ }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5778,6 +5800,7 @@ }, "node_modules/@jest/core/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -5792,6 +5815,7 @@ }, "node_modules/@jest/core/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -5802,10 +5826,12 @@ }, "node_modules/@jest/core/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/core/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5813,6 +5839,7 @@ }, "node_modules/@jest/core/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -5846,6 +5873,7 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "expect": "^29.7.0", @@ -5857,6 +5885,7 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -5882,6 +5911,7 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -5895,6 +5925,7 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -5936,6 +5967,7 @@ }, "node_modules/@jest/reporters/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5949,6 +5981,7 @@ }, "node_modules/@jest/reporters/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -5963,6 +5996,7 @@ }, "node_modules/@jest/reporters/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -5973,10 +6007,12 @@ }, "node_modules/@jest/reporters/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5984,6 +6020,7 @@ }, "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { "version": "6.0.2", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", @@ -5998,6 +6035,7 @@ }, "node_modules/@jest/reporters/node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -6011,6 +6049,7 @@ }, "node_modules/@jest/reporters/node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6024,6 +6063,7 @@ }, "node_modules/@jest/reporters/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6044,6 +6084,7 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -6056,6 +6097,7 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -6069,6 +6111,7 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -6082,6 +6125,7 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -6106,6 +6150,7 @@ }, "node_modules/@jest/transform/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6119,6 +6164,7 @@ }, "node_modules/@jest/transform/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -6133,6 +6179,7 @@ }, "node_modules/@jest/transform/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6143,10 +6190,12 @@ }, "node_modules/@jest/transform/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6154,6 +6203,7 @@ }, "node_modules/@jest/transform/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6164,6 +6214,7 @@ }, "node_modules/@jest/transform/node_modules/write-file-atomic": { "version": "4.0.2", + "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -6318,6 +6369,7 @@ }, "node_modules/@kie/act-js": { "version": "2.6.2", + "dev": true, "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { @@ -6336,6 +6388,7 @@ }, "node_modules/@kie/mock-github": { "version": "2.0.1", + "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { "@octokit/openapi-types-ghec": "^18.0.0", @@ -6350,6 +6403,7 @@ }, "node_modules/@kie/mock-github/node_modules/fs-extra": { "version": "10.1.0", + "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -6362,6 +6416,7 @@ }, "node_modules/@kie/mock-github/node_modules/totalist": { "version": "3.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -6369,6 +6424,7 @@ }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", + "dev": true, "license": "MIT", "dependencies": { "debug": "^4.1.1" @@ -6376,6 +6432,7 @@ }, "node_modules/@kwsites/promise-deferred": { "version": "1.1.1", + "dev": true, "license": "MIT" }, "node_modules/@leichtgewicht/ip-codec": { @@ -6785,6 +6842,7 @@ }, "node_modules/@octokit/openapi-types-ghec": { "version": "18.1.1", + "dev": true, "license": "MIT" }, "node_modules/@octokit/plugin-paginate-rest": { @@ -15021,22 +15079,22 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@turf/along": { @@ -15180,6 +15238,7 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -15191,6 +15250,7 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -15198,6 +15258,7 @@ }, "node_modules/@types/babel__template": { "version": "7.4.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -15206,6 +15267,7 @@ }, "node_modules/@types/babel__traverse": { "version": "7.18.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.3.0" @@ -15309,6 +15371,7 @@ }, "node_modules/@types/eslint": { "version": "8.4.6", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "*", @@ -15317,6 +15380,7 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.4", + "dev": true, "license": "MIT", "dependencies": { "@types/eslint": "*", @@ -15325,6 +15389,7 @@ }, "node_modules/@types/estree": { "version": "0.0.51", + "dev": true, "license": "MIT" }, "node_modules/@types/express": { @@ -15372,6 +15437,7 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.9", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -15399,6 +15465,7 @@ }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", + "dev": true, "license": "MIT" }, "node_modules/@types/http-cache-semantics": { @@ -15461,6 +15528,7 @@ }, "node_modules/@types/jsdom": { "version": "20.0.1", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -15470,6 +15538,7 @@ }, "node_modules/@types/jsdom/node_modules/entities": { "version": "4.5.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -15480,6 +15549,7 @@ }, "node_modules/@types/jsdom/node_modules/parse5": { "version": "7.1.2", + "dev": true, "license": "MIT", "dependencies": { "entities": "^4.4.0" @@ -15490,6 +15560,7 @@ }, "node_modules/@types/json-schema": { "version": "7.0.12", + "dev": true, "license": "MIT" }, "node_modules/@types/json5": { @@ -15539,7 +15610,8 @@ "node_modules/@types/mime-db": { "version": "1.43.5", "resolved": "https://registry.npmjs.org/@types/mime-db/-/mime-db-1.43.5.tgz", - "integrity": "sha512-/bfTiIUTNPUBnwnYvUxXAre5MhD88jgagLEQiQtIASjU+bwxd8kS/ASDA4a8ufd8m0Lheu6eeMJHEUpLHoJ28A==" + "integrity": "sha512-/bfTiIUTNPUBnwnYvUxXAre5MhD88jgagLEQiQtIASjU+bwxd8kS/ASDA4a8ufd8m0Lheu6eeMJHEUpLHoJ28A==", + "dev": true }, "node_modules/@types/minimatch": { "version": "3.0.5", @@ -15786,6 +15858,7 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.2", + "dev": true, "license": "MIT" }, "node_modules/@types/unist": { @@ -16422,6 +16495,7 @@ }, "node_modules/@vue/preload-webpack-plugin": { "version": "2.0.0", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=6.0.0" @@ -16433,10 +16507,12 @@ }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", @@ -16446,14 +16522,17 @@ }, "node_modules/@webassemblyjs/helper-numbers/node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers/node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", @@ -16464,6 +16543,7 @@ }, "node_modules/@webassemblyjs/helper-wasm-section/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -16472,10 +16552,12 @@ }, "node_modules/@webassemblyjs/helper-wasm-section/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" @@ -16483,6 +16565,7 @@ }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.6", + "dev": true, "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" @@ -16490,10 +16573,12 @@ }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", @@ -16508,6 +16593,7 @@ }, "node_modules/@webassemblyjs/wasm-edit/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -16516,10 +16602,12 @@ }, "node_modules/@webassemblyjs/wasm-edit/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit/node_modules/@webassemblyjs/wast-printer": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", @@ -16528,6 +16616,7 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", @@ -16539,6 +16628,7 @@ }, "node_modules/@webassemblyjs/wasm-gen/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -16547,10 +16637,12 @@ }, "node_modules/@webassemblyjs/wasm-gen/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", @@ -16561,6 +16653,7 @@ }, "node_modules/@webassemblyjs/wasm-opt/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -16569,10 +16662,12 @@ }, "node_modules/@webassemblyjs/wasm-opt/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", @@ -16585,6 +16680,7 @@ }, "node_modules/@webassemblyjs/wasm-parser/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -16593,10 +16689,12 @@ }, "node_modules/@webassemblyjs/wasm-parser/node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-parser/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/@webpack-cli/configtest": { @@ -16660,10 +16758,12 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", + "dev": true, "license": "Apache-2.0" }, "node_modules/@yarnpkg/fslib": { @@ -16712,6 +16812,7 @@ }, "node_modules/abab": { "version": "2.0.6", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/abbrev": { @@ -16770,6 +16871,7 @@ }, "node_modules/acorn-globals": { "version": "7.0.1", + "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.1.0", @@ -16778,6 +16880,7 @@ }, "node_modules/acorn-globals/node_modules/acorn": { "version": "8.11.3", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -16788,6 +16891,7 @@ }, "node_modules/acorn-globals/node_modules/acorn-walk": { "version": "8.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -16811,6 +16915,7 @@ }, "node_modules/adm-zip": { "version": "0.5.10", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0" @@ -17296,7 +17401,7 @@ }, "node_modules/arg": { "version": "4.1.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/argparse": { @@ -17364,6 +17469,7 @@ }, "node_modules/array-flatten": { "version": "1.1.1", + "dev": true, "license": "MIT" }, "node_modules/array-includes": { @@ -17818,6 +17924,7 @@ }, "node_modules/babel-jest": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.4.1", @@ -17837,6 +17944,7 @@ }, "node_modules/babel-jest/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -17850,6 +17958,7 @@ }, "node_modules/babel-jest/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -17864,6 +17973,7 @@ }, "node_modules/babel-jest/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -17874,10 +17984,12 @@ }, "node_modules/babel-jest/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17885,6 +17997,7 @@ }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -18058,6 +18171,7 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -18072,6 +18186,7 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -18386,6 +18501,7 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -18536,6 +18652,7 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", @@ -18749,6 +18866,7 @@ }, "node_modules/bin-links": { "version": "4.0.2", + "dev": true, "license": "ISC", "dependencies": { "cmd-shim": "^6.0.0", @@ -18762,6 +18880,7 @@ }, "node_modules/bin-links/node_modules/signal-exit": { "version": "4.1.0", + "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -18772,6 +18891,7 @@ }, "node_modules/bin-links/node_modules/write-file-atomic": { "version": "5.0.1", + "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -18839,6 +18959,7 @@ "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -18863,6 +18984,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18872,6 +18994,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -18881,6 +19004,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -18893,6 +19017,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, "license": "MIT" }, "node_modules/bonjour-service": { @@ -19543,6 +19668,7 @@ }, "node_modules/camel-case": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", @@ -19642,6 +19768,7 @@ }, "node_modules/char-regex": { "version": "1.0.2", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -19718,6 +19845,7 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.3", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0" @@ -19875,6 +20003,7 @@ }, "node_modules/clean-css": { "version": "5.3.2", + "dev": true, "license": "MIT", "dependencies": { "source-map": "~0.6.0" @@ -19885,6 +20014,7 @@ }, "node_modules/clean-css/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -20038,6 +20168,7 @@ }, "node_modules/cmd-shim": { "version": "6.0.1", + "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -20060,6 +20191,7 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/collection-visit": { @@ -20550,6 +20682,7 @@ }, "node_modules/content-disposition": { "version": "0.5.4", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -20560,6 +20693,7 @@ }, "node_modules/content-disposition/node_modules/safe-buffer": { "version": "5.2.1", + "dev": true, "funding": [ { "type": "github", @@ -20580,6 +20714,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -20602,6 +20737,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -20609,6 +20745,7 @@ }, "node_modules/cookie-signature": { "version": "1.0.6", + "dev": true, "license": "MIT" }, "node_modules/copy-descriptor": { @@ -20863,7 +21000,7 @@ }, "node_modules/create-require": { "version": "1.1.1", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/create-storybook": { @@ -21306,6 +21443,7 @@ }, "node_modules/cssom": { "version": "0.5.0", + "dev": true, "license": "MIT" }, "node_modules/csstype": { @@ -21424,6 +21562,7 @@ }, "node_modules/decimal.js": { "version": "10.4.3", + "dev": true, "license": "MIT" }, "node_modules/decode-uri-component": { @@ -21773,6 +21912,7 @@ }, "node_modules/detect-newline": { "version": "3.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -21806,7 +21946,7 @@ }, "node_modules/diff": { "version": "4.0.2", - "devOptional": true, + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -21814,6 +21954,7 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -21979,6 +22120,7 @@ }, "node_modules/dom-converter": { "version": "0.2.0", + "dev": true, "license": "MIT", "dependencies": { "utila": "~0.4" @@ -22012,6 +22154,7 @@ }, "node_modules/domexception": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "webidl-conversions": "^7.0.0" @@ -22059,6 +22202,7 @@ }, "node_modules/dot-case": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -22388,6 +22532,7 @@ }, "node_modules/emittery": { "version": "0.13.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -22446,6 +22591,7 @@ }, "node_modules/enhanced-resolve": { "version": "5.15.0", + "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -22662,6 +22808,7 @@ }, "node_modules/es-module-lexer": { "version": "1.5.0", + "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { @@ -22790,6 +22937,7 @@ }, "node_modules/escodegen": { "version": "2.1.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", @@ -22809,6 +22957,7 @@ }, "node_modules/escodegen/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "optional": true, "engines": { @@ -23636,6 +23785,7 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -23647,6 +23797,7 @@ }, "node_modules/eslint-scope/node_modules/estraverse": { "version": "4.3.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -23892,6 +24043,7 @@ }, "node_modules/esrecurse": { "version": "4.3.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -23902,6 +24054,7 @@ }, "node_modules/estraverse": { "version": "5.3.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -23975,6 +24128,7 @@ }, "node_modules/exit": { "version": "0.1.2", + "dev": true, "engines": { "node": ">= 0.8.0" } @@ -24106,6 +24260,7 @@ }, "node_modules/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -24464,6 +24619,7 @@ "version": "4.20.0", "resolved": "https://registry.npmjs.org/express/-/express-4.20.0.tgz", "integrity": "sha512-pLdae7I6QqShF5PnNTCVn4hI91Dx0Grkn2+IAsMTgMIKuQVte2dN9PeGSSAME2FR8anOhVA62QDIUaWVfEXVLw==", + "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -24504,6 +24660,7 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -24513,6 +24670,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -24522,6 +24680,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, "license": "MIT", "bin": { "mime": "cli.js" @@ -24532,12 +24691,14 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", + "dev": true, "license": "MIT" }, "node_modules/express/node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" @@ -24551,6 +24712,7 @@ }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", + "dev": true, "funding": [ { "type": "github", @@ -24571,6 +24733,7 @@ "version": "0.19.0", "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -24595,6 +24758,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -24604,6 +24768,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/extend-shallow": { @@ -24757,6 +24922,7 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -24943,6 +25109,7 @@ }, "node_modules/finalhandler": { "version": "1.2.0", + "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -24959,6 +25126,7 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", + "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -24966,6 +25134,7 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", + "dev": true, "license": "MIT" }, "node_modules/find-babel-config": { @@ -25132,6 +25301,7 @@ }, "node_modules/follow-redirects": { "version": "1.15.5", + "dev": true, "funding": [ { "type": "individual", @@ -25344,6 +25514,7 @@ }, "node_modules/forwarded": { "version": "0.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -25653,6 +25824,7 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -25763,6 +25935,7 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", + "dev": true, "license": "BSD-2-Clause" }, "node_modules/global-agent": { @@ -26188,6 +26361,7 @@ }, "node_modules/he": { "version": "1.2.0", + "dev": true, "license": "MIT", "bin": { "he": "bin/he" @@ -26265,6 +26439,7 @@ }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "whatwg-encoding": "^2.0.0" @@ -26289,10 +26464,12 @@ }, "node_modules/html-escaper": { "version": "2.0.2", + "dev": true, "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", + "dev": true, "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -26312,6 +26489,7 @@ }, "node_modules/html-minifier-terser/node_modules/commander": { "version": "8.3.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 12" @@ -26330,6 +26508,7 @@ }, "node_modules/html-webpack-plugin": { "version": "5.5.3", + "dev": true, "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -26668,6 +26847,7 @@ }, "node_modules/iconv-lite": { "version": "0.6.3", + "devOptional": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -26775,6 +26955,7 @@ }, "node_modules/import-local": { "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -26792,6 +26973,7 @@ }, "node_modules/import-local/node_modules/find-up": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -26803,6 +26985,7 @@ }, "node_modules/import-local/node_modules/locate-path": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -26813,6 +26996,7 @@ }, "node_modules/import-local/node_modules/p-limit": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -26826,6 +27010,7 @@ }, "node_modules/import-local/node_modules/p-locate": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -26836,6 +27021,7 @@ }, "node_modules/import-local/node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -26843,6 +27029,7 @@ }, "node_modules/import-local/node_modules/pkg-dir": { "version": "4.2.0", + "dev": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -27348,6 +27535,7 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -27550,6 +27738,7 @@ }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/is-regex": { @@ -27736,6 +27925,7 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -27743,6 +27933,7 @@ }, "node_modules/istanbul-lib-instrument": { "version": "5.2.0", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -27757,6 +27948,7 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.1", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -27764,6 +27956,7 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -27776,6 +27969,7 @@ }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -27783,6 +27977,7 @@ }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -27796,6 +27991,7 @@ }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -27806,6 +28002,7 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -27818,6 +28015,7 @@ }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -27825,6 +28023,7 @@ }, "node_modules/istanbul-reports": { "version": "3.1.7", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -27951,6 +28150,7 @@ }, "node_modules/jest": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.4.1", @@ -27975,6 +28175,7 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "execa": "^5.0.0", @@ -28080,6 +28281,7 @@ }, "node_modules/jest-cli": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.4.1", @@ -28112,6 +28314,7 @@ }, "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28125,6 +28328,7 @@ }, "node_modules/jest-cli/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28139,6 +28343,7 @@ }, "node_modules/jest-cli/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28149,10 +28354,12 @@ }, "node_modules/jest-cli/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28160,6 +28367,7 @@ }, "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28170,6 +28378,7 @@ }, "node_modules/jest-config": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -28213,6 +28422,7 @@ }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28226,6 +28436,7 @@ }, "node_modules/jest-config/node_modules/babel-jest": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", @@ -28245,6 +28456,7 @@ }, "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28259,6 +28471,7 @@ }, "node_modules/jest-config/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28269,10 +28482,12 @@ }, "node_modules/jest-config/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-config/node_modules/dedent": { "version": "1.5.3", + "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -28285,6 +28500,7 @@ }, "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28292,6 +28508,7 @@ }, "node_modules/jest-config/node_modules/jest-circus": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -28321,6 +28538,7 @@ }, "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28331,6 +28549,7 @@ }, "node_modules/jest-diff": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -28344,6 +28563,7 @@ }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28357,6 +28577,7 @@ }, "node_modules/jest-diff/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28371,6 +28592,7 @@ }, "node_modules/jest-diff/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28381,10 +28603,12 @@ }, "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28392,6 +28616,7 @@ }, "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28402,6 +28627,7 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -28412,6 +28638,7 @@ }, "node_modules/jest-each": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -28426,6 +28653,7 @@ }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28439,6 +28667,7 @@ }, "node_modules/jest-each/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28453,6 +28682,7 @@ }, "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28463,10 +28693,12 @@ }, "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28474,6 +28706,7 @@ }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28484,6 +28717,7 @@ }, "node_modules/jest-environment-jsdom": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.4.1", @@ -28509,6 +28743,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/acorn": { "version": "8.11.3", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -28519,6 +28754,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/cssstyle": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "cssom": "~0.3.6" @@ -28529,10 +28765,12 @@ }, "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", + "dev": true, "license": "MIT" }, "node_modules/jest-environment-jsdom/node_modules/data-urls": { "version": "3.0.2", + "dev": true, "license": "MIT", "dependencies": { "abab": "^2.0.6", @@ -28545,6 +28783,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/entities": { "version": "4.5.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -28555,6 +28794,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/form-data": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -28567,6 +28807,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/jsdom": { "version": "20.0.3", + "dev": true, "license": "MIT", "dependencies": { "abab": "^2.0.6", @@ -28610,6 +28851,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/parse5": { "version": "7.1.2", + "dev": true, "license": "MIT", "dependencies": { "entities": "^4.4.0" @@ -28620,6 +28862,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/tr46": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "punycode": "^2.1.1" @@ -28630,6 +28873,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "xml-name-validator": "^4.0.0" @@ -28640,6 +28884,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -28647,6 +28892,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { "version": "11.0.0", + "dev": true, "license": "MIT", "dependencies": { "tr46": "^3.0.0", @@ -28658,6 +28904,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/xml-name-validator": { "version": "4.0.0", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12" @@ -28680,6 +28927,7 @@ }, "node_modules/jest-expo": { "version": "51.0.3", + "dev": true, "license": "MIT", "dependencies": { "@expo/config": "~9.0.0-beta.0", @@ -28701,6 +28949,7 @@ }, "node_modules/jest-expo/node_modules/@babel/code-frame": { "version": "7.10.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/highlight": "^7.10.4" @@ -28708,6 +28957,7 @@ }, "node_modules/jest-expo/node_modules/@expo/json-file": { "version": "8.3.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "~7.10.4", @@ -28717,6 +28967,7 @@ }, "node_modules/jest-expo/node_modules/react-test-renderer": { "version": "18.2.0", + "dev": true, "license": "MIT", "dependencies": { "react-is": "^18.2.0", @@ -28729,6 +28980,7 @@ }, "node_modules/jest-expo/node_modules/scheduler": { "version": "0.23.2", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -28743,6 +28995,7 @@ }, "node_modules/jest-haste-map": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -28766,6 +29019,7 @@ }, "node_modules/jest-haste-map/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28773,6 +29027,7 @@ }, "node_modules/jest-haste-map/node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -28786,6 +29041,7 @@ }, "node_modules/jest-haste-map/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28799,6 +29055,7 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", @@ -28810,6 +29067,7 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -28823,6 +29081,7 @@ }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28836,6 +29095,7 @@ }, "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28850,6 +29110,7 @@ }, "node_modules/jest-matcher-utils/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28860,10 +29121,12 @@ }, "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28871,6 +29134,7 @@ }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28969,6 +29233,7 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -28984,6 +29249,7 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -28991,6 +29257,7 @@ }, "node_modules/jest-resolve": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -29009,6 +29276,7 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", @@ -29020,6 +29288,7 @@ }, "node_modules/jest-resolve/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29033,6 +29302,7 @@ }, "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29047,6 +29317,7 @@ }, "node_modules/jest-resolve/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29057,10 +29328,12 @@ }, "node_modules/jest-resolve/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29068,6 +29341,7 @@ }, "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29078,6 +29352,7 @@ }, "node_modules/jest-runner": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -29108,6 +29383,7 @@ }, "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29121,6 +29397,7 @@ }, "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29135,6 +29412,7 @@ }, "node_modules/jest-runner/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29145,10 +29423,12 @@ }, "node_modules/jest-runner/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29156,6 +29436,7 @@ }, "node_modules/jest-runner/node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -29169,6 +29450,7 @@ }, "node_modules/jest-runner/node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29182,6 +29464,7 @@ }, "node_modules/jest-runner/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -29189,6 +29472,7 @@ }, "node_modules/jest-runner/node_modules/source-map-support": { "version": "0.5.13", + "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -29197,6 +29481,7 @@ }, "node_modules/jest-runner/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29207,6 +29492,7 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -29238,6 +29524,7 @@ }, "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29251,6 +29538,7 @@ }, "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29265,6 +29553,7 @@ }, "node_modules/jest-runtime/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29275,10 +29564,12 @@ }, "node_modules/jest-runtime/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29286,6 +29577,7 @@ }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29296,6 +29588,7 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -29325,6 +29618,7 @@ }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29338,6 +29632,7 @@ }, "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29352,6 +29647,7 @@ }, "node_modules/jest-snapshot/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29362,10 +29658,12 @@ }, "node_modules/jest-snapshot/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29373,6 +29671,7 @@ }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29538,6 +29837,7 @@ }, "node_modules/jest-watch-select-projects": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.0", @@ -29547,6 +29847,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29560,6 +29861,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/chalk": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29571,6 +29873,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29581,10 +29884,12 @@ }, "node_modules/jest-watch-select-projects/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watch-select-projects/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29592,6 +29897,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29602,6 +29908,7 @@ }, "node_modules/jest-watch-typeahead": { "version": "2.2.1", + "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^6.0.0", @@ -29621,6 +29928,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-escapes": { "version": "6.2.0", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^3.0.0" @@ -29634,6 +29942,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-regex": { "version": "6.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -29644,6 +29953,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29657,6 +29967,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29671,6 +29982,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/char-regex": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12.20" @@ -29678,6 +29990,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29688,10 +30001,12 @@ }, "node_modules/jest-watch-typeahead/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watch-typeahead/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29699,6 +30014,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/slash": { "version": "5.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=14.16" @@ -29709,6 +30025,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/string-length": { "version": "5.0.1", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^2.0.0", @@ -29723,6 +30040,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { "version": "7.1.0", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -29736,6 +30054,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29746,6 +30065,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/type-fest": { "version": "3.13.1", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=14.16" @@ -29756,6 +30076,7 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -29773,6 +30094,7 @@ }, "node_modules/jest-watcher/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29786,6 +30108,7 @@ }, "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29800,6 +30123,7 @@ }, "node_modules/jest-watcher/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29810,10 +30134,12 @@ }, "node_modules/jest-watcher/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watcher/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29821,6 +30147,7 @@ }, "node_modules/jest-watcher/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29831,6 +30158,7 @@ }, "node_modules/jest-when": { "version": "3.5.2", + "dev": true, "license": "MIT", "peerDependencies": { "jest": ">= 25" @@ -29838,6 +30166,7 @@ }, "node_modules/jest-worker": { "version": "27.5.1", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -29850,6 +30179,7 @@ }, "node_modules/jest-worker/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29857,6 +30187,7 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -30121,6 +30452,7 @@ }, "node_modules/json-stringify-safe": { "version": "5.0.1", + "dev": true, "license": "ISC" }, "node_modules/json5": { @@ -30803,6 +31135,7 @@ }, "node_modules/lower-case": { "version": "2.0.2", + "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -30869,7 +31202,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "devOptional": true, + "dev": true, "license": "ISC" }, "node_modules/make-event-props": { @@ -31207,6 +31540,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -31307,6 +31641,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -31335,6 +31670,7 @@ }, "node_modules/methods": { "version": "1.1.2", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -32229,6 +32565,7 @@ }, "node_modules/natural-compare": { "version": "1.4.0", + "dev": true, "license": "MIT" }, "node_modules/natural-compare-lite": { @@ -32265,6 +32602,7 @@ }, "node_modules/no-case": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "lower-case": "^2.0.2", @@ -32280,6 +32618,7 @@ }, "node_modules/nock": { "version": "13.3.3", + "dev": true, "license": "MIT", "dependencies": { "debug": "^4.1.0", @@ -32597,6 +32936,7 @@ }, "node_modules/npm-normalize-package-bin": { "version": "3.0.1", + "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -32673,6 +33013,7 @@ }, "node_modules/nwsapi": { "version": "2.2.7", + "dev": true, "license": "MIT" }, "node_modules/nypm": { @@ -33433,6 +33774,7 @@ }, "node_modules/param-case": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -33502,6 +33844,7 @@ }, "node_modules/pascal-case": { "version": "3.1.2", + "dev": true, "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -33733,6 +34076,7 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true, "license": "MIT" }, "node_modules/path-type": { @@ -34155,6 +34499,7 @@ }, "node_modules/pretty-error": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "lodash": "^4.17.20", @@ -34267,6 +34612,7 @@ }, "node_modules/propagate": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -34278,6 +34624,7 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", + "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -34293,6 +34640,7 @@ }, "node_modules/psl": { "version": "1.9.0", + "dev": true, "license": "MIT" }, "node_modules/public-encrypt": { @@ -34328,6 +34676,7 @@ }, "node_modules/pure-rand": { "version": "6.0.4", + "dev": true, "funding": [ { "type": "individual", @@ -34518,6 +34867,7 @@ "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" @@ -34559,6 +34909,7 @@ }, "node_modules/querystringify": { "version": "2.2.0", + "dev": true, "license": "MIT" }, "node_modules/queue": { @@ -34654,6 +35005,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -34669,6 +35021,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -34678,6 +35031,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -38001,6 +38355,7 @@ }, "node_modules/read-cmd-shim": { "version": "4.0.0", + "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -38338,6 +38693,7 @@ }, "node_modules/relateurl": { "version": "0.2.7", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -38354,6 +38710,7 @@ }, "node_modules/renderkid": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "css-select": "^4.1.3", @@ -38365,6 +38722,7 @@ }, "node_modules/renderkid/node_modules/css-select": { "version": "4.3.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -38379,6 +38737,7 @@ }, "node_modules/renderkid/node_modules/htmlparser2": { "version": "6.1.0", + "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -38468,6 +38827,7 @@ }, "node_modules/requires-port": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/resedit": { @@ -38509,6 +38869,7 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -38751,6 +39112,7 @@ }, "node_modules/saxes": { "version": "6.0.0", + "dev": true, "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" @@ -38768,6 +39130,7 @@ }, "node_modules/schema-utils": { "version": "3.3.0", + "dev": true, "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", @@ -38784,6 +39147,7 @@ }, "node_modules/schema-utils/node_modules/ajv": { "version": "6.12.6", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -38798,6 +39162,7 @@ }, "node_modules/schema-utils/node_modules/ajv-keywords": { "version": "3.5.2", + "dev": true, "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" @@ -38805,6 +39170,7 @@ }, "node_modules/schema-utils/node_modules/json-schema-traverse": { "version": "0.4.1", + "dev": true, "license": "MIT" }, "node_modules/secure-compare": { @@ -38927,6 +39293,7 @@ }, "node_modules/serialize-javascript": { "version": "6.0.2", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -39270,6 +39637,7 @@ }, "node_modules/simple-git": { "version": "3.24.0", + "dev": true, "license": "MIT", "dependencies": { "@kwsites/file-exists": "^1.1.1", @@ -40101,6 +40469,7 @@ }, "node_modules/string-length": { "version": "4.0.2", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -40251,6 +40620,7 @@ }, "node_modules/strip-bom": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -40283,6 +40653,7 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -40548,6 +40919,7 @@ }, "node_modules/symbol-tree": { "version": "3.2.4", + "dev": true, "license": "MIT" }, "node_modules/tabbable": { @@ -40556,6 +40928,7 @@ }, "node_modules/tapable": { "version": "2.2.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -40756,6 +41129,7 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.10", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", @@ -40802,6 +41176,7 @@ }, "node_modules/test-exclude": { "version": "6.0.0", + "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -41083,6 +41458,7 @@ }, "node_modules/tough-cookie": { "version": "4.1.3", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", @@ -41096,6 +41472,7 @@ }, "node_modules/tough-cookie/node_modules/universalify": { "version": "0.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -41215,7 +41592,7 @@ }, "node_modules/ts-node": { "version": "10.9.2", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -41257,7 +41634,7 @@ }, "node_modules/ts-node/node_modules/acorn": { "version": "8.11.3", - "devOptional": true, + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -41268,7 +41645,7 @@ }, "node_modules/ts-node/node_modules/acorn-walk": { "version": "8.3.2", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -41385,6 +41762,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -41887,6 +42265,7 @@ }, "node_modules/url-parse": { "version": "1.5.10", + "dev": true, "license": "MIT", "dependencies": { "querystringify": "^2.1.1", @@ -42106,6 +42485,7 @@ }, "node_modules/utila": { "version": "0.4.0", + "dev": true, "license": "MIT" }, "node_modules/utils-merge": { @@ -42131,11 +42511,12 @@ }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.2.0", + "dev": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -42250,6 +42631,7 @@ }, "node_modules/watchpack": { "version": "2.4.0", + "dev": true, "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -42522,6 +42904,7 @@ }, "node_modules/webidl-conversions": { "version": "7.0.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -42529,6 +42912,7 @@ }, "node_modules/webpack": { "version": "5.88.2", + "dev": true, "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -43117,10 +43501,12 @@ }, "node_modules/webpack/node_modules/@types/estree": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/webpack/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -43129,10 +43515,12 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "dev": true, "license": "MIT" }, "node_modules/webpack/node_modules/acorn": { "version": "8.10.0", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -43143,6 +43531,7 @@ }, "node_modules/webpack/node_modules/acorn-import-assertions": { "version": "1.9.0", + "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^8" @@ -43150,6 +43539,7 @@ }, "node_modules/webpack/node_modules/loader-runner": { "version": "4.3.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" @@ -43157,6 +43547,7 @@ }, "node_modules/webpack/node_modules/webpack-sources": { "version": "3.2.3", + "dev": true, "license": "MIT", "engines": { "node": ">=10.13.0" @@ -43185,6 +43576,7 @@ }, "node_modules/whatwg-encoding": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" @@ -43479,6 +43871,7 @@ "version": "0.20.3", "resolved": "file:vendor/xlsx-0.20.3.tgz", "integrity": "sha512-oLDq3jw7AcLqKWH2AhCpVTZl8mf6X2YReP+Neh0SJUzV/BdZYjth94tG5toiMB1PPrYtxOCfaoUCkvtuH+3AJA==", + "dev": true, "bin": { "xlsx": "bin/xlsx.njs" }, @@ -43553,6 +43946,7 @@ }, "node_modules/xmlchars": { "version": "2.2.0", + "dev": true, "license": "MIT" }, "node_modules/xpath": { @@ -43634,7 +44028,7 @@ }, "node_modules/yn": { "version": "3.1.1", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/package.json b/package.json index 34124107e436..b29533992d82 100644 --- a/package.json +++ b/package.json @@ -67,8 +67,6 @@ "web:prod": "http-server ./dist --cors" }, "dependencies": { - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@dotlottie/react-player": "^1.6.3", "@expensify/react-native-live-markdown": "0.1.120", "@expo/metro-runtime": "~3.1.1", @@ -77,14 +75,10 @@ "@formatjs/intl-locale": "^4.0.0", "@formatjs/intl-numberformat": "^8.10.3", "@formatjs/intl-pluralrules": "^5.2.14", - "@fullstory/babel-plugin-annotate-react": "github:fullstorydev/fullstory-babel-plugin-annotate-react#ryanwang/react-native-web-demo", - "@fullstory/babel-plugin-react-native": "^1.2.1", "@fullstory/browser": "^2.0.3", "@fullstory/react-native": "^1.4.2", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", - "@kie/act-js": "^2.6.2", - "@kie/mock-github": "2.0.1", "@onfido/react-native-sdk": "10.6.0", "@react-native-camera-roll/camera-roll": "7.4.0", "@react-native-clipboard/clipboard": "^1.13.2", @@ -102,9 +96,7 @@ "@react-ng/bounds-observer": "^0.2.1", "@rnmapbox/maps": "10.1.30", "@shopify/flash-list": "1.7.1", - "@types/mime-db": "^1.43.5", "@ua/react-native-airship": "19.2.1", - "@vue/preload-webpack-plugin": "^2.0.0", "awesome-phonenumber": "^5.4.0", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", @@ -122,8 +114,6 @@ "focus-trap-react": "^10.2.3", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", - "jest-expo": "51.0.3", - "jest-when": "^3.5.2", "lodash-es": "4.17.21", "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", @@ -133,7 +123,6 @@ "react": "18.3.1", "react-beautiful-dnd": "^13.1.1", "react-collapse": "^5.1.0", - "react-compiler-runtime": "file:./lib/react-compiler-runtime", "react-content-loader": "^7.0.0", "react-dom": "18.3.1", "react-error-boundary": "^4.0.11", @@ -189,11 +178,22 @@ "react-plaid-link": "3.3.2", "react-web-config": "^1.0.0", "react-webcam": "^7.1.1", - "react-window": "^1.8.9", - "semver": "^7.5.2", - "xlsx": "file:vendor/xlsx-0.20.3.tgz" + "react-window": "^1.8.9" }, "devDependencies": { + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@fullstory/babel-plugin-annotate-react": "github:fullstorydev/fullstory-babel-plugin-annotate-react#ryanwang/react-native-web-demo", + "@fullstory/babel-plugin-react-native": "^1.2.1", + "@kie/act-js": "^2.6.2", + "@kie/mock-github": "2.0.1", + "@types/mime-db": "^1.43.5", + "@vue/preload-webpack-plugin": "^2.0.0", + "jest-expo": "51.0.3", + "jest-when": "^3.5.2", + "react-compiler-runtime": "file:./lib/react-compiler-runtime", + "semver": "^7.5.2", + "xlsx": "file:vendor/xlsx-0.20.3.tgz", "@actions/core": "1.10.0", "@actions/github": "5.1.1", "@babel/core": "^7.20.0", From e0e1d5bff44f677d7f9fae8af8c3bb6646da3552 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Thu, 12 Sep 2024 17:02:18 +0200 Subject: [PATCH 026/104] make pending keys unique --- src/CONST.ts | 1 + src/libs/PolicyUtils.ts | 7 +++++++ src/libs/actions/Policy/Category.ts | 19 +++++++++++-------- src/libs/actions/Policy/Tag.ts | 7 ++++--- .../categories/CategorySettingsPage.tsx | 8 ++++++-- src/pages/workspace/tags/TagSettingsPage.tsx | 2 +- 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 2e91ec48901f..5a6a7ba30564 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2150,6 +2150,7 @@ const CONST = { TAG: 'tag', CATEGORY: 'category', TITLE: 'text_title', + TAX: 'tax', }, DEFAULT_REPORT_NAME_PATTERN: '{report:type} {report:startdate}', ROLE: { diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 46914be44f38..9c322a62b785 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -989,6 +989,12 @@ function getTagApproverRule(policyID: string, tagName: string) { return approverRule; } +type PolicyFieldUpdateKeyField = ValueOf; + +function getPolicyFieldUpdateKey(fieldValue: string, fieldName: PolicyFieldUpdateKeyField) { + return `${fieldName}_${fieldValue}`; +} + function getDomainNameForPolicy(policyID?: string): string { if (!policyID) { return ''; @@ -1110,6 +1116,7 @@ export { getTagApproverRule, getDomainNameForPolicy, getWorkflowApprovalsUnavailable, + getPolicyFieldUpdateKey, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 1b571e4d6bdb..f34cdf5b57df 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -28,6 +28,7 @@ import Log from '@libs/Log'; import enhanceParameters from '@libs/Network/enhanceParameters'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import {navigateWhenEnableFeature, removePendingFieldsFromCustomUnit} from '@libs/PolicyUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -1152,6 +1153,7 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro const approvalRules = policy?.rules?.approvalRules ?? []; let updatedApprovalRules: ApprovalRule[] = lodashCloneDeep(approvalRules); const existingCategoryApproverRule = CategoryUtils.getCategoryApproverRule(updatedApprovalRules, categoryName); + const categoryRuleUpdateKey = PolicyUtils.getPolicyFieldUpdateKey(categoryName, CONST.POLICY.FIELDS.CATEGORY); let newApprover = approver; @@ -1184,7 +1186,7 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro approvalRules: updatedApprovalRules, }, pendingRulesUpdates: { - [categoryName]: { + [categoryRuleUpdateKey]: { approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, @@ -1197,8 +1199,8 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingRulesUpdates: { - [categoryName]: { - approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + [categoryRuleUpdateKey]: { + approvalRule: null, }, }, }, @@ -1213,8 +1215,8 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro approvalRules, }, pendingRulesUpdates: { - [categoryName]: { - approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + [categoryRuleUpdateKey]: { + approvalRule: null, }, }, }, @@ -1236,6 +1238,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str const expenseRules = policy?.rules?.expenseRules ?? []; const updatedExpenseRules: ExpenseRule[] = lodashCloneDeep(expenseRules); const existingCategoryExpenseRule = updatedExpenseRules.find((rule) => rule.applyWhen.some((when) => when.value === categoryName)); + const categoryRuleUpdateKey = PolicyUtils.getPolicyFieldUpdateKey(categoryName, CONST.POLICY.FIELDS.TAX); if (!existingCategoryExpenseRule) { updatedExpenseRules.push({ @@ -1268,7 +1271,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str expenseRules: updatedExpenseRules, }, pendingRulesUpdates: { - [categoryName]: { + [categoryRuleUpdateKey]: { expenseRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, @@ -1281,7 +1284,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingRulesUpdates: { - [categoryName]: { + [categoryRuleUpdateKey]: { expenseRule: null, }, }, @@ -1297,7 +1300,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str expenseRules, }, pendingRulesUpdates: { - [categoryName]: { + [categoryRuleUpdateKey]: { expenseRule: null, }, }, diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index d126cf9e58e0..f6ed865d1695 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -853,6 +853,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { const approverRuleToUpdate = PolicyUtils.getTagApproverRule(policyID, tag); const filteredApprovalRules = approverRuleToUpdate ? prevApprovalRules.filter((rule) => rule.id !== approverRuleToUpdate.id) : prevApprovalRules; const toBeUnselected = approverRuleToUpdate?.approver === approver; + const tagRuleUpdateKey = PolicyUtils.getPolicyFieldUpdateKey(tag, CONST.POLICY.FIELDS.TAG); const updatedApproverRule = approverRuleToUpdate ? {...approverRuleToUpdate, approver} @@ -880,7 +881,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { approvalRules: updatedApprovalRules, }, pendingRulesUpdates: { - [tag]: { + [tagRuleUpdateKey]: { approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, }, }, @@ -896,7 +897,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { approvalRules: updatedApprovalRules, }, pendingRulesUpdates: { - [tag]: { + [tagRuleUpdateKey]: { approvalRule: null, }, }, @@ -912,7 +913,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { approvalRules: prevApprovalRules, }, pendingRulesUpdates: { - [tag]: { + [tagRuleUpdateKey]: { approvalRule: null, }, }, diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index cd8a462f7bb6..6e939dc18351 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -260,7 +260,9 @@ function CategorySettingsPage({ /> )} - + )} {policy?.tax?.trackingEnabled && ( - + {translate('workspace.tags.tagRules')} - + Date: Thu, 12 Sep 2024 23:23:44 +0530 Subject: [PATCH 027/104] Fix clear error function --- .../SageIntacctNonReimbursableExpensesDestinationPage.tsx | 2 +- .../export/SageIntacctReimbursableExpensesDestinationPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx index 1355b07773ed..51a80c57599b 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx @@ -59,7 +59,7 @@ function SageIntacctNonReimbursableExpensesDestinationPage({policy}: WithPolicyC pendingAction={settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE], config?.pendingFields)} errors={ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE)} errorRowStyles={[styles.ph5, styles.pv3]} - onClose={() => Policy.clearNetSuiteErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE)} + onClose={() => Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE)} /> ); } diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx index aad242798324..2517d1d6843e 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx @@ -63,7 +63,7 @@ function SageIntacctReimbursableExpensesDestinationPage({policy}: WithPolicyConn pendingAction={settingsPendingAction([CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE], config?.pendingFields)} errors={ErrorUtils.getLatestErrorField(config, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)} errorRowStyles={[styles.ph5, styles.pv3]} - onClose={() => Policy.clearNetSuiteErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)} + onClose={() => Policy.clearSageIntacctErrorField(policyID, CONST.SAGE_INTACCT_CONFIG.REIMBURSABLE)} /> ); } From e44b5220ac5d9253716403b5d79557db7d1ffc0c Mon Sep 17 00:00:00 2001 From: Marc Glasser Date: Thu, 12 Sep 2024 10:15:05 -1000 Subject: [PATCH 028/104] Use jsonCode instead of error message --- src/CONST.ts | 1 + src/libs/actions/Card.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index 0778478c2950..3488363922e4 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1149,6 +1149,7 @@ const CONST = { MANY_WRITES_ERROR: 665, UNABLE_TO_RETRY: 'unableToRetry', UPDATE_REQUIRED: 426, + INCORRECT_MAGIC_CODE: 451, }, HTTP_STATUS: { // When Cloudflare throttles diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index 15d1eadb662d..e423af5bb7e7 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -202,7 +202,7 @@ function revealVirtualCardDetails(cardID: number, validateCode: string): Promise API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.REVEAL_EXPENSIFY_CARD_DETAILS, parameters) .then((response) => { if (response?.jsonCode !== CONST.JSON_CODE.SUCCESS) { - if (response?.message === 'Incorrect or invalid magic code. Please try again.') { + if (response?.jsonCode === CONST.JSON_CODE.INCORRECT_MAGIC_CODE) { // eslint-disable-next-line prefer-promise-reject-errors reject('validateCodeForm.error.incorrectMagicCode'); return; From 3c1f44245ced0e54471fbbbb9c70499364afd4a7 Mon Sep 17 00:00:00 2001 From: daledah Date: Fri, 13 Sep 2024 04:02:38 +0700 Subject: [PATCH 029/104] fix: react-compiler --- src/pages/home/ReportScreen.tsx | 86 +++++++++++++++++---------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 2f36262eda78..5a07f89af24c 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -169,47 +169,47 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const report = useMemo( (): OnyxEntry => reportOnyx && { - lastReadTime: reportOnyx?.lastReadTime, - reportID: reportOnyx?.reportID ?? '', - policyID: reportOnyx?.policyID, - lastVisibleActionCreated: reportOnyx?.lastVisibleActionCreated, - statusNum: reportOnyx?.statusNum, - stateNum: reportOnyx?.stateNum, - writeCapability: reportOnyx?.writeCapability, - type: reportOnyx?.type, - errorFields: reportOnyx?.errorFields, - isPolicyExpenseChat: reportOnyx?.isPolicyExpenseChat, - parentReportID: reportOnyx?.parentReportID, - parentReportActionID: reportOnyx?.parentReportActionID, - chatType: reportOnyx?.chatType, - pendingFields: reportOnyx?.pendingFields, - isDeletedParentAction: reportOnyx?.isDeletedParentAction, - reportName: reportOnyx?.reportName, - description: reportOnyx?.description, - managerID: reportOnyx?.managerID, - total: reportOnyx?.total, - nonReimbursableTotal: reportOnyx?.nonReimbursableTotal, - fieldList: reportOnyx?.fieldList, - ownerAccountID: reportOnyx?.ownerAccountID, - currency: reportOnyx?.currency, - unheldTotal: reportOnyx?.unheldTotal, - participants: reportOnyx?.participants, - isWaitingOnBankAccount: reportOnyx?.isWaitingOnBankAccount, - iouReportID: reportOnyx?.iouReportID, - isOwnPolicyExpenseChat: reportOnyx?.isOwnPolicyExpenseChat, - isPinned: reportOnyx?.isPinned, - chatReportID: reportOnyx?.chatReportID, - visibility: reportOnyx?.visibility, - oldPolicyName: reportOnyx?.oldPolicyName, - policyName: reportOnyx?.policyName, + lastReadTime: reportOnyx.lastReadTime, + reportID: reportOnyx.reportID, + policyID: reportOnyx.policyID, + lastVisibleActionCreated: reportOnyx.lastVisibleActionCreated, + statusNum: reportOnyx.statusNum, + stateNum: reportOnyx.stateNum, + writeCapability: reportOnyx.writeCapability, + type: reportOnyx.type, + errorFields: reportOnyx.errorFields, + isPolicyExpenseChat: reportOnyx.isPolicyExpenseChat, + parentReportID: reportOnyx.parentReportID, + parentReportActionID: reportOnyx.parentReportActionID, + chatType: reportOnyx.chatType, + pendingFields: reportOnyx.pendingFields, + isDeletedParentAction: reportOnyx.isDeletedParentAction, + reportName: reportOnyx.reportName, + description: reportOnyx.description, + managerID: reportOnyx.managerID, + total: reportOnyx.total, + nonReimbursableTotal: reportOnyx.nonReimbursableTotal, + fieldList: reportOnyx.fieldList, + ownerAccountID: reportOnyx.ownerAccountID, + currency: reportOnyx.currency, + unheldTotal: reportOnyx.unheldTotal, + participants: reportOnyx.participants, + isWaitingOnBankAccount: reportOnyx.isWaitingOnBankAccount, + iouReportID: reportOnyx.iouReportID, + isOwnPolicyExpenseChat: reportOnyx.isOwnPolicyExpenseChat, + isPinned: reportOnyx.isPinned, + chatReportID: reportOnyx.chatReportID, + visibility: reportOnyx.visibility, + oldPolicyName: reportOnyx.oldPolicyName, + policyName: reportOnyx.policyName, // eslint-disable-next-line @typescript-eslint/naming-convention - private_isArchived: reportOnyx?.private_isArchived, - isOptimisticReport: reportOnyx?.isOptimisticReport, - lastMentionedTime: reportOnyx?.lastMentionedTime, - avatarUrl: reportOnyx?.avatarUrl, + private_isArchived: reportOnyx.private_isArchived, + isOptimisticReport: reportOnyx.isOptimisticReport, + lastMentionedTime: reportOnyx.lastMentionedTime, + avatarUrl: reportOnyx.avatarUrl, permissions, - invoiceReceiver: reportOnyx?.invoiceReceiver, - policyAvatar: reportOnyx?.policyAvatar, + invoiceReceiver: reportOnyx.invoiceReceiver, + policyAvatar: reportOnyx.policyAvatar, }, [reportOnyx, permissions], ); @@ -452,15 +452,17 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(accountManagerReportID ?? '')); }, [accountManagerReportID]); + const reportID = report?.reportID; + // Clear notifications for the current report when it's opened and re-focused const clearNotifications = useCallback(() => { // Check if this is the top-most ReportScreen since the Navigator preserves multiple at a time - if (!isTopMostReportId || !report?.reportID) { + if (!isTopMostReportId || !reportID) { return; } - clearReportNotifications(report?.reportID); - }, [report?.reportID, isTopMostReportId]); + clearReportNotifications(reportID); + }, [reportID, isTopMostReportId]); useEffect(clearNotifications, [clearNotifications]); useAppFocusEvent(clearNotifications); From 1ad06b58ca523146dc682a10dd31f2c55a6b2c8c Mon Sep 17 00:00:00 2001 From: daledah Date: Fri, 13 Sep 2024 04:05:22 +0700 Subject: [PATCH 030/104] fix: remove changed in comments --- src/pages/home/ReportScreen.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 5a07f89af24c..e1edddf0277b 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -381,7 +381,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return false; } - // If we just finished loading the app, we still need to try fetching the report?. Wait until that's done before + // If we just finished loading the app, we still need to try fetching the report. Wait until that's done before // showing the Not Found page if (finishedLoadingApp) { return false; @@ -427,7 +427,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro /** * Since OpenReport is a write, the response from OpenReport will get dropped while the app is - * still loading. This usually happens when signing in and deeplinking to a report?. Instead, + * still loading. This usually happens when signing in and deeplinking to a report. Instead, * we'll fetch the report after the app finishes loading. * * This needs to be a strict equality check since isLoadingApp is initially undefined until the @@ -501,7 +501,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } - // This function is triggered when a user clicks on a link to navigate to a report?. + // This function is triggered when a user clicks on a link to navigate to a report. // For each link click, we retrieve the report data again, even though it may already be cached. // There should be only one openReport execution per page start or navigating fetchReportIfNeeded(); From b47cf207fce23b9792a1dd72aabd9f4595ae40bd Mon Sep 17 00:00:00 2001 From: hurali97 Date: Fri, 13 Sep 2024 15:39:49 +0500 Subject: [PATCH 031/104] chore: build actions --- .../actions/javascript/bumpVersion/index.js | 61 +++++-------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/.github/actions/javascript/bumpVersion/index.js b/.github/actions/javascript/bumpVersion/index.js index c8360931845a..43bd09558c26 100644 --- a/.github/actions/javascript/bumpVersion/index.js +++ b/.github/actions/javascript/bumpVersion/index.js @@ -1928,7 +1928,7 @@ class SemVer { do { const a = this.build[i] const b = other.build[i] - debug('build compare', i, a, b) + debug('prerelease compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { @@ -2154,10 +2154,6 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16 -// Max safe length for a build identifier. The max length minus 6 characters for -// the shortest version with a build 0.0.0+BUILD. -const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 - const RELEASE_TYPES = [ 'major', 'premajor', @@ -2171,7 +2167,6 @@ const RELEASE_TYPES = [ module.exports = { MAX_LENGTH, MAX_SAFE_COMPONENT_LENGTH, - MAX_SAFE_BUILD_LENGTH, MAX_SAFE_INTEGER, RELEASE_TYPES, SEMVER_SPEC_VERSION, @@ -2253,11 +2248,7 @@ module.exports = parseOptions /***/ 9523: /***/ ((module, exports, __nccwpck_require__) => { -const { - MAX_SAFE_COMPONENT_LENGTH, - MAX_SAFE_BUILD_LENGTH, - MAX_LENGTH, -} = __nccwpck_require__(2293) +const { MAX_SAFE_COMPONENT_LENGTH } = __nccwpck_require__(2293) const debug = __nccwpck_require__(427) exports = module.exports = {} @@ -2268,31 +2259,16 @@ const src = exports.src = [] const t = exports.t = {} let R = 0 -const LETTERDASHNUMBER = '[a-zA-Z0-9-]' - -// Replace some greedy regex tokens to prevent regex dos issues. These regex are -// used internally via the safeRe object since all inputs in this library get -// normalized first to trim and collapse all extra whitespace. The original -// regexes are exported for userland consumption and lower level usage. A -// future breaking change could export the safer regex only with a note that -// all input should have extra whitespace removed. -const safeRegexReplacements = [ - ['\\s', 1], - ['\\d', MAX_LENGTH], - [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], -] - -const makeSafeRegex = (value) => { - for (const [token, max] of safeRegexReplacements) { - value = value - .split(`${token}*`).join(`${token}{0,${max}}`) - .split(`${token}+`).join(`${token}{1,${max}}`) - } - return value -} - const createToken = (name, value, isGlobal) => { - const safe = makeSafeRegex(value) + // Replace all greedy whitespace to prevent regex dos issues. These regex are + // used internally via the safeRe object since all inputs in this library get + // normalized first to trim and collapse all extra whitespace. The original + // regexes are exported for userland consumption and lower level usage. A + // future breaking change could export the safer regex only with a note that + // all input should have extra whitespace removed. + const safe = value + .split('\\s*').join('\\s{0,1}') + .split('\\s+').join('\\s') const index = R++ debug(name, index, value) t[name] = index @@ -2308,13 +2284,13 @@ const createToken = (name, value, isGlobal) => { // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') -createToken('NUMERICIDENTIFIERLOOSE', '\\d+') +createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. -createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) +createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') // ## Main Version // Three dot-separated numeric identifiers. @@ -2349,7 +2325,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. -createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) +createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -2409,17 +2385,12 @@ createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) // Coercion. // Extract anything that could conceivably be a part of a valid semver -createToken('COERCEPLAIN', `${'(^|[^\\d])' + +createToken('COERCE', `${'(^|[^\\d])' + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) -createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) -createToken('COERCEFULL', src[t.COERCEPLAIN] + - `(?:${src[t.PRERELEASE]})?` + - `(?:${src[t.BUILD]})?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + `(?:$|[^\\d])`) createToken('COERCERTL', src[t.COERCE], true) -createToken('COERCERTLFULL', src[t.COERCEFULL], true) // Tilde ranges. // Meaning is "reasonably at or greater than" From 57a13f249924dc172122497e7e54f64456e5de26 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Fri, 13 Sep 2024 12:55:59 +0200 Subject: [PATCH 032/104] review fixes --- src/CONST.ts | 2 +- src/libs/PolicyUtils.ts | 7 +++-- src/libs/actions/Policy/Category.ts | 4 +-- src/libs/actions/Policy/Policy.ts | 26 +++++++++---------- src/libs/actions/Policy/Tag.ts | 2 +- .../categories/CategorySettingsPage.tsx | 4 +-- .../rules/ExpenseReportRulesSection.tsx | 12 ++++----- .../workspace/rules/RulesCustomNamePage.tsx | 2 +- src/pages/workspace/tags/TagSettingsPage.tsx | 2 +- 9 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 5a6a7ba30564..91b9b7579c90 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2149,7 +2149,7 @@ const CONST = { FIELDS: { TAG: 'tag', CATEGORY: 'category', - TITLE: 'text_title', + FIELD_LIST_TITLE: 'text_title', TAX: 'tax', }, DEFAULT_REPORT_NAME_PATTERN: '{report:type} {report:startdate}', diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 9c322a62b785..4b18fd8a593f 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -991,7 +991,10 @@ function getTagApproverRule(policyID: string, tagName: string) { type PolicyFieldUpdateKeyField = ValueOf; -function getPolicyFieldUpdateKey(fieldValue: string, fieldName: PolicyFieldUpdateKeyField) { +/** + * Get a key for a pending rule field update - we want to differentiate specific field updates to gray out only desired sections + */ +function getKeyForPendingRuleUpdate(fieldValue: string, fieldName: PolicyFieldUpdateKeyField) { return `${fieldName}_${fieldValue}`; } @@ -1116,7 +1119,7 @@ export { getTagApproverRule, getDomainNameForPolicy, getWorkflowApprovalsUnavailable, - getPolicyFieldUpdateKey, + getKeyForPendingRuleUpdate, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index f34cdf5b57df..695a2c9b9f8b 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1153,7 +1153,7 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro const approvalRules = policy?.rules?.approvalRules ?? []; let updatedApprovalRules: ApprovalRule[] = lodashCloneDeep(approvalRules); const existingCategoryApproverRule = CategoryUtils.getCategoryApproverRule(updatedApprovalRules, categoryName); - const categoryRuleUpdateKey = PolicyUtils.getPolicyFieldUpdateKey(categoryName, CONST.POLICY.FIELDS.CATEGORY); + const categoryRuleUpdateKey = PolicyUtils.getKeyForPendingRuleUpdate(categoryName, CONST.POLICY.FIELDS.CATEGORY); let newApprover = approver; @@ -1238,7 +1238,7 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str const expenseRules = policy?.rules?.expenseRules ?? []; const updatedExpenseRules: ExpenseRule[] = lodashCloneDeep(expenseRules); const existingCategoryExpenseRule = updatedExpenseRules.find((rule) => rule.applyWhen.some((when) => when.value === categoryName)); - const categoryRuleUpdateKey = PolicyUtils.getPolicyFieldUpdateKey(categoryName, CONST.POLICY.FIELDS.TAX); + const categoryRuleUpdateKey = PolicyUtils.getKeyForPendingRuleUpdate(categoryName, CONST.POLICY.FIELDS.TAX); if (!existingCategoryExpenseRule) { updatedExpenseRules.push({ diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index eca47005857e..f99d37b43941 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -3891,8 +3891,8 @@ function enablePolicyDefaultReportTitle(policyID: string, enabled: boolean) { return; } - const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE] ?? {}; - const titleFieldValues = enabled ? {} : {fieldList: {[CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN}}}; + const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.FIELD_LIST_TITLE] ?? {}; + const titleFieldValues = enabled ? {} : {fieldList: {[CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {...previousReportTitleField, defaultValue: CONST.POLICY.DEFAULT_REPORT_NAME_PATTERN}}}; const optimisticData: OnyxUpdate[] = [ { @@ -3928,7 +3928,7 @@ function enablePolicyDefaultReportTitle(policyID: string, enabled: boolean) { value: { shouldShowCustomReportTitleOption: !!policy?.shouldShowCustomReportTitleOption, fieldList: { - [CONST.POLICY.FIELDS.TITLE]: previousReportTitleField, + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: previousReportTitleField, }, pendingFields: { shouldShowCustomReportTitleOption: null, @@ -3960,11 +3960,11 @@ function enablePolicyDefaultReportTitle(policyID: string, enabled: boolean) { function setPolicyDefaultReportTitle(policyID: string, customName: string) { const policy = getPolicy(policyID); - if (customName === policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE]?.defaultValue) { + if (customName === policy?.fieldList?.[CONST.POLICY.FIELDS.FIELD_LIST_TITLE]?.defaultValue) { return; } - const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE] ?? {}; + const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.FIELD_LIST_TITLE] ?? {}; const optimisticData: OnyxUpdate[] = [ { @@ -3972,7 +3972,7 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELDS.TITLE]: { + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: { defaultValue: customName, pendingFields: {defaultValue: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, @@ -3987,7 +3987,7 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELDS.TITLE]: {pendingFields: {defaultValue: null}}, + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {pendingFields: {defaultValue: null}}, }, errorFields: null, }, @@ -4000,7 +4000,7 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, pendingFields: {defaultValue: null}}, + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {...previousReportTitleField, pendingFields: {defaultValue: null}}, }, errorFields: { fieldList: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), @@ -4029,11 +4029,11 @@ function setPolicyDefaultReportTitle(policyID: string, customName: string) { function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) { const policy = getPolicy(policyID); - if (!enforced === policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE].deletable) { + if (!enforced === policy?.fieldList?.[CONST.POLICY.FIELDS.FIELD_LIST_TITLE].deletable) { return; } - const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE] ?? {}; + const previousReportTitleField = policy?.fieldList?.[CONST.POLICY.FIELDS.FIELD_LIST_TITLE] ?? {}; const optimisticData: OnyxUpdate[] = [ { @@ -4041,7 +4041,7 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, deletable: !enforced, pendingFields: {deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}, + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {...previousReportTitleField, deletable: !enforced, pendingFields: {deletable: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}}, }, }, }, @@ -4053,7 +4053,7 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELDS.TITLE]: {pendingFields: {deletable: null}}, + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {pendingFields: {deletable: null}}, }, errorFields: null, }, @@ -4066,7 +4066,7 @@ function setPolicyPreventMemberCreatedTitle(policyID: string, enforced: boolean) key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { fieldList: { - [CONST.POLICY.FIELDS.TITLE]: {...previousReportTitleField, pendingFields: {deletable: null}}, + [CONST.POLICY.FIELDS.FIELD_LIST_TITLE]: {...previousReportTitleField, pendingFields: {deletable: null}}, }, errorFields: { fieldList: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index f6ed865d1695..8f4db840476c 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -853,7 +853,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { const approverRuleToUpdate = PolicyUtils.getTagApproverRule(policyID, tag); const filteredApprovalRules = approverRuleToUpdate ? prevApprovalRules.filter((rule) => rule.id !== approverRuleToUpdate.id) : prevApprovalRules; const toBeUnselected = approverRuleToUpdate?.approver === approver; - const tagRuleUpdateKey = PolicyUtils.getPolicyFieldUpdateKey(tag, CONST.POLICY.FIELDS.TAG); + const tagRuleUpdateKey = PolicyUtils.getKeyForPendingRuleUpdate(tag, CONST.POLICY.FIELDS.TAG); const updatedApproverRule = approverRuleToUpdate ? {...approverRuleToUpdate, approver} diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 6e939dc18351..02115c47d8b7 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -261,7 +261,7 @@ function CategorySettingsPage({ )} Navigation.navigate(ROUTES.RULES_CUSTOM_NAME.getRoute(policyID))} @@ -70,8 +70,8 @@ function ExpenseReportRulesSection({policyID}: ExpenseReportRulesSectionProps) { , PolicyActions.setPolicyPreventMemberCreatedTitle(policyID, isEnabled)} />, ], diff --git a/src/pages/workspace/rules/RulesCustomNamePage.tsx b/src/pages/workspace/rules/RulesCustomNamePage.tsx index 738ac2e0cf3e..42f0ab1e5047 100644 --- a/src/pages/workspace/rules/RulesCustomNamePage.tsx +++ b/src/pages/workspace/rules/RulesCustomNamePage.tsx @@ -39,7 +39,7 @@ function RulesCustomNamePage({route}: RulesCustomNamePageProps) { translate('workspace.rules.expenseReportRules.customNameTotalExample'), ] as const satisfies string[]; - const customNameDefaultValue = policy?.fieldList?.[CONST.POLICY.FIELDS.TITLE].defaultValue; + const customNameDefaultValue = policy?.fieldList?.[CONST.POLICY.FIELDS.FIELD_LIST_TITLE].defaultValue; const validateCustomName = ({customName}: FormOnyxValues) => { const errors: FormInputErrors = {}; diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index fd4c20e8437e..fd2b39b14f9f 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -161,7 +161,7 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) {translate('workspace.tags.tagRules')} - + Date: Sun, 15 Sep 2024 18:40:32 +0530 Subject: [PATCH 033/104] Fix lint --- .../export/SageIntacctNonReimbursableExpensesPage.tsx | 2 +- .../intacct/export/SageIntacctReimbursableExpensesPage.tsx | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index a6a175098812..a3eae2ad8aaa 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -19,7 +19,7 @@ import {getDefaultVendorName} from './utils'; type MenuItemWithSubscribedSettings = Pick & {subscribedSettings?: string[]}; -function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyProps) { +function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; const styles = useThemeStyles(); diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx index d09b63915402..bbe90414309a 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesPage.tsx @@ -15,14 +15,10 @@ import {updateSageIntacctDefaultVendor} from '@userActions/connections/SageIntac import * as Policy from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; -import type {SageIntacctDataElementWithValue} from '@src/types/onyx/Policy'; +import {getDefaultVendorName} from './utils'; type MenuItemWithSubscribedSettings = Pick & {subscribedSettings?: string[]}; -function getDefaultVendorName(defaultVendor?: string, vendors?: SageIntacctDataElementWithValue[]): string | undefined { - return (vendors ?? []).find((vendor) => vendor.id === defaultVendor)?.value ?? defaultVendor; -} - function SageIntacctReimbursableExpensesPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; From 6aaea8cc219daa4b40063a9961b7c2ca7754f2c2 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Sun, 15 Sep 2024 19:14:15 +0530 Subject: [PATCH 034/104] Fix duplicating options --- .../export/SageIntacctNonReimbursableExpensesPage.tsx | 6 ++++-- .../intacct/export/SageIntacctReimbursableExpensesPage.tsx | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index a3eae2ad8aaa..a248bbfcb481 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -19,6 +19,8 @@ import {getDefaultVendorName} from './utils'; type MenuItemWithSubscribedSettings = Pick & {subscribedSettings?: string[]}; +type ToggleItemWithKey = ToggleItem & {key: string}; + function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; @@ -28,7 +30,7 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsP const activeDefaultVendor = getSageIntacctNonReimbursableActiveDefaultVendor(policy); const defaultVendorName = getDefaultVendorName(activeDefaultVendor, intacctData?.vendors); - const menuItems: Array = [ + const menuItems: Array = [ { type: 'menuitem', title: config?.export.nonReimbursable @@ -53,6 +55,7 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsP { type: 'toggle', title: translate('workspace.sageIntacct.defaultVendor'), + key: 'Default vendor toggle', subtitle: translate('workspace.sageIntacct.defaultVendorDescription', false), isActive: !!config?.export.nonReimbursableCreditCardChargeDefaultVendor, switchAccessibilityLabel: translate('workspace.sageIntacct.defaultVendor'), @@ -105,7 +108,6 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsP const {type, shouldHide, ...rest} = item; return ( & {subscribedSettings?: string[]}; +type ToggleItemWithKey = ToggleItem & {key: string}; + function SageIntacctReimbursableExpensesPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const policyID = policy?.id ?? '-1'; @@ -28,7 +30,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyConnectionsProp const defaultVendorName = getDefaultVendorName(reimbursableExpenseReportDefaultVendor, intacctData?.vendors); - const menuItems: Array = [ + const menuItems: Array = [ { type: 'menuitem', title: reimbursable ? translate(`workspace.sageIntacct.reimbursableExpenses.values.${reimbursable}`) : translate('workspace.sageIntacct.notConfigured'), @@ -41,6 +43,7 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyConnectionsProp { type: 'toggle', title: translate('workspace.sageIntacct.defaultVendor'), + key: 'Default vendor toggle', subtitle: translate('workspace.sageIntacct.defaultVendorDescription', true), isActive: !!config?.export.reimbursableExpenseReportDefaultVendor, switchAccessibilityLabel: translate('workspace.sageIntacct.defaultVendor'), @@ -87,7 +90,6 @@ function SageIntacctReimbursableExpensesPage({policy}: WithPolicyConnectionsProp const {type, shouldHide, ...rest} = item; return ( Date: Mon, 16 Sep 2024 19:08:48 +0700 Subject: [PATCH 035/104] fix approve report partially shows wrong owes amount --- src/components/LHNOptionsList/LHNOptionsList.tsx | 4 +++- src/components/LHNOptionsList/OptionRowLHNData.tsx | 3 +++ src/components/LHNOptionsList/types.ts | 3 +++ src/libs/OptionsListUtils.ts | 10 +++++----- src/libs/SidebarUtils.ts | 4 +++- src/libs/actions/IOU.ts | 4 +++- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 624e8f18e69e..bad7fec04831 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -132,6 +132,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const iouReportIDOfLastAction = OptionsListUtils.getIOUReportIDOfLastAction(itemFullReport); const itemIouReportReportActions = iouReportIDOfLastAction ? reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportIDOfLastAction}`] : undefined; + const itemIouReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportIDOfLastAction}`]; const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`]; const transactionID = ReportActionsUtils.isMoneyRequestAction(itemParentReportAction) @@ -162,7 +163,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio } : null; } - const lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(itemFullReport, lastActorDetails, itemPolicy); + const lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(itemFullReport, itemIouReport, lastActorDetails, itemPolicy); return ( ; + /** IOU report related to the last action of this report */ + iouReport: OnyxEntry; + /** List of transaction violation */ transactionViolations: OnyxCollection; diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index f191c1d06532..fb6928056249 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -588,7 +588,7 @@ function getIOUReportIDOfLastAction(report: OnyxEntry): string | undefin /** * Get the last message text from the report directly or from other sources for special cases. */ -function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails: Partial | null, policy?: OnyxEntry): string { +function getLastMessageTextForReport(report: OnyxEntry, iouReport: OnyxEntry, lastActorDetails: Partial | null, policy?: OnyxEntry): string { const reportID = report?.reportID ?? '-1'; const lastReportAction = lastVisibleReportActions[reportID] ?? null; @@ -623,15 +623,15 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails const properSchemaForMoneyRequestMessage = ReportUtils.getReportPreviewMessage(report, lastReportAction, true, false, null, true); lastMessageTextFromReport = ReportUtils.formatReportLastMessageText(properSchemaForMoneyRequestMessage); } else if (ReportActionUtils.isReportPreviewAction(lastReportAction)) { - const iouReport = ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); - const lastIOUMoneyReportAction = allSortedReportActions[iouReport?.reportID ?? '-1']?.find( + const iouReportValue = iouReport ?? ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); + const lastIOUMoneyReportAction = allSortedReportActions[iouReportValue?.reportID ?? '-1']?.find( (reportAction, key): reportAction is ReportAction => ReportActionUtils.shouldReportActionBeVisible(reportAction, key) && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && ReportActionUtils.isMoneyRequestAction(reportAction), ); const reportPreviewMessage = ReportUtils.getReportPreviewMessage( - !isEmptyObject(iouReport) ? iouReport : null, + !isEmptyObject(iouReportValue) ? iouReportValue : null, lastIOUMoneyReportAction, true, ReportUtils.isChatReport(report), @@ -766,7 +766,7 @@ function createOption( const lastActorDetails = personalDetailMap[report.lastActorAccountID ?? -1] ?? null; const lastActorDisplayName = getLastActorDisplayName(lastActorDetails, hasMultipleParticipants); - const lastMessageTextFromReport = getLastMessageTextForReport(report, lastActorDetails); + const lastMessageTextFromReport = getLastMessageTextForReport(report, undefined, lastActorDetails); let lastMessageText = lastMessageTextFromReport; const lastAction = lastVisibleReportActions[report.reportID]; diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 4bd7e2714e25..0cc139685b08 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -234,6 +234,7 @@ function getOrderedReportIDs( */ function getOptionData({ report, + iouReport, reportActions, personalDetails, preferredLocale, @@ -245,6 +246,7 @@ function getOptionData({ invoiceReceiverPolicy, }: { report: OnyxEntry; + iouReport: OnyxEntry; reportActions: OnyxEntry; personalDetails: OnyxEntry; preferredLocale: DeepValueOf; @@ -389,7 +391,7 @@ function getOptionData({ let lastMessageTextFromReport = lastMessageTextFromReportProp; if (!lastMessageTextFromReport) { - lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(report, lastActorDetails, policy); + lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(report, iouReport, lastActorDetails, policy); } // We need to remove sms domain in case the last message text has a phone number mention with sms domain. diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index b0d025e0768f..30d20a0a63db 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6440,11 +6440,12 @@ function getReportFromHoldRequestsOnyxData( const firstHoldTransaction = holdTransactions[0]; const newParentReportActionID = rand64(); + const holdTotal = iouReport.total && iouReport.unheldTotal ? iouReport.total - iouReport.unheldTotal : 0; const optimisticExpenseReport = ReportUtils.buildOptimisticExpenseReport( chatReport.reportID, chatReport.policyID ?? iouReport.policyID ?? '', recipient.accountID ?? 1, - (firstHoldTransaction?.amount ?? 0) * -1, + holdTotal * -1, getCurrency(firstHoldTransaction), false, newParentReportActionID, @@ -7044,6 +7045,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.reportID}`, value: { ...expenseReport, + total, lastMessageText: ReportActionsUtils.getReportActionText(optimisticApprovedReportAction), lastMessageHtml: ReportActionsUtils.getReportActionHtml(optimisticApprovedReportAction), stateNum: predictedNextState, From f19136f3f89157eb8033e7d855196673cfb1ee10 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Mon, 16 Sep 2024 22:30:41 +0700 Subject: [PATCH 036/104] optimistically update the iou report total --- src/libs/actions/IOU.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 30d20a0a63db..3f91d2f62f1c 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6742,6 +6742,7 @@ function getPayMoneyRequestParams( key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, value: { ...iouReport, + total, lastMessageText: ReportActionsUtils.getReportActionText(optimisticIOUReportAction), lastMessageHtml: ReportActionsUtils.getReportActionHtml(optimisticIOUReportAction), hasOutstandingChildRequest: false, From e48b7447f08665f9977520801486a08fb5509ec3 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Mon, 16 Sep 2024 22:42:11 +0700 Subject: [PATCH 037/104] add missing param --- tests/perf-test/SidebarUtils.perf-test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/perf-test/SidebarUtils.perf-test.ts b/tests/perf-test/SidebarUtils.perf-test.ts index 4a6b12d726d9..47595b207277 100644 --- a/tests/perf-test/SidebarUtils.perf-test.ts +++ b/tests/perf-test/SidebarUtils.perf-test.ts @@ -102,6 +102,7 @@ describe('SidebarUtils', () => { await measureFunction(() => SidebarUtils.getOptionData({ report, + iouReport: undefined, reportActions, personalDetails, preferredLocale, From 05bbb0d5271c54a8dda75625e4670bf3f907d219 Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 17 Sep 2024 11:22:48 +0700 Subject: [PATCH 038/104] fix scroll issue --- src/components/FocusTrap/WIDE_LAYOUT_INACTIVE_SCREENS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/FocusTrap/WIDE_LAYOUT_INACTIVE_SCREENS.ts b/src/components/FocusTrap/WIDE_LAYOUT_INACTIVE_SCREENS.ts index 686c318a99dc..3d1fcf6fe54c 100644 --- a/src/components/FocusTrap/WIDE_LAYOUT_INACTIVE_SCREENS.ts +++ b/src/components/FocusTrap/WIDE_LAYOUT_INACTIVE_SCREENS.ts @@ -38,6 +38,7 @@ const WIDE_LAYOUT_INACTIVE_SCREENS: string[] = [ SCREENS.SEARCH.CENTRAL_PANE, SCREENS.SETTINGS.TROUBLESHOOT, SCREENS.SETTINGS.SAVE_THE_WORLD, + SCREENS.WORKSPACE.RULES, ]; export default WIDE_LAYOUT_INACTIVE_SCREENS; From 45ae762736a3852341eb06275508b41a1fe6c750 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Tue, 17 Sep 2024 03:08:25 -0400 Subject: [PATCH 039/104] fix lint --- src/libs/ReportUtils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a92c89479c74..c75d6a8e1dd4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1536,8 +1536,8 @@ function isChildReport(report: OnyxEntry): boolean { * the parentReportAction is a transaction. */ function isExpenseRequest(report: OnyxInputOrEntry): boolean { - if (isThread(report)) { - const parentReportAction = ReportActionsUtils.getParentReportAction(report); + if (isThread(report) && report?.parentReportID && report.parentReportActionID) { + const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isExpenseReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); } @@ -1549,8 +1549,8 @@ function isExpenseRequest(report: OnyxInputOrEntry): boolean { * the parentReportAction is a transaction. */ function isIOURequest(report: OnyxInputOrEntry): boolean { - if (isThread(report)) { - const parentReportAction = ReportActionsUtils.getParentReportAction(report); + if (isThread(report) && report?.parentReportID && report.parentReportActionID) { + const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isIOUReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); } From bfaa8d6aef7ff446b34f6bc5e2b76fa99731e413 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Tue, 17 Sep 2024 03:14:57 -0400 Subject: [PATCH 040/104] more lint changes --- src/libs/ReportUtils.ts | 21 ++++++++++++--------- src/libs/actions/IOU.ts | 4 +++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index c75d6a8e1dd4..a8e6bd02a8cf 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1562,8 +1562,8 @@ function isIOURequest(report: OnyxInputOrEntry): boolean { * parentReportAction has type of track. */ function isTrackExpenseReport(report: OnyxInputOrEntry): boolean { - if (isThread(report)) { - const parentReportAction = ReportActionsUtils.getParentReportAction(report); + if (isThread(report) && report?.parentReportID && report.parentReportActionID) { + const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; return !isEmptyObject(parentReportAction) && ReportActionsUtils.isTrackExpenseAction(parentReportAction); } return false; @@ -2211,8 +2211,8 @@ function getIcons( }; return [fallbackIcon]; } - if (isExpenseRequest(report)) { - const parentReportAction = ReportActionsUtils.getParentReportAction(report); + if (isExpenseRequest(report) && report?.parentReportID && report.parentReportActionID) { + const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const workspaceIcon = getWorkspaceIcon(report, policy); const memberIcon = { source: personalDetails?.[parentReportAction?.actorAccountID ?? -1]?.avatar ?? FallbackAvatar, @@ -2224,8 +2224,8 @@ function getIcons( return [memberIcon, workspaceIcon]; } - if (isChatThread(report)) { - const parentReportAction = ReportActionsUtils.getParentReportAction(report); + if (isChatThread(report) && report?.parentReportID && report.parentReportActionID) { + const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const actorAccountID = getReportActionActorAccountID(parentReportAction, report); const actorDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(allPersonalDetails?.[actorAccountID ?? -1], '', false); @@ -3106,7 +3106,7 @@ function canHoldUnholdReportAction(reportAction: OnyxInputOrEntry) const transactionID = moneyRequestReport ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUTransactionID : 0; const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction); - const parentReportAction = ReportActionsUtils.getParentReportAction(moneyRequestReport); + const parentReportAction = report?.parentReportID && report.parentReportActionID ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; const isRequestIOU = isIOUReport(moneyRequestReport); const isHoldActionCreator = isHoldCreator(transaction, reportAction.childReportID ?? '-1'); @@ -3713,7 +3713,10 @@ function getReportName( } let formattedName: string | undefined; - const parentReportAction = parentReportActionParam ?? ReportActionsUtils.getParentReportAction(report); + let parentReportAction: OnyxEntry | undefined; + if (parentReportActionParam) { + parentReportAction = report?.parentReportID && report.parentReportActionID ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; + } const parentReportActionMessage = ReportActionsUtils.getReportActionMessage(parentReportAction); if (parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.SUBMITTED) { @@ -5995,7 +5998,7 @@ function shouldReportBeInOptionList({ // This can also happen for anyone accessing a public room or archived room for which they don't have access to the underlying policy. // Optionally exclude reports that do not belong to currently active workspace - const parentReportAction = ReportActionsUtils.getParentReportAction(report); + const parentReportAction = report?.parentReportID && report.parentReportActionID ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; if ( !report?.reportID || diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index b0d025e0768f..4620be236a9f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2046,7 +2046,9 @@ function getMoneyRequestInformation( // STEP 2: Get the Expense/IOU report. If the moneyRequestReportID has been provided, we want to add the transaction to this specific report. // If no such reportID has been provided, let's use the chatReport.iouReportID property. In case that is not present, build a new optimistic Expense/IOU report. let iouReport: OnyxInputValue = null; - if (moneyRequestReportID) { + if (policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO) { + iouReport = null; + } else if (moneyRequestReportID) { iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReportID}`] ?? null; } else { iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`] ?? null; From a98a93f6b0e733eca5a838b1055c1785c28ddf13 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Tue, 17 Sep 2024 03:19:23 -0400 Subject: [PATCH 041/104] remove uneeded --- src/libs/actions/IOU.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 4620be236a9f..b0d025e0768f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2046,9 +2046,7 @@ function getMoneyRequestInformation( // STEP 2: Get the Expense/IOU report. If the moneyRequestReportID has been provided, we want to add the transaction to this specific report. // If no such reportID has been provided, let's use the chatReport.iouReportID property. In case that is not present, build a new optimistic Expense/IOU report. let iouReport: OnyxInputValue = null; - if (policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO) { - iouReport = null; - } else if (moneyRequestReportID) { + if (moneyRequestReportID) { iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReportID}`] ?? null; } else { iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`] ?? null; From 0f674a1a229528f687bd7caa3945b7192d28ebf0 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Tue, 17 Sep 2024 03:21:44 -0400 Subject: [PATCH 042/104] prettier --- src/libs/ReportUtils.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a8e6bd02a8cf..eb86e53ff21e 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3106,7 +3106,10 @@ function canHoldUnholdReportAction(reportAction: OnyxInputOrEntry) const transactionID = moneyRequestReport ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUTransactionID : 0; const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction); - const parentReportAction = report?.parentReportID && report.parentReportActionID ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; + const parentReportAction = + report?.parentReportID && report.parentReportActionID + ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] + : undefined; const isRequestIOU = isIOUReport(moneyRequestReport); const isHoldActionCreator = isHoldCreator(transaction, reportAction.childReportID ?? '-1'); @@ -3715,7 +3718,10 @@ function getReportName( let formattedName: string | undefined; let parentReportAction: OnyxEntry | undefined; if (parentReportActionParam) { - parentReportAction = report?.parentReportID && report.parentReportActionID ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; + parentReportAction = + report?.parentReportID && report.parentReportActionID + ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] + : undefined; } const parentReportActionMessage = ReportActionsUtils.getReportActionMessage(parentReportAction); @@ -5998,7 +6004,10 @@ function shouldReportBeInOptionList({ // This can also happen for anyone accessing a public room or archived room for which they don't have access to the underlying policy. // Optionally exclude reports that do not belong to currently active workspace - const parentReportAction = report?.parentReportID && report.parentReportActionID ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; + const parentReportAction = + report?.parentReportID && report.parentReportActionID + ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] + : undefined; if ( !report?.reportID || From 05d474aa78f19a4244365ff05a08a4812b6f7ca3 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Tue, 17 Sep 2024 03:31:04 -0400 Subject: [PATCH 043/104] fix error --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index eb86e53ff21e..f4ad6a00a896 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3107,8 +3107,8 @@ function canHoldUnholdReportAction(reportAction: OnyxInputOrEntry) const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction); const parentReportAction = - report?.parentReportID && report.parentReportActionID - ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] + moneyRequestReport?.parentReportID && moneyRequestReport.parentReportActionID + ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${moneyRequestReport.parentReportID}`]?.[moneyRequestReport.parentReportActionID] : undefined; const isRequestIOU = isIOUReport(moneyRequestReport); From 2643e894957c7cb21d7ed1e8f64f916cd6d9400a Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 17 Sep 2024 22:04:30 +0700 Subject: [PATCH 044/104] display downlaod failure modal --- src/libs/Permissions.ts | 2 +- src/libs/actions/Policy/Category.ts | 4 +-- src/libs/fileDownload/DownloadUtils.ts | 8 +++++- src/libs/fileDownload/index.desktop.ts | 4 +-- .../categories/WorkspaceCategoriesPage.tsx | 25 +++++++++++++++---- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 8c47100e465b..8b7d92701a55 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -4,7 +4,7 @@ import type {IOUType} from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; function canUseAllBetas(betas: OnyxEntry): boolean { - return !!betas?.includes(CONST.BETAS.ALL); + return true; } function canUseDefaultRooms(betas: OnyxEntry): boolean { diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 5716eed8947d..f7685b444e69 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1001,7 +1001,7 @@ function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUn API.write(WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); } -function downloadCategoriesCSV(policyID: string) { +function downloadCategoriesCSV(policyID: string, onDownloadFailed?: () => void) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_CATEGORIES_CSV, { policyID, }); @@ -1011,7 +1011,7 @@ function downloadCategoriesCSV(policyID: string) { formData.append(key, String(value)); }); - fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_CATEGORIES_CSV}), 'Categories.csv', '', false, formData, CONST.NETWORK.METHOD.POST); + fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_CATEGORIES_CSV}), 'Categories.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function setWorkspaceCategoryDescriptionHint(policyID: string, categoryName: string, commentHint: string) { diff --git a/src/libs/fileDownload/DownloadUtils.ts b/src/libs/fileDownload/DownloadUtils.ts index a09b0aa38c75..4f0ce6ab0c92 100644 --- a/src/libs/fileDownload/DownloadUtils.ts +++ b/src/libs/fileDownload/DownloadUtils.ts @@ -53,7 +53,13 @@ const fetchFileDownload: FileDownload = (url, fileName, successMessage = '', sho }; return fetch(url, fetchOptions) - .then((response) => response.blob()) + .then((response) => { + const contentType = response.headers.get('content-type'); + if (contentType === 'application/json' && fileName?.includes('.csv')) { + throw new Error(); + } + return response.blob(); + }) .then((blob) => { // Create blob link to download const href = URL.createObjectURL(new Blob([blob])); diff --git a/src/libs/fileDownload/index.desktop.ts b/src/libs/fileDownload/index.desktop.ts index de000f61b41b..6a601a4af249 100644 --- a/src/libs/fileDownload/index.desktop.ts +++ b/src/libs/fileDownload/index.desktop.ts @@ -7,10 +7,10 @@ import type {FileDownload} from './types'; /** * The function downloads an attachment on desktop platforms. */ -const fileDownload: FileDownload = (url, fileName, successMessage, shouldOpenExternalLink, formData, requestType) => { +const fileDownload: FileDownload = (url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed?: () => void) => { if (requestType === CONST.NETWORK.METHOD.POST) { window.electron.send(ELECTRON_EVENTS.DOWNLOAD); - return fetchFileDownload(url, fileName, successMessage, shouldOpenExternalLink, formData, requestType); + return fetchFileDownload(url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed); } const options: Options = { diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index 267b8ec52019..11dd49d0befb 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -8,6 +8,7 @@ import Button from '@components/Button'; import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu'; import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; import ConfirmModal from '@components/ConfirmModal'; +import DecisionModal from '@components/DecisionModal'; import EmptyStateComponent from '@components/EmptyStateComponent'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -54,13 +55,14 @@ type PolicyOption = ListItem & { type WorkspaceCategoriesPageProps = StackScreenProps; function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { - const {shouldUseNarrowLayout} = useResponsiveLayout(); + const {shouldUseNarrowLayout, isSmallScreenWidth} = useResponsiveLayout(); const {windowWidth} = useWindowDimensions(); const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); const [isOfflineModalVisible, setIsOfflineModalVisible] = useState(false); const [selectedCategories, setSelectedCategories] = useState>({}); + const [downloadFailureModalVisible, setDownloadFailureModalVisible] = useState(false); const [deleteCategoriesConfirmModalVisible, setDeleteCategoriesConfirmModalVisible] = useState(false); const isFocused = useIsFocused(); const {environmentURL} = useEnvironment(); @@ -308,7 +310,9 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { Navigation.navigate(ROUTES.WORKSPACE_CATEGORIES_IMPORT.getRoute(policyId)); }, }, - { + ]; + if (hasVisibleCategories) { + menuItems.push({ icon: Expensicons.Download, text: translate('spreadsheet.downloadCSV'), onSelected: () => { @@ -316,10 +320,12 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { Modal.close(() => setIsOfflineModalVisible(true)); return; } - Category.downloadCategoriesCSV(policyId); + Category.downloadCategoriesCSV(policyId, () => { + setDownloadFailureModalVisible(true); + }); }, - }, - ]; + }); + } return menuItems; }, [policyId, translate, isOffline]); @@ -415,6 +421,15 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { confirmText={translate('common.buttonConfirm')} shouldShowCancelButton={false} /> + setDownloadFailureModalVisible(false)} + secondOptionText={translate('common.buttonConfirm')} + isVisible={downloadFailureModalVisible} + onClose={() => setDownloadFailureModalVisible(false)} + /> ); From 175fa24a789559942cbcf6a6facf9ae1babeaa2e Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Tue, 17 Sep 2024 22:10:05 +0700 Subject: [PATCH 045/104] update the lint error --- src/libs/Permissions.ts | 2 +- src/pages/workspace/categories/WorkspaceCategoriesPage.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 8b7d92701a55..8c47100e465b 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -4,7 +4,7 @@ import type {IOUType} from '@src/CONST'; import type Beta from '@src/types/onyx/Beta'; function canUseAllBetas(betas: OnyxEntry): boolean { - return true; + return !!betas?.includes(CONST.BETAS.ALL); } function canUseDefaultRooms(betas: OnyxEntry): boolean { diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index 11dd49d0befb..b6870702d487 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -328,7 +328,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { } return menuItems; - }, [policyId, translate, isOffline]); + }, [policyId, translate, isOffline, hasVisibleCategories]); const selectionModeHeader = selectionMode?.isEnabled && shouldUseNarrowLayout; From fe5f31cd4d0fd5b7ca18ccaa9c98d1b1aca489e0 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 00:50:01 +0200 Subject: [PATCH 046/104] update category rule when renaming category --- src/libs/actions/Policy/Category.ts | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 695a2c9b9f8b..b0b2c10b37e3 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -521,8 +521,28 @@ function importPolicyCategories(policyID: string, categories: PolicyCategory[]) } function renamePolicyCategory(policyID: string, policyCategory: {oldName: string; newName: string}) { + const policy = PolicyUtils.getPolicy(policyID); const policyCategoryToUpdate = allPolicyCategories?.[`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`]?.[policyCategory.oldName]; + const policyCategoryRule = CategoryUtils.getCategoryApproverRule(policy?.rules?.approvalRules ?? [], policyCategory.oldName); + const approvalRules = policy?.rules?.approvalRules ?? []; + const updatedApprovalRules: ApprovalRule[] = lodashCloneDeep(approvalRules); + + // Its related by name, so the corresponding rule has to be updated to handle offline scenario + if (policyCategoryRule) { + const indexToUpdate = updatedApprovalRules.findIndex((rule) => rule.id === policyCategoryRule.id); + policyCategoryRule.applyWhen = policyCategoryRule.applyWhen.map((ruleCondition) => { + const {value, field, condition} = ruleCondition; + + if (value === policyCategory.oldName && field === CONST.POLICY.FIELDS.CATEGORY && condition === CONST.POLICY.RULE_CONDITIONS.MATCHES) { + return {...ruleCondition, value: policyCategory.newName}; + } + + return ruleCondition; + }); + updatedApprovalRules[indexToUpdate] = policyCategoryRule; + } + const onyxData: OnyxData = { optimisticData: [ { @@ -542,6 +562,15 @@ function renamePolicyCategory(policyID: string, policyCategory: {oldName: string }, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + rules: { + approvalRules: updatedApprovalRules, + }, + }, + }, ], successData: [ { @@ -576,6 +605,15 @@ function renamePolicyCategory(policyID: string, policyCategory: {oldName: string }, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + rules: { + approvalRules, + }, + }, + }, ], }; From bc4eed8fe3ee3cddddfc772e45d48768e0898f2a Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 01:19:20 +0200 Subject: [PATCH 047/104] update tag rule when renaming tag --- src/libs/actions/Policy/Tag.ts | 43 +++++++++++++++----- src/pages/workspace/tags/TagSettingsPage.tsx | 2 +- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 8f4db840476c..ba2a06d450b9 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -1,3 +1,4 @@ +import lodashCloneDeep from 'lodash/cloneDeep'; import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; @@ -24,7 +25,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy, PolicyTag, PolicyTagLists, PolicyTags, RecentlyUsedTags, Report} from '@src/types/onyx'; import type {OnyxValueWithOfflineFeedback} from '@src/types/onyx/OnyxCommon'; -import type {Attributes, Rate} from '@src/types/onyx/Policy'; +import type {ApprovalRule, Attributes, Rate} from '@src/types/onyx/Policy'; import type {OnyxData} from '@src/types/onyx/Request'; type NewCustomUnit = { @@ -410,10 +411,31 @@ function clearPolicyTagListErrors(policyID: string, tagListIndex: number) { } function renamePolicyTag(policyID: string, policyTag: {oldName: string; newName: string}, tagListIndex: number) { + const policy = PolicyUtils.getPolicy(policyID); const tagList = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[tagListIndex] ?? {}; const tag = tagList.tags?.[policyTag.oldName]; const oldTagName = policyTag.oldName; const newTagName = PolicyUtils.escapeTagName(policyTag.newName); + + const policyTagRule = PolicyUtils.getTagApproverRule(policyID, oldTagName); + const approvalRules = policy?.rules?.approvalRules ?? []; + const updatedApprovalRules: ApprovalRule[] = lodashCloneDeep(approvalRules); + + // Its related by name, so the corresponding rule has to be updated to handle offline scenario + if (policyTagRule) { + const indexToUpdate = updatedApprovalRules.findIndex((rule) => rule.id === policyTagRule.id); + policyTagRule.applyWhen = policyTagRule.applyWhen.map((ruleCondition) => { + const {value, field, condition} = ruleCondition; + + if (value === policyTag.oldName && field === CONST.POLICY.FIELDS.TAG && condition === CONST.POLICY.RULE_CONDITIONS.MATCHES) { + return {...ruleCondition, value: policyTag.newName}; + } + + return ruleCondition; + }); + updatedApprovalRules[indexToUpdate] = policyTagRule; + } + const onyxData: OnyxData = { optimisticData: [ { @@ -438,6 +460,15 @@ function renamePolicyTag(policyID: string, policyTag: {oldName: string; newName: }, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + rules: { + approvalRules: updatedApprovalRules, + }, + }, + }, ], successData: [ { @@ -896,11 +927,6 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { rules: { approvalRules: updatedApprovalRules, }, - pendingRulesUpdates: { - [tagRuleUpdateKey]: { - approvalRule: null, - }, - }, }, }, ], @@ -912,11 +938,6 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { rules: { approvalRules: prevApprovalRules, }, - pendingRulesUpdates: { - [tagRuleUpdateKey]: { - approvalRule: null, - }, - }, }, }, ], diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index fd2b39b14f9f..3240758f12b5 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -89,7 +89,7 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) const isThereAnyAccountingConnection = Object.keys(policy?.connections ?? {}).length !== 0; const isMultiLevelTags = PolicyUtils.isMultiLevelTags(policyTags); - const tagApprover = PolicyUtils.getTagApproverRule(policyID, currentPolicyTag.name)?.approver; + const tagApprover = PolicyUtils.getTagApproverRule(policyID, route.params.tagName)?.approver; const shouldShowDeleteMenuItem = !isThereAnyAccountingConnection && !isMultiLevelTags; const workflowApprovalsUnavailable = PolicyUtils.getWorkflowApprovalsUnavailable(policy); From 6fc0879a41aa1526b5122b60f84d521b81125e9d Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 01:29:27 +0200 Subject: [PATCH 048/104] remove pending action pattern for rules --- src/libs/PolicyUtils.ts | 10 ---- src/libs/actions/Policy/Category.ts | 51 +------------------ src/libs/actions/Policy/Tag.ts | 6 --- .../categories/CategorySettingsPage.tsx | 42 +++++++-------- src/pages/workspace/tags/TagSettingsPage.tsx | 16 +++--- 5 files changed, 26 insertions(+), 99 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index e5852f44a1c5..0eb656d36631 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -995,15 +995,6 @@ function getTagApproverRule(policyID: string, tagName: string) { return approverRule; } -type PolicyFieldUpdateKeyField = ValueOf; - -/** - * Get a key for a pending rule field update - we want to differentiate specific field updates to gray out only desired sections - */ -function getKeyForPendingRuleUpdate(fieldValue: string, fieldName: PolicyFieldUpdateKeyField) { - return `${fieldName}_${fieldValue}`; -} - function getDomainNameForPolicy(policyID?: string): string { if (!policyID) { return ''; @@ -1126,7 +1117,6 @@ export { getTagApproverRule, getDomainNameForPolicy, getWorkflowApprovalsUnavailable, - getKeyForPendingRuleUpdate, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index b0b2c10b37e3..95f2e8efe115 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1191,7 +1191,6 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro const approvalRules = policy?.rules?.approvalRules ?? []; let updatedApprovalRules: ApprovalRule[] = lodashCloneDeep(approvalRules); const existingCategoryApproverRule = CategoryUtils.getCategoryApproverRule(updatedApprovalRules, categoryName); - const categoryRuleUpdateKey = PolicyUtils.getKeyForPendingRuleUpdate(categoryName, CONST.POLICY.FIELDS.CATEGORY); let newApprover = approver; @@ -1223,27 +1222,10 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro rules: { approvalRules: updatedApprovalRules, }, - pendingRulesUpdates: { - [categoryRuleUpdateKey]: { - approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, - }, - }, - }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - pendingRulesUpdates: { - [categoryRuleUpdateKey]: { - approvalRule: null, - }, - }, }, }, ], + failureData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -1252,11 +1234,6 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro rules: { approvalRules, }, - pendingRulesUpdates: { - [categoryRuleUpdateKey]: { - approvalRule: null, - }, - }, }, }, ], @@ -1272,11 +1249,10 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro } function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: string) { - const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; + const policy = PolicyUtils.getPolicy(policyID); const expenseRules = policy?.rules?.expenseRules ?? []; const updatedExpenseRules: ExpenseRule[] = lodashCloneDeep(expenseRules); const existingCategoryExpenseRule = updatedExpenseRules.find((rule) => rule.applyWhen.some((when) => when.value === categoryName)); - const categoryRuleUpdateKey = PolicyUtils.getKeyForPendingRuleUpdate(categoryName, CONST.POLICY.FIELDS.TAX); if (!existingCategoryExpenseRule) { updatedExpenseRules.push({ @@ -1308,24 +1284,6 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str rules: { expenseRules: updatedExpenseRules, }, - pendingRulesUpdates: { - [categoryRuleUpdateKey]: { - expenseRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, - }, - }, - }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - value: { - pendingRulesUpdates: { - [categoryRuleUpdateKey]: { - expenseRule: null, - }, - }, }, }, ], @@ -1337,11 +1295,6 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str rules: { expenseRules, }, - pendingRulesUpdates: { - [categoryRuleUpdateKey]: { - expenseRule: null, - }, - }, }, }, ], diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index ba2a06d450b9..f3be5d64b836 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -884,7 +884,6 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { const approverRuleToUpdate = PolicyUtils.getTagApproverRule(policyID, tag); const filteredApprovalRules = approverRuleToUpdate ? prevApprovalRules.filter((rule) => rule.id !== approverRuleToUpdate.id) : prevApprovalRules; const toBeUnselected = approverRuleToUpdate?.approver === approver; - const tagRuleUpdateKey = PolicyUtils.getKeyForPendingRuleUpdate(tag, CONST.POLICY.FIELDS.TAG); const updatedApproverRule = approverRuleToUpdate ? {...approverRuleToUpdate, approver} @@ -911,11 +910,6 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { rules: { approvalRules: updatedApprovalRules, }, - pendingRulesUpdates: { - [tagRuleUpdateKey]: { - approvalRule: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, - }, }, }, ], diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 02115c47d8b7..17c1a69ac661 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -260,19 +260,15 @@ function CategorySettingsPage({ /> )} - - { - Navigation.navigate(ROUTES.WORSKPACE_CATEGORY_APPROVER.getRoute(policyID, policyCategory.name)); - }} - shouldShowRightIcon - disabled={approverDisabled} - /> - + { + Navigation.navigate(ROUTES.WORSKPACE_CATEGORY_APPROVER.getRoute(policyID, policyCategory.name)); + }} + shouldShowRightIcon + disabled={approverDisabled} + /> {approverDisabled && ( {translate('workspace.rules.categoryRules.goTo')}{' '} @@ -286,18 +282,14 @@ function CategorySettingsPage({ )} {policy?.tax?.trackingEnabled && ( - - { - Navigation.navigate(ROUTES.WORSKPACE_CATEGORY_DEFAULT_TAX_RATE.getRoute(policyID, policyCategory.name)); - }} - shouldShowRightIcon - /> - + { + Navigation.navigate(ROUTES.WORSKPACE_CATEGORY_DEFAULT_TAX_RATE.getRoute(policyID, policyCategory.name)); + }} + shouldShowRightIcon + /> )} diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index 3240758f12b5..c96632ddf872 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -161,15 +161,13 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) {translate('workspace.tags.tagRules')} - - - + {approverDisabled && ( {translate('workspace.rules.categoryRules.goTo')}{' '} From 08cf2a2c52d327460facc2acbb9bb59c37ac06be Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 02:26:58 +0200 Subject: [PATCH 049/104] fix onyx check --- package-lock.json | 16 ---------------- src/libs/ReportActionsConnection.ts | 24 ++++++++++++++++++++++++ src/libs/actions/Policy/Policy.ts | 7 +++++-- 3 files changed, 29 insertions(+), 18 deletions(-) create mode 100644 src/libs/ReportActionsConnection.ts diff --git a/package-lock.json b/package-lock.json index d21d80353080..fd4217d640e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27979,22 +27979,6 @@ "jest": "bin/jest.js" } }, - "node_modules/jest-expo/node_modules/@babel/code-frame": { - "version": "7.10.4", - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/jest-expo/node_modules/@expo/json-file": { - "version": "8.3.1", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "~7.10.4", - "json5": "^2.2.2", - "write-file-atomic": "^2.3.0" - } - }, "node_modules/jest-expo/node_modules/json5": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", diff --git a/src/libs/ReportActionsConnection.ts b/src/libs/ReportActionsConnection.ts new file mode 100644 index 000000000000..b512aeb42c97 --- /dev/null +++ b/src/libs/ReportActionsConnection.ts @@ -0,0 +1,24 @@ +import type {OnyxCollection} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Message, OldDotReportAction, OriginalMessage, ReportActions} from '@src/types/onyx/ReportAction'; + +let allReportActions: OnyxCollection; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_ACTIONS, + waitForCollectionCallback: true, + callback: (actions) => { + if (!actions) { + return; + } + + allReportActions = actions; + }, +}); + +// This function is used to get all reports +function getAllReportActions() { + return allReportActions; +} + +export {getAllReportActions}; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index ae12b3747bab..6dda2a457115 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -71,8 +71,8 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; -import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportConnection from '@libs/ReportConnection'; +import * as ReportAcionsConnection from '@libs/ReportActionsConnection' import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; @@ -2578,7 +2578,10 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF }); // We need to move the report preview action from the DM to the workspace chat. - const reportPreview = ReportActionsUtils.getParentReportAction(iouReport); + const parentReport = ReportAcionsConnection.getAllReportActions()?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`] + const parentReportActionID = iouReport.parentReportActionID + const reportPreview = parentReportActionID ? parentReport?.[parentReportActionID] : undefined; + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, From b32ed64cc822f7e7803e522ba400c9d5becefdf5 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 02:28:08 +0200 Subject: [PATCH 050/104] remove pending pattern from type --- src/types/onyx/Policy.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 006a4a42cf04..6b8817ff5581 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1686,18 +1686,6 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** Workspace account ID configured for Expensify Card */ workspaceAccountID?: number; - - /** Information about rules being updated */ - pendingRulesUpdates?: Record< - CategoryOrTagName, - { - /** Indicates whether the approval rule is updated for the given category or tag */ - approvalRule: OnyxCommon.PendingAction; - - /** Indicates whether the expense rule is updated for the given category or tag */ - expenseRule: OnyxCommon.PendingAction; - } - >; } & Partial, 'addWorkspaceRoom' | keyof ACHAccount | keyof Attributes >; From 71c8ef800f284f085fcbb6e408293cca9b358624 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 02:37:42 +0200 Subject: [PATCH 051/104] run prettier --- src/libs/actions/Policy/Policy.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 6dda2a457115..b202ac961755 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -71,8 +71,8 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import * as ReportAcionsConnection from '@libs/ReportActionsConnection'; import * as ReportConnection from '@libs/ReportConnection'; -import * as ReportAcionsConnection from '@libs/ReportActionsConnection' import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; @@ -2578,10 +2578,10 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF }); // We need to move the report preview action from the DM to the workspace chat. - const parentReport = ReportAcionsConnection.getAllReportActions()?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`] - const parentReportActionID = iouReport.parentReportActionID - const reportPreview = parentReportActionID ? parentReport?.[parentReportActionID] : undefined; - + const parentReport = ReportAcionsConnection.getAllReportActions()?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`]; + const parentReportActionID = iouReport.parentReportActionID; + const reportPreview = parentReportActionID ? parentReport?.[parentReportActionID] : undefined; + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, From 669e6924b64b47030a0156e5c8e4d929358dfcb2 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 02:38:30 +0200 Subject: [PATCH 052/104] cleanup --- src/types/onyx/Policy.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 6b8817ff5581..1f1be7e89c20 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1412,9 +1412,6 @@ type ExpenseRule = { id?: string; }; -/** The name of the category or tag */ -type CategoryOrTagName = string; - /** Model of policy data */ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< { From 4fccbb14cb2472960cfff8bdaac78be84dc88592 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 02:44:02 +0200 Subject: [PATCH 053/104] cleanup --- src/libs/ReportActionsConnection.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportActionsConnection.ts b/src/libs/ReportActionsConnection.ts index b512aeb42c97..e3c8a4c3cf60 100644 --- a/src/libs/ReportActionsConnection.ts +++ b/src/libs/ReportActionsConnection.ts @@ -1,7 +1,7 @@ import type {OnyxCollection} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Message, OldDotReportAction, OriginalMessage, ReportActions} from '@src/types/onyx/ReportAction'; +import type {ReportActions} from '@src/types/onyx/ReportAction'; let allReportActions: OnyxCollection; Onyx.connect({ @@ -21,4 +21,5 @@ function getAllReportActions() { return allReportActions; } +// eslint-disable-next-line import/prefer-default-export export {getAllReportActions}; From 2fdea8246269e9c1cc6b9ccf2a349fc6aa31d83e Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 02:46:58 +0200 Subject: [PATCH 054/104] remove withOnyx --- .../categories/CategorySettingsPage.tsx | 19 ++++-------------- src/pages/workspace/tags/TagSettingsPage.tsx | 20 +++++-------------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/src/pages/workspace/categories/CategorySettingsPage.tsx b/src/pages/workspace/categories/CategorySettingsPage.tsx index 17c1a69ac661..05111864f61a 100644 --- a/src/pages/workspace/categories/CategorySettingsPage.tsx +++ b/src/pages/workspace/categories/CategorySettingsPage.tsx @@ -1,8 +1,7 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo, useState} from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import ConfirmModal from '@components/ConfirmModal'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -31,22 +30,16 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type * as OnyxTypes from '@src/types/onyx'; -type CategorySettingsPageOnyxProps = { - /** Collection of categories attached to a policy */ - policyCategories: OnyxEntry; -}; - -type CategorySettingsPageProps = CategorySettingsPageOnyxProps & StackScreenProps; +type CategorySettingsPageProps = StackScreenProps; function CategorySettingsPage({ route: { params: {backTo, policyID, categoryName}, }, - policyCategories, navigation, }: CategorySettingsPageProps) { + const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`); const styles = useThemeStyles(); const {translate} = useLocalize(); const [deleteCategoryConfirmModalVisible, setDeleteCategoryConfirmModalVisible] = useState(false); @@ -332,8 +325,4 @@ function CategorySettingsPage({ CategorySettingsPage.displayName = 'CategorySettingsPage'; -export default withOnyx({ - policyCategories: { - key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route.params.policyID}`, - }, -})(CategorySettingsPage); +export default CategorySettingsPage; diff --git a/src/pages/workspace/tags/TagSettingsPage.tsx b/src/pages/workspace/tags/TagSettingsPage.tsx index c96632ddf872..6b70b6f636fe 100644 --- a/src/pages/workspace/tags/TagSettingsPage.tsx +++ b/src/pages/workspace/tags/TagSettingsPage.tsx @@ -1,8 +1,7 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo} from 'react'; import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import type {OnyxEntry} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import ConfirmModal from '@components/ConfirmModal'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -28,16 +27,11 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {PolicyTagLists} from '@src/types/onyx'; -type TagSettingsPageOnyxProps = { - /** All policy tags */ - policyTags: OnyxEntry; -}; +type TagSettingsPageProps = StackScreenProps; -type TagSettingsPageProps = TagSettingsPageOnyxProps & StackScreenProps; - -function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) { +function TagSettingsPage({route, navigation}: TagSettingsPageProps) { + const [policyTags] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_TAGS}${route.params.policyID}`); const {orderWeight, policyID, tagName} = route.params; const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -198,8 +192,4 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps) TagSettingsPage.displayName = 'TagSettingsPage'; -export default withOnyx({ - policyTags: { - key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${route.params.policyID}`, - }, -})(TagSettingsPage); +export default TagSettingsPage; From 024a2ec1ad97b412b9aef341db6e498aa56fb78e Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Wed, 18 Sep 2024 06:59:05 +0200 Subject: [PATCH 055/104] chore: update `package-lock.json` --- package-lock.json | 748 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 705 insertions(+), 43 deletions(-) diff --git a/package-lock.json b/package-lock.json index d21d80353080..f0af39ce1757 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,6 @@ "@rnmapbox/maps": "10.1.30", "@shopify/flash-list": "1.7.1", "@ua/react-native-airship": "19.2.1", - "@vue/preload-webpack-plugin": "^2.0.0", "awesome-phonenumber": "^5.4.0", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", @@ -60,9 +59,7 @@ "focus-trap-react": "^10.2.3", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", - "jest-expo": "51.0.4", - "jest-when": "^3.5.2", - "lodash": "4.17.21", + "lodash-es": "4.17.21", "lottie-react-native": "6.5.1", "mapbox-gl": "^2.15.0", "onfido-sdk-ui": "14.15.0", @@ -71,7 +68,6 @@ "react": "18.3.1", "react-beautiful-dnd": "^13.1.1", "react-collapse": "^5.1.0", - "react-compiler-runtime": "file:./lib/react-compiler-runtime", "react-content-loader": "^7.0.0", "react-dom": "18.3.1", "react-error-boundary": "^4.0.11", @@ -125,8 +121,7 @@ "react-plaid-link": "3.3.2", "react-web-config": "^1.0.0", "react-webcam": "^7.1.1", - "semver": "^7.5.2", - "xlsx": "file:vendor/xlsx-0.20.3.tgz" + "react-window": "^1.8.9" }, "devDependencies": { "@actions/core": "1.10.0", @@ -149,7 +144,10 @@ "@dword-design/eslint-plugin-import-alias": "^5.0.0", "@electron/notarize": "^2.1.0", "@fullstory/babel-plugin-annotate-react": "^2.3.0", + "@fullstory/babel-plugin-react-native": "^1.2.1", "@jest/globals": "^29.5.0", + "@kie/act-js": "^2.6.2", + "@kie/mock-github": "2.0.1", "@ngneat/falso": "^7.1.1", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", @@ -179,7 +177,7 @@ "@types/jest": "^29.5.2", "@types/jest-when": "^3.5.2", "@types/js-yaml": "^4.0.5", - "@types/lodash": "^4.14.195", + "@types/lodash-es": "4.17.12", "@types/mapbox-gl": "^2.7.13", "@types/mime-db": "^1.43.5", "@types/node": "^20.11.5", @@ -198,6 +196,7 @@ "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", "@vercel/ncc": "0.38.1", + "@vue/preload-webpack-plugin": "^2.0.0", "@welldone-software/why-did-you-render": "7.0.1", "ajv-cli": "^5.0.0", "babel-jest": "29.4.1", @@ -233,7 +232,9 @@ "jest-circus": "29.4.1", "jest-cli": "29.4.1", "jest-environment-jsdom": "^29.4.1", + "jest-expo": "51.0.4", "jest-transformer-svg": "^2.0.1", + "jest-when": "^3.5.2", "link": "^2.1.1", "memfs": "^4.6.0", "onchange": "^7.1.0", @@ -244,10 +245,12 @@ "prettier": "^2.8.8", "pusher-js-mock": "^0.3.3", "react-compiler-healthcheck": "^0.0.0-experimental-ab3118d-20240725", + "react-compiler-runtime": "file:./lib/react-compiler-runtime", "react-is": "^18.3.1", "react-native-clean-project": "^4.0.0-alpha4.0", "react-test-renderer": "18.3.1", "reassure": "^1.0.0-rc.4", + "semver": "7.5.2", "setimmediate": "^1.0.5", "shellcheck": "^1.1.0", "source-map": "^0.7.4", @@ -264,7 +267,8 @@ "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^5.0.4", "webpack-dev-server": "^5.0.4", - "webpack-merge": "^5.8.0" + "webpack-merge": "^5.8.0", + "xlsx": "file:vendor/xlsx-0.20.3.tgz" }, "engines": { "node": "20.15.1", @@ -273,6 +277,7 @@ }, "lib/react-compiler-runtime": { "version": "0.0.1", + "dev": true, "license": "MIT", "dependencies": { "react": "18.3.1" @@ -1440,6 +1445,7 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -2837,6 +2843,7 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", + "dev": true, "license": "MIT" }, "node_modules/@blakeembrey/deque": { @@ -3031,7 +3038,7 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -3042,7 +3049,7 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -4100,6 +4107,17 @@ "node": ">=4" } }, + "node_modules/@expo/cli/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/cli/node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -4247,6 +4265,17 @@ "node": ">=8" } }, + "node_modules/@expo/config-plugins/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/config-plugins/node_modules/supports-color": { "version": "7.2.0", "license": "MIT", @@ -4345,6 +4374,17 @@ "node": ">=8" } }, + "node_modules/@expo/config/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/config/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4634,6 +4674,17 @@ "node": ">=8" } }, + "node_modules/@expo/image-utils/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/image-utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5261,6 +5312,17 @@ "node": ">=8" } }, + "node_modules/@expo/prebuild-config/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@expo/prebuild-config/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5772,6 +5834,7 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", + "dev": true, "license": "ISC", "dependencies": { "camelcase": "^5.3.1", @@ -5786,6 +5849,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5793,6 +5857,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -5804,6 +5869,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -5814,6 +5880,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -5827,6 +5894,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -5837,6 +5905,7 @@ }, "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5844,6 +5913,7 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5851,6 +5921,7 @@ }, "node_modules/@jest/console": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -5866,6 +5937,7 @@ }, "node_modules/@jest/console/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5879,6 +5951,7 @@ }, "node_modules/@jest/console/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -5893,6 +5966,7 @@ }, "node_modules/@jest/console/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -5903,10 +5977,12 @@ }, "node_modules/@jest/console/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/console/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5914,6 +5990,7 @@ }, "node_modules/@jest/console/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -5924,6 +6001,7 @@ }, "node_modules/@jest/core": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -5969,6 +6047,7 @@ }, "node_modules/@jest/core/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -5982,6 +6061,7 @@ }, "node_modules/@jest/core/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -5996,6 +6076,7 @@ }, "node_modules/@jest/core/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6006,10 +6087,12 @@ }, "node_modules/@jest/core/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/core/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6017,6 +6100,7 @@ }, "node_modules/@jest/core/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6050,6 +6134,7 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "expect": "^29.7.0", @@ -6061,6 +6146,7 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3" @@ -6086,6 +6172,7 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -6099,6 +6186,7 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", @@ -6140,6 +6228,7 @@ }, "node_modules/@jest/reporters/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6153,6 +6242,7 @@ }, "node_modules/@jest/reporters/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -6167,6 +6257,7 @@ }, "node_modules/@jest/reporters/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6177,10 +6268,12 @@ }, "node_modules/@jest/reporters/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/reporters/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6188,6 +6281,7 @@ }, "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { "version": "6.0.2", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.23.9", @@ -6202,6 +6296,7 @@ }, "node_modules/@jest/reporters/node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -6215,6 +6310,7 @@ }, "node_modules/@jest/reporters/node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6226,8 +6322,21 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@jest/reporters/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6248,6 +6357,7 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -6260,6 +6370,7 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -6273,6 +6384,7 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -6286,6 +6398,7 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -6310,6 +6423,7 @@ }, "node_modules/@jest/transform/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6323,6 +6437,7 @@ }, "node_modules/@jest/transform/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -6337,6 +6452,7 @@ }, "node_modules/@jest/transform/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -6347,10 +6463,12 @@ }, "node_modules/@jest/transform/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6358,6 +6476,7 @@ }, "node_modules/@jest/transform/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -6368,6 +6487,7 @@ }, "node_modules/@jest/transform/node_modules/write-file-atomic": { "version": "4.0.2", + "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -6520,6 +6640,56 @@ "react-native": "*" } }, + "node_modules/@kie/act-js": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.6.2.tgz", + "integrity": "sha512-i366cfWluUi55rPZ6e9/aWH4tnw3Q6W1CKh9Gz6QjTvbAtS4KnUUy33I9aMXS6uwa0haw6MSahMM37vmuFCVpQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@kie/mock-github": "^2.0.0", + "adm-zip": "^0.5.10", + "ajv": "^8.12.0", + "bin-links": "^4.0.1", + "express": "^4.18.1", + "follow-redirects": "^1.15.2", + "tar": "^6.1.13", + "yaml": "^2.1.3" + }, + "bin": { + "act-js": "bin/act" + } + }, + "node_modules/@kie/mock-github": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.1.tgz", + "integrity": "sha512-G1FD/jg1KyW7a6NvKI4uEVJCK3eJnzXkh4Ikxn2is5tiNC980lavi8ak6bn1QEFEgpYcfM4DpZM3yHDfOmyLuQ==", + "dev": true, + "dependencies": { + "@octokit/openapi-types-ghec": "^18.0.0", + "ajv": "^8.11.0", + "express": "^4.18.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "nock": "^13.2.7", + "simple-git": "^3.8.0", + "totalist": "^3.0.0" + } + }, + "node_modules/@kie/mock-github/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", "dev": true, @@ -6939,6 +7109,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@octokit/openapi-types-ghec": { + "version": "18.1.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.1.1.tgz", + "integrity": "sha512-5Ri7FLYX4gJSdG+G0Q8QDca/gOLfkPN4YR2hkbVg6hEL+0N62MIsJPTyNaT9pGEXCLd1KbYV6Lh3T2ggsmyBJw==", + "dev": true + }, "node_modules/@octokit/plugin-paginate-rest": { "version": "3.1.0", "dev": true, @@ -13218,6 +13394,18 @@ "node": ">= 4" } }, + "node_modules/@storybook/core/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@storybook/core/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -15207,22 +15395,22 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.9", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@turf/along": { @@ -15366,6 +15554,7 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -15377,6 +15566,7 @@ }, "node_modules/@types/babel__generator": { "version": "7.6.4", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -15384,6 +15574,7 @@ }, "node_modules/@types/babel__template": { "version": "7.4.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -15392,6 +15583,7 @@ }, "node_modules/@types/babel__traverse": { "version": "7.18.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.3.0" @@ -15543,6 +15735,7 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.9", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -15570,6 +15763,7 @@ }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", + "dev": true, "license": "MIT" }, "node_modules/@types/http-cache-semantics": { @@ -15632,6 +15826,7 @@ }, "node_modules/@types/jsdom": { "version": "20.0.1", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -15641,6 +15836,7 @@ }, "node_modules/@types/jsdom/node_modules/entities": { "version": "4.5.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -15651,6 +15847,7 @@ }, "node_modules/@types/jsdom/node_modules/parse5": { "version": "7.1.2", + "dev": true, "license": "MIT", "dependencies": { "entities": "^4.4.0" @@ -15681,6 +15878,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/mapbox-gl": { "version": "2.7.13", "license": "MIT", @@ -15949,6 +16155,7 @@ }, "node_modules/@types/tough-cookie": { "version": "4.0.2", + "dev": true, "license": "MIT" }, "node_modules/@types/unist": { @@ -16279,6 +16486,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@typescript-eslint/rule-tester/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.13.1", "dev": true, @@ -16403,6 +16622,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/utils": { "version": "5.62.0", "dev": true, @@ -16587,6 +16818,7 @@ }, "node_modules/@vue/preload-webpack-plugin": { "version": "2.0.0", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=6.0.0" @@ -16842,6 +17074,7 @@ }, "node_modules/abab": { "version": "2.0.6", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/abbrev": { @@ -16883,6 +17116,7 @@ }, "node_modules/acorn-globals": { "version": "7.0.1", + "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.1.0", @@ -16891,6 +17125,7 @@ }, "node_modules/acorn-globals/node_modules/acorn": { "version": "8.11.3", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -16901,6 +17136,7 @@ }, "node_modules/acorn-globals/node_modules/acorn-walk": { "version": "8.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -16922,6 +17158,15 @@ "node": ">=0.4.0" } }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "dev": true, + "engines": { + "node": ">=12.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "license": "MIT", @@ -17387,7 +17632,7 @@ }, "node_modules/arg": { "version": "4.1.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/argparse": { @@ -17739,6 +17984,7 @@ }, "node_modules/babel-jest": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.4.1", @@ -17758,6 +18004,7 @@ }, "node_modules/babel-jest/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -17771,6 +18018,7 @@ }, "node_modules/babel-jest/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -17785,6 +18033,7 @@ }, "node_modules/babel-jest/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -17795,10 +18044,12 @@ }, "node_modules/babel-jest/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/babel-jest/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17806,6 +18057,7 @@ }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -17971,6 +18223,7 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -17985,6 +18238,7 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", @@ -18283,6 +18537,7 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", + "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -18595,6 +18850,7 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", + "dev": true, "license": "MIT", "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", @@ -18702,6 +18958,46 @@ "node": "*" } }, + "node_modules/bin-links": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", + "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==", + "dev": true, + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/bin-links/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/bin-links/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "dev": true, @@ -19333,6 +19629,7 @@ }, "node_modules/camel-case": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", @@ -19421,6 +19718,7 @@ }, "node_modules/char-regex": { "version": "1.0.2", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -19557,6 +19855,7 @@ }, "node_modules/clean-css": { "version": "5.3.2", + "dev": true, "license": "MIT", "dependencies": { "source-map": "~0.6.0" @@ -19567,6 +19866,7 @@ }, "node_modules/clean-css/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -19718,8 +20018,18 @@ "node": ">=6" } }, + "node_modules/cmd-shim": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", + "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/co": { "version": "4.6.0", + "dev": true, "license": "MIT", "engines": { "iojs": ">= 1.0.0", @@ -19728,6 +20038,7 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/color": { @@ -20475,7 +20786,7 @@ }, "node_modules/create-require": { "version": "1.1.1", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/create-storybook": { @@ -20900,6 +21211,7 @@ }, "node_modules/cssom": { "version": "0.5.0", + "dev": true, "license": "MIT" }, "node_modules/csstype": { @@ -21012,6 +21324,7 @@ }, "node_modules/decimal.js": { "version": "10.4.3", + "dev": true, "license": "MIT" }, "node_modules/decode-uri-component": { @@ -21342,6 +21655,7 @@ }, "node_modules/detect-newline": { "version": "3.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -21373,9 +21687,21 @@ "diagnostic-channel": "*" } }, + "node_modules/diagnostic-channel/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/diff": { "version": "4.0.2", - "devOptional": true, + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -21383,6 +21709,7 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -21535,6 +21862,7 @@ }, "node_modules/dom-converter": { "version": "0.2.0", + "dev": true, "license": "MIT", "dependencies": { "utila": "~0.4" @@ -21560,6 +21888,7 @@ }, "node_modules/domexception": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "webidl-conversions": "^7.0.0" @@ -21607,6 +21936,7 @@ }, "node_modules/dot-case": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -21919,6 +22249,7 @@ }, "node_modules/emittery": { "version": "0.13.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -22314,6 +22645,7 @@ }, "node_modules/escodegen": { "version": "2.1.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", @@ -22333,6 +22665,7 @@ }, "node_modules/escodegen/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "optional": true, "engines": { @@ -22601,6 +22934,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-expensify/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-config-prettier": { "version": "9.1.0", "dev": true, @@ -22802,6 +23147,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/eslint-plugin-deprecation/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-plugin-es": { "version": "4.1.0", "dev": true, @@ -23641,12 +23998,14 @@ }, "node_modules/exit": { "version": "0.1.2", + "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/expect-utils": "^29.7.0", @@ -23679,6 +24038,17 @@ "ua-parser-js": "^1.0.38" } }, + "node_modules/expensify-common/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/expensify-common/node_modules/ua-parser-js": { "version": "1.0.38", "funding": [ @@ -23978,6 +24348,17 @@ "node": ">=8" } }, + "node_modules/expo/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/expo/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -25091,6 +25472,7 @@ }, "node_modules/get-package-type": { "version": "0.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" @@ -25505,6 +25887,7 @@ }, "node_modules/he": { "version": "1.2.0", + "dev": true, "license": "MIT", "bin": { "he": "bin/he" @@ -25573,6 +25956,7 @@ }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "whatwg-encoding": "^2.0.0" @@ -25597,10 +25981,12 @@ }, "node_modules/html-escaper": { "version": "2.0.2", + "dev": true, "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "6.1.0", + "dev": true, "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -25620,6 +26006,7 @@ }, "node_modules/html-minifier-terser/node_modules/commander": { "version": "8.3.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 12" @@ -25638,6 +26025,7 @@ }, "node_modules/html-webpack-plugin": { "version": "5.5.3", + "dev": true, "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -25957,6 +26345,7 @@ }, "node_modules/iconv-lite": { "version": "0.6.3", + "devOptional": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -26069,6 +26458,7 @@ }, "node_modules/import-local": { "version": "3.1.0", + "dev": true, "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", @@ -26086,6 +26476,7 @@ }, "node_modules/import-local/node_modules/find-up": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "locate-path": "^5.0.0", @@ -26097,6 +26488,7 @@ }, "node_modules/import-local/node_modules/locate-path": { "version": "5.0.0", + "dev": true, "license": "MIT", "dependencies": { "p-locate": "^4.1.0" @@ -26107,6 +26499,7 @@ }, "node_modules/import-local/node_modules/p-limit": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "p-try": "^2.0.0" @@ -26120,6 +26513,7 @@ }, "node_modules/import-local/node_modules/p-locate": { "version": "4.1.0", + "dev": true, "license": "MIT", "dependencies": { "p-limit": "^2.2.0" @@ -26130,6 +26524,7 @@ }, "node_modules/import-local/node_modules/path-exists": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -26137,6 +26532,7 @@ }, "node_modules/import-local/node_modules/pkg-dir": { "version": "4.2.0", + "dev": true, "license": "MIT", "dependencies": { "find-up": "^4.0.0" @@ -26614,6 +27010,7 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -26820,6 +27217,7 @@ }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", + "dev": true, "license": "MIT" }, "node_modules/is-regex": { @@ -26995,6 +27393,7 @@ }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=8" @@ -27002,6 +27401,7 @@ }, "node_modules/istanbul-lib-instrument": { "version": "5.2.0", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "@babel/core": "^7.12.3", @@ -27016,6 +27416,7 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.1", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -27023,6 +27424,7 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -27035,6 +27437,7 @@ }, "node_modules/istanbul-lib-report/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -27042,6 +27445,7 @@ }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "semver": "^7.5.3" @@ -27053,8 +27457,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -27065,6 +27482,7 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", @@ -27077,6 +27495,7 @@ }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -27084,6 +27503,7 @@ }, "node_modules/istanbul-reports": { "version": "3.1.7", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", @@ -27210,6 +27630,7 @@ }, "node_modules/jest": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.4.1", @@ -27234,6 +27655,7 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "execa": "^5.0.0", @@ -27339,6 +27761,7 @@ }, "node_modules/jest-cli": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/core": "^29.4.1", @@ -27371,6 +27794,7 @@ }, "node_modules/jest-cli/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -27384,6 +27808,7 @@ }, "node_modules/jest-cli/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -27398,6 +27823,7 @@ }, "node_modules/jest-cli/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -27408,10 +27834,12 @@ }, "node_modules/jest-cli/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-cli/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -27419,6 +27847,7 @@ }, "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -27429,6 +27858,7 @@ }, "node_modules/jest-config": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -27472,6 +27902,7 @@ }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -27485,6 +27916,7 @@ }, "node_modules/jest-config/node_modules/babel-jest": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/transform": "^29.7.0", @@ -27504,6 +27936,7 @@ }, "node_modules/jest-config/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -27518,6 +27951,7 @@ }, "node_modules/jest-config/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -27528,10 +27962,12 @@ }, "node_modules/jest-config/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-config/node_modules/dedent": { "version": "1.5.3", + "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -27544,6 +27980,7 @@ }, "node_modules/jest-config/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -27551,6 +27988,7 @@ }, "node_modules/jest-config/node_modules/jest-circus": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -27580,6 +28018,7 @@ }, "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -27590,6 +28029,7 @@ }, "node_modules/jest-diff": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -27603,6 +28043,7 @@ }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -27616,6 +28057,7 @@ }, "node_modules/jest-diff/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -27630,6 +28072,7 @@ }, "node_modules/jest-diff/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -27640,10 +28083,12 @@ }, "node_modules/jest-diff/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-diff/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -27651,6 +28096,7 @@ }, "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -27661,6 +28107,7 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" @@ -27671,6 +28118,7 @@ }, "node_modules/jest-each": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -27685,6 +28133,7 @@ }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -27698,6 +28147,7 @@ }, "node_modules/jest-each/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -27712,6 +28162,7 @@ }, "node_modules/jest-each/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -27722,10 +28173,12 @@ }, "node_modules/jest-each/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-each/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -27733,6 +28186,7 @@ }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -27743,6 +28197,7 @@ }, "node_modules/jest-environment-jsdom": { "version": "29.4.1", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.4.1", @@ -27768,6 +28223,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/acorn": { "version": "8.11.3", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -27778,6 +28234,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/cssstyle": { "version": "2.3.0", + "dev": true, "license": "MIT", "dependencies": { "cssom": "~0.3.6" @@ -27788,10 +28245,12 @@ }, "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", + "dev": true, "license": "MIT" }, "node_modules/jest-environment-jsdom/node_modules/data-urls": { "version": "3.0.2", + "dev": true, "license": "MIT", "dependencies": { "abab": "^2.0.6", @@ -27804,6 +28263,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/entities": { "version": "4.5.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -27814,6 +28274,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/form-data": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -27826,6 +28287,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/jsdom": { "version": "20.0.3", + "dev": true, "license": "MIT", "dependencies": { "abab": "^2.0.6", @@ -27869,6 +28331,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/parse5": { "version": "7.1.2", + "dev": true, "license": "MIT", "dependencies": { "entities": "^4.4.0" @@ -27879,6 +28342,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/tr46": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "punycode": "^2.1.1" @@ -27889,6 +28353,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "xml-name-validator": "^4.0.0" @@ -27899,6 +28364,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { "version": "3.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -27906,6 +28372,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { "version": "11.0.0", + "dev": true, "license": "MIT", "dependencies": { "tr46": "^3.0.0", @@ -27919,6 +28386,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, "engines": { "node": ">=10.0.0" }, @@ -27937,6 +28405,7 @@ }, "node_modules/jest-environment-jsdom/node_modules/xml-name-validator": { "version": "4.0.0", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12" @@ -27961,6 +28430,7 @@ "version": "51.0.4", "resolved": "https://registry.npmjs.org/jest-expo/-/jest-expo-51.0.4.tgz", "integrity": "sha512-WmlR4rUur1TNF/F14brKCmPdX3TWf7Bno/6A1PuxnflN79LEIXpXuPKMlMWwCCChTohGB5FRniknRibblWu1ug==", + "dev": true, "dependencies": { "@expo/config": "~9.0.0-beta.0", "@expo/json-file": "^8.3.0", @@ -27979,26 +28449,11 @@ "jest": "bin/jest.js" } }, - "node_modules/jest-expo/node_modules/@babel/code-frame": { - "version": "7.10.4", - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/jest-expo/node_modules/@expo/json-file": { - "version": "8.3.1", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "~7.10.4", - "json5": "^2.2.2", - "write-file-atomic": "^2.3.0" - } - }, "node_modules/jest-expo/node_modules/json5": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -28008,6 +28463,7 @@ }, "node_modules/jest-expo/node_modules/react-test-renderer": { "version": "18.2.0", + "dev": true, "license": "MIT", "dependencies": { "react-is": "^18.2.0", @@ -28020,6 +28476,7 @@ }, "node_modules/jest-expo/node_modules/scheduler": { "version": "0.23.2", + "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -28034,6 +28491,7 @@ }, "node_modules/jest-haste-map": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -28057,6 +28515,7 @@ }, "node_modules/jest-haste-map/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28064,6 +28523,7 @@ }, "node_modules/jest-haste-map/node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -28077,6 +28537,7 @@ }, "node_modules/jest-haste-map/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28090,6 +28551,7 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-get-type": "^29.6.3", @@ -28101,6 +28563,7 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -28114,6 +28577,7 @@ }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28127,6 +28591,7 @@ }, "node_modules/jest-matcher-utils/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28141,6 +28606,7 @@ }, "node_modules/jest-matcher-utils/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28151,10 +28617,12 @@ }, "node_modules/jest-matcher-utils/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-matcher-utils/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28162,6 +28630,7 @@ }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28260,6 +28729,7 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -28275,6 +28745,7 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", + "dev": true, "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -28282,6 +28753,7 @@ }, "node_modules/jest-resolve": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.0.0", @@ -28300,6 +28772,7 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "jest-regex-util": "^29.6.3", @@ -28311,6 +28784,7 @@ }, "node_modules/jest-resolve/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28324,6 +28798,7 @@ }, "node_modules/jest-resolve/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28338,6 +28813,7 @@ }, "node_modules/jest-resolve/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28348,10 +28824,12 @@ }, "node_modules/jest-resolve/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-resolve/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28359,6 +28837,7 @@ }, "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28369,6 +28848,7 @@ }, "node_modules/jest-runner": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/console": "^29.7.0", @@ -28399,6 +28879,7 @@ }, "node_modules/jest-runner/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28412,6 +28893,7 @@ }, "node_modules/jest-runner/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28426,6 +28908,7 @@ }, "node_modules/jest-runner/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28436,10 +28919,12 @@ }, "node_modules/jest-runner/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-runner/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28447,6 +28932,7 @@ }, "node_modules/jest-runner/node_modules/jest-worker": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -28460,6 +28946,7 @@ }, "node_modules/jest-runner/node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28473,6 +28960,7 @@ }, "node_modules/jest-runner/node_modules/source-map": { "version": "0.6.1", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -28480,6 +28968,7 @@ }, "node_modules/jest-runner/node_modules/source-map-support": { "version": "0.5.13", + "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -28488,6 +28977,7 @@ }, "node_modules/jest-runner/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28498,6 +28988,7 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", @@ -28529,6 +29020,7 @@ }, "node_modules/jest-runtime/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28542,6 +29034,7 @@ }, "node_modules/jest-runtime/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28556,6 +29049,7 @@ }, "node_modules/jest-runtime/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28566,10 +29060,12 @@ }, "node_modules/jest-runtime/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-runtime/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28577,6 +29073,7 @@ }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28587,6 +29084,7 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", @@ -28616,6 +29114,7 @@ }, "node_modules/jest-snapshot/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28629,6 +29128,7 @@ }, "node_modules/jest-snapshot/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28643,6 +29143,7 @@ }, "node_modules/jest-snapshot/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28653,17 +29154,32 @@ }, "node_modules/jest-snapshot/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-snapshot/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28829,6 +29345,7 @@ }, "node_modules/jest-watch-select-projects": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.0", @@ -28838,6 +29355,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28851,6 +29369,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/chalk": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28862,6 +29381,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28872,10 +29392,12 @@ }, "node_modules/jest-watch-select-projects/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watch-select-projects/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28883,6 +29405,7 @@ }, "node_modules/jest-watch-select-projects/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -28893,6 +29416,7 @@ }, "node_modules/jest-watch-typeahead": { "version": "2.2.1", + "dev": true, "license": "MIT", "dependencies": { "ansi-escapes": "^6.0.0", @@ -28912,6 +29436,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-escapes": { "version": "6.2.0", + "dev": true, "license": "MIT", "dependencies": { "type-fest": "^3.0.0" @@ -28925,6 +29450,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-regex": { "version": "6.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -28935,6 +29461,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -28948,6 +29475,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -28962,6 +29490,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/char-regex": { "version": "2.0.1", + "dev": true, "license": "MIT", "engines": { "node": ">=12.20" @@ -28969,6 +29498,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -28979,10 +29509,12 @@ }, "node_modules/jest-watch-typeahead/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watch-typeahead/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -28990,6 +29522,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/slash": { "version": "5.1.0", + "dev": true, "license": "MIT", "engines": { "node": ">=14.16" @@ -29000,6 +29533,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/string-length": { "version": "5.0.1", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^2.0.0", @@ -29014,6 +29548,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { "version": "7.1.0", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -29027,6 +29562,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29037,6 +29573,7 @@ }, "node_modules/jest-watch-typeahead/node_modules/type-fest": { "version": "3.13.1", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=14.16" @@ -29047,6 +29584,7 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", + "dev": true, "license": "MIT", "dependencies": { "@jest/test-result": "^29.7.0", @@ -29064,6 +29602,7 @@ }, "node_modules/jest-watcher/node_modules/ansi-styles": { "version": "4.3.0", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -29077,6 +29616,7 @@ }, "node_modules/jest-watcher/node_modules/chalk": { "version": "4.1.2", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -29091,6 +29631,7 @@ }, "node_modules/jest-watcher/node_modules/color-convert": { "version": "2.0.1", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -29101,10 +29642,12 @@ }, "node_modules/jest-watcher/node_modules/color-name": { "version": "1.1.4", + "dev": true, "license": "MIT" }, "node_modules/jest-watcher/node_modules/has-flag": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -29112,6 +29655,7 @@ }, "node_modules/jest-watcher/node_modules/supports-color": { "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -29122,6 +29666,7 @@ }, "node_modules/jest-when": { "version": "3.5.2", + "dev": true, "license": "MIT", "peerDependencies": { "jest": ">= 25" @@ -29847,6 +30392,11 @@ "version": "4.17.21", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "dev": true, @@ -30023,6 +30573,7 @@ }, "node_modules/lower-case": { "version": "2.0.2", + "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -30089,7 +30640,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "devOptional": true, + "dev": true, "license": "ISC" }, "node_modules/make-event-props": { @@ -31328,6 +31879,7 @@ }, "node_modules/natural-compare": { "version": "1.4.0", + "dev": true, "license": "MIT" }, "node_modules/natural-compare-lite": { @@ -31357,6 +31909,7 @@ }, "node_modules/no-case": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "lower-case": "^2.0.2", @@ -31370,6 +31923,20 @@ "node": ">=12.0.0" } }, + "node_modules/nock": { + "version": "13.5.5", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.5.tgz", + "integrity": "sha512-XKYnqUrCwXC8DGG1xX4YH5yNIrlh9c065uaMZZHUoeUUINTOyt+x/G+ezYk0Ft6ExSREVIs+qBJDK503viTfFA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, "node_modules/node-abi": { "version": "3.65.0", "dev": true, @@ -31607,6 +32174,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm-package-arg": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz", @@ -31674,6 +32250,7 @@ }, "node_modules/nwsapi": { "version": "2.2.7", + "dev": true, "license": "MIT" }, "node_modules/nypm": { @@ -32319,6 +32896,7 @@ }, "node_modules/param-case": { "version": "3.0.4", + "dev": true, "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -32379,6 +32957,7 @@ }, "node_modules/pascal-case": { "version": "3.1.2", + "dev": true, "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -32502,6 +33081,18 @@ "rimraf": "bin.js" } }, + "node_modules/patch-package/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/patch-package/node_modules/slash": { "version": "2.0.0", "dev": true, @@ -33000,6 +33591,7 @@ }, "node_modules/pretty-error": { "version": "4.0.0", + "dev": true, "license": "MIT", "dependencies": { "lodash": "^4.17.20", @@ -33110,6 +33702,15 @@ "version": "16.13.1", "license": "MIT" }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/protocol-buffers-schema": { "version": "3.6.0", "license": "MIT" @@ -33128,6 +33729,7 @@ }, "node_modules/psl": { "version": "1.9.0", + "dev": true, "license": "MIT" }, "node_modules/pump": { @@ -33147,6 +33749,7 @@ }, "node_modules/pure-rand": { "version": "6.0.4", + "dev": true, "funding": [ { "type": "individual", @@ -33239,6 +33842,7 @@ }, "node_modules/querystringify": { "version": "2.2.0", + "dev": true, "license": "MIT" }, "node_modules/queue": { @@ -36259,6 +36863,15 @@ "read-binary-file-arch": "cli.js" } }, + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/read-config-file": { "version": "6.4.0", "dev": true, @@ -36591,6 +37204,7 @@ }, "node_modules/relateurl": { "version": "0.2.7", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -36603,6 +37217,7 @@ }, "node_modules/renderkid": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "css-select": "^4.1.3", @@ -36614,6 +37229,7 @@ }, "node_modules/renderkid/node_modules/css-select": { "version": "4.3.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -36628,6 +37244,7 @@ }, "node_modules/renderkid/node_modules/htmlparser2": { "version": "6.1.0", + "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -36709,6 +37326,7 @@ }, "node_modules/requires-port": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/resedit": { @@ -36750,6 +37368,7 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", + "dev": true, "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" @@ -36932,6 +37551,7 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", + "devOptional": true, "license": "MIT" }, "node_modules/sanitize-filename": { @@ -36948,6 +37568,7 @@ }, "node_modules/saxes": { "version": "6.0.0", + "dev": true, "license": "ISC", "dependencies": { "xmlchars": "^2.2.0" @@ -37035,9 +37656,12 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -37511,6 +38135,18 @@ "node": ">=10" } }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/simply-deferred": { "version": "3.0.0", "resolved": "git+ssh://git@github.com/Expensify/simply-deferred.git#77a08a95754660c7bd6e0b6979fdf84e8e831bf5", @@ -37981,6 +38617,7 @@ }, "node_modules/string-length": { "version": "4.0.2", + "dev": true, "license": "MIT", "dependencies": { "char-regex": "^1.0.2", @@ -38131,6 +38768,7 @@ }, "node_modules/strip-bom": { "version": "4.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -38163,6 +38801,7 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -38432,6 +39071,7 @@ }, "node_modules/symbol-tree": { "version": "3.2.4", + "dev": true, "license": "MIT" }, "node_modules/tabbable": { @@ -38691,6 +39331,7 @@ }, "node_modules/test-exclude": { "version": "6.0.0", + "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", @@ -38925,6 +39566,7 @@ }, "node_modules/tough-cookie": { "version": "4.1.3", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "psl": "^1.1.33", @@ -38938,6 +39580,7 @@ }, "node_modules/tough-cookie/node_modules/universalify": { "version": "0.2.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -39059,6 +39702,18 @@ "node": ">=6" } }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ts-jest/node_modules/yargs-parser": { "version": "21.1.1", "dev": true, @@ -39069,7 +39724,7 @@ }, "node_modules/ts-node": { "version": "10.9.2", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -39111,7 +39766,7 @@ }, "node_modules/ts-node/node_modules/acorn": { "version": "8.11.3", - "devOptional": true, + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -39122,7 +39777,7 @@ }, "node_modules/ts-node/node_modules/acorn-walk": { "version": "8.3.2", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -39688,6 +40343,7 @@ }, "node_modules/url-parse": { "version": "1.5.10", + "dev": true, "license": "MIT", "dependencies": { "querystringify": "^2.1.1", @@ -39889,6 +40545,7 @@ }, "node_modules/utila": { "version": "0.4.0", + "dev": true, "license": "MIT" }, "node_modules/utils-merge": { @@ -39914,11 +40571,12 @@ }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { "version": "9.2.0", + "dev": true, "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", @@ -40059,6 +40717,7 @@ }, "node_modules/webidl-conversions": { "version": "7.0.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -40665,6 +41324,7 @@ }, "node_modules/whatwg-encoding": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" @@ -40930,6 +41590,7 @@ "version": "0.20.3", "resolved": "file:vendor/xlsx-0.20.3.tgz", "integrity": "sha512-oLDq3jw7AcLqKWH2AhCpVTZl8mf6X2YReP+Neh0SJUzV/BdZYjth94tG5toiMB1PPrYtxOCfaoUCkvtuH+3AJA==", + "dev": true, "bin": { "xlsx": "bin/xlsx.njs" }, @@ -41006,6 +41667,7 @@ }, "node_modules/xmlchars": { "version": "2.2.0", + "dev": true, "license": "MIT" }, "node_modules/xpath": { @@ -41075,7 +41737,7 @@ }, "node_modules/yn": { "version": "3.1.1", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6" From 075745198479378a9cdff4988a1958f3867446ea Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Wed, 18 Sep 2024 01:16:45 -0400 Subject: [PATCH 056/104] use message instead of originalMessage --- 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 f4ad6a00a896..734828a6cb75 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4258,7 +4258,7 @@ function buildOptimisticTaskCommentReportAction( // These parameters are not saved on the reportAction, but are used to display the task in the UI // Added when we fetch the reportActions on a report - reportAction.reportAction.originalMessage = { + reportAction.reportAction.message = { html: ReportActionsUtils.getReportActionHtml(reportAction.reportAction), taskReportID: ReportActionsUtils.getReportActionMessage(reportAction.reportAction)?.taskReportID, whisperedTo: [], From da9621298ec9a06f32fa41c4bbf1b6ce343c7af1 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Wed, 18 Sep 2024 01:20:45 -0400 Subject: [PATCH 057/104] revert --- 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 9093ee977a1d..0a55973b5ce8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4257,7 +4257,7 @@ function buildOptimisticTaskCommentReportAction( // These parameters are not saved on the reportAction, but are used to display the task in the UI // Added when we fetch the reportActions on a report - reportAction.reportAction.message = { + reportAction.reportAction.originalMessage = { html: ReportActionsUtils.getReportActionHtml(reportAction.reportAction), taskReportID: ReportActionsUtils.getReportActionMessage(reportAction.reportAction)?.taskReportID, whisperedTo: [], From 1b0cce928285c90ac79f382c2c86996b3eaa9115 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Wed, 18 Sep 2024 01:45:03 -0400 Subject: [PATCH 058/104] remove eslint for setting optimistic data --- src/libs/ReportUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 0a55973b5ce8..d1cf4b70a120 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4257,6 +4257,7 @@ function buildOptimisticTaskCommentReportAction( // These parameters are not saved on the reportAction, but are used to display the task in the UI // Added when we fetch the reportActions on a report + // eslint-disable-next-line deprecation/deprecation reportAction.reportAction.originalMessage = { html: ReportActionsUtils.getReportActionHtml(reportAction.reportAction), taskReportID: ReportActionsUtils.getReportActionMessage(reportAction.reportAction)?.taskReportID, From 5e94320264c7bb0cb74ce123e51d3a412aed9bd1 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Wed, 18 Sep 2024 02:01:13 -0400 Subject: [PATCH 059/104] remove specific deprecation --- 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 d1cf4b70a120..dc0b444850f4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4257,7 +4257,7 @@ function buildOptimisticTaskCommentReportAction( // These parameters are not saved on the reportAction, but are used to display the task in the UI // Added when we fetch the reportActions on a report - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line reportAction.reportAction.originalMessage = { html: ReportActionsUtils.getReportActionHtml(reportAction.reportAction), taskReportID: ReportActionsUtils.getReportActionMessage(reportAction.reportAction)?.taskReportID, From 34a236f6a4a0ece85112686c2b8336302cae17c8 Mon Sep 17 00:00:00 2001 From: daledah Date: Wed, 18 Sep 2024 13:27:12 +0700 Subject: [PATCH 060/104] fix: revert changes --- src/pages/home/ReportScreen.tsx | 43 ++++++++++++++------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index e1edddf0277b..11c8b5290ec6 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -213,13 +213,14 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro }, [reportOnyx, permissions], ); + const reportID = report?.reportID; const prevReport = usePrevious(report); const prevUserLeavingStatus = usePrevious(userLeavingStatus); const [isLinkingToMessage, setIsLinkingToMessage] = useState(!!reportActionIDFromRoute); const [currentUserAccountID = -1] = useOnyx(ONYXKEYS.SESSION, {selector: (value) => value?.accountID}); - const {reportActions, linkedAction, sortedAllReportActions} = usePaginatedReportActions(report?.reportID, reportActionIDFromRoute); + const {reportActions, linkedAction, sortedAllReportActions} = usePaginatedReportActions(reportID, reportActionIDFromRoute); const [isBannerVisible, setIsBannerVisible] = useState(true); const [scrollPosition, setScrollPosition] = useState({}); @@ -255,7 +256,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro const hasHelpfulErrors = Object.keys(report?.errorFields ?? {}).some((key) => key !== 'notFound'); const shouldHideReport = !hasHelpfulErrors && !ReportUtils.canAccessReport(report, policies, betas); - const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(report?.reportID ?? '', reportActions ?? [], isOffline); + const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(reportID ?? '', reportActions ?? [], isOffline); const [transactionThreadReportActions = {}] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID}`); const combinedReportActions = ReportActionsUtils.getCombinedReportActions(reportActions, transactionThreadReportID ?? null, Object.values(transactionThreadReportActions)); const lastReportAction = [...combinedReportActions, parentReportAction].find((action) => ReportUtils.canEditReportAction(action) && !ReportActionsUtils.isMoneyRequestAction(action)); @@ -303,16 +304,11 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro } useEffect(() => { - if ( - !transactionThreadReportID || - !route?.params?.reportActionID || - !report?.reportID || - !ReportUtils.isOneTransactionThread(linkedAction?.childReportID ?? '-1', report?.reportID, linkedAction) - ) { + if (!transactionThreadReportID || !route?.params?.reportActionID || !ReportUtils.isOneTransactionThread(linkedAction?.childReportID ?? '-1', reportID ?? '', linkedAction)) { return; } Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(route?.params?.reportID)); - }, [transactionThreadReportID, route?.params?.reportActionID, route?.params?.reportID, linkedAction, report?.reportID]); + }, [transactionThreadReportID, route?.params?.reportActionID, route?.params?.reportID, linkedAction, reportID]); if (report && (ReportUtils.isMoneyRequestReport(report) || ReportUtils.isInvoiceReport(report))) { headerView = ( @@ -387,7 +383,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return false; } - if (!wasReportAccessibleRef.current && !firstRenderRef.current && !report?.reportID && !isOptimisticDelete && !reportMetadata?.isLoadingInitialReportActions && !userLeavingStatus) { + if (!wasReportAccessibleRef.current && !firstRenderRef.current && !reportID && !isOptimisticDelete && !reportMetadata?.isLoadingInitialReportActions && !userLeavingStatus) { return true; } @@ -399,7 +395,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro shouldShowNotFoundLinkedAction, isLoadingApp, finishedLoadingApp, - report?.reportID, + reportID, isOptimisticDelete, reportMetadata?.isLoadingInitialReportActions, userLeavingStatus, @@ -412,11 +408,11 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro }, [reportIDFromRoute, reportActionIDFromRoute]); useEffect(() => { - if (!report?.reportID || !isFocused) { + if (!reportID || !isFocused) { return; } - Report.updateLastVisitTime(report?.reportID); - }, [report?.reportID, isFocused]); + Report.updateLastVisitTime(reportID); + }, [reportID, isFocused]); const fetchReportIfNeeded = useCallback(() => { // Report ID will be empty when the reports collection is empty. @@ -452,16 +448,14 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(accountManagerReportID ?? '')); }, [accountManagerReportID]); - const reportID = report?.reportID; - // Clear notifications for the current report when it's opened and re-focused const clearNotifications = useCallback(() => { // Check if this is the top-most ReportScreen since the Navigator preserves multiple at a time - if (!isTopMostReportId || !reportID) { + if (!isTopMostReportId) { return; } - clearReportNotifications(reportID); + clearReportNotifications(reportID ?? ''); }, [reportID, isTopMostReportId]); useEffect(clearNotifications, [clearNotifications]); @@ -480,7 +474,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro return; } - Report.unsubscribeFromLeavingRoomReportChannel(report?.reportID ?? ''); + Report.unsubscribeFromLeavingRoomReportChannel(reportID ?? ''); }; // I'm disabling the warning, as it expects to use exhaustive deps, even though we want this useEffect to run only on the first render. @@ -516,17 +510,16 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro prevIsFocused || !ReportUtils.isChatThread(report) || ReportUtils.getReportNotificationPreference(report) !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN || - isSingleTransactionView || - !report?.reportID + isSingleTransactionView ) { return; } - Report.openReport(report?.reportID); + Report.openReport(reportID ?? ''); // We don't want to run this useEffect every time `report` is changed // Excluding shouldUseNarrowLayout from the dependency list to prevent re-triggering on screen resize events. // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, [prevIsFocused, report?.participants, isFocused, isSingleTransactionView, report?.reportID]); + }, [prevIsFocused, report?.participants, isFocused, isSingleTransactionView, reportID]); useEffect(() => { // We don't want this effect to run on the first render. @@ -681,11 +674,11 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro }, [isLinkedActionInaccessibleWhisper]); useEffect(() => { - if (!!report?.lastReadTime || !ReportUtils.isTaskReport(report) || !report?.reportID) { + if (!!report?.lastReadTime || !ReportUtils.isTaskReport(report)) { return; } // After creating the task report then navigating to task detail we don't have any report actions and the last read time is empty so We need to update the initial last read time when opening the task report detail. - Report.readNewestAction(report?.reportID); + Report.readNewestAction(report?.reportID ?? ''); }, [report]); const firstReportAction = reportActions[0]; From fa37921d912aa651effa864e75cb0b6b9d1f0d5b Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 18 Sep 2024 16:03:24 +0700 Subject: [PATCH 061/104] calc the total amount from the transactions --- src/libs/actions/IOU.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 3f91d2f62f1c..f51ad70023a5 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6440,12 +6440,11 @@ function getReportFromHoldRequestsOnyxData( const firstHoldTransaction = holdTransactions[0]; const newParentReportActionID = rand64(); - const holdTotal = iouReport.total && iouReport.unheldTotal ? iouReport.total - iouReport.unheldTotal : 0; const optimisticExpenseReport = ReportUtils.buildOptimisticExpenseReport( chatReport.reportID, chatReport.policyID ?? iouReport.policyID ?? '', recipient.accountID ?? 1, - holdTotal * -1, + holdTransactions.reduce((acc, transaction) => acc + transaction.amount, 0) * -1, getCurrency(firstHoldTransaction), false, newParentReportActionID, From 4810e33e8d836cdcde4b00ac404cd6a8f3a59fac Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 16:53:38 +0200 Subject: [PATCH 062/104] run prettier --- src/libs/actions/Policy/Policy.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index eb75338d0caf..97edc635e8ec 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -166,8 +166,6 @@ Onyx.connect({ }, }); - - let lastAccessedWorkspacePolicyID: OnyxEntry; Onyx.connect({ key: ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, From 2ba31913da3662e45dc3da9a86a8a8871a30a821 Mon Sep 17 00:00:00 2001 From: BrtqKr Date: Wed, 18 Sep 2024 16:56:31 +0200 Subject: [PATCH 063/104] cleanup --- src/libs/actions/Policy/Policy.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 97edc635e8ec..79ae9a636870 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -93,7 +93,6 @@ import type { } from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import type {Attributes, CompanyAddress, CustomUnit, NetSuiteCustomList, NetSuiteCustomSegment, Rate, TaxRate, Unit} from '@src/types/onyx/Policy'; -import type {ReportActions} from '@src/types/onyx/ReportAction'; import type {OnyxData} from '@src/types/onyx/Request'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import {buildOptimisticPolicyCategories} from './Category'; From 6bb28d6c9b1caebd86a22e675c7dfaa9b4676ccd Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 18 Sep 2024 21:57:13 +0700 Subject: [PATCH 064/104] fix bug on IOS --- src/libs/actions/Policy/Category.ts | 2 +- src/libs/fileDownload/index.android.ts | 4 ++++ src/libs/fileDownload/index.ios.ts | 4 ++++ .../categories/WorkspaceCategoriesPage.tsx | 16 +++++++++------- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index de277edb6b44..0fe7030dd2e1 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1001,7 +1001,7 @@ function setPolicyDistanceRatesDefaultCategory(policyID: string, currentCustomUn API.write(WRITE_COMMANDS.SET_POLICY_DISTANCE_RATES_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); } -function downloadCategoriesCSV(policyID: string, onDownloadFailed?: () => void) { +function downloadCategoriesCSV(policyID: string, onDownloadFailed: () => void) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_CATEGORIES_CSV, { policyID, }); diff --git a/src/libs/fileDownload/index.android.ts b/src/libs/fileDownload/index.android.ts index a1e81e47994d..8426e20a33f7 100644 --- a/src/libs/fileDownload/index.android.ts +++ b/src/libs/fileDownload/index.android.ts @@ -107,6 +107,10 @@ const postDownloadFile = (url: string, fileName?: string, formData?: FormData, o if (!response.ok) { throw new Error('Failed to download file'); } + const contentType = response.headers.get('content-type'); + if (contentType === 'application/json' && fileName?.includes('.csv')) { + throw new Error(); + } return response.text(); }) .then((fileData) => { diff --git a/src/libs/fileDownload/index.ios.ts b/src/libs/fileDownload/index.ios.ts index 1fff9fb998e6..fb2e1c2c146a 100644 --- a/src/libs/fileDownload/index.ios.ts +++ b/src/libs/fileDownload/index.ios.ts @@ -38,6 +38,10 @@ const postDownloadFile = (url: string, fileName?: string, formData?: FormData, o if (!response.ok) { throw new Error('Failed to download file'); } + const contentType = response.headers.get('content-type'); + if (contentType === 'application/json' && fileName?.includes('.csv')) { + throw new Error(); + } return response.text(); }) .then((fileData) => { diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index e4571e0a3d78..478510eae0a1 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -63,7 +63,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { const {translate} = useLocalize(); const [isOfflineModalVisible, setIsOfflineModalVisible] = useState(false); const [selectedCategories, setSelectedCategories] = useState>({}); - const [downloadFailureModalVisible, setDownloadFailureModalVisible] = useState(false); + const [isDownloadFailureModalVisible, setIsDownloadFailureModalVisible] = useState(false); const [deleteCategoriesConfirmModalVisible, setDeleteCategoriesConfirmModalVisible] = useState(false); const isFocused = useIsFocused(); const {environmentURL} = useEnvironment(); @@ -323,9 +323,11 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { Modal.close(() => setIsOfflineModalVisible(true)); return; } - Category.downloadCategoriesCSV(policyId, () => { - setDownloadFailureModalVisible(true); - }); + Modal.close(() => { + Category.downloadCategoriesCSV(policyId, () => { + setIsDownloadFailureModalVisible(true); + }); + }) }, }); } @@ -428,10 +430,10 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { title={translate('common.downloadFailedTitle')} prompt={translate('common.downloadFailedDescription')} isSmallScreenWidth={isSmallScreenWidth} - onSecondOptionSubmit={() => setDownloadFailureModalVisible(false)} + onSecondOptionSubmit={() => setIsDownloadFailureModalVisible(false)} secondOptionText={translate('common.buttonConfirm')} - isVisible={downloadFailureModalVisible} - onClose={() => setDownloadFailureModalVisible(false)} + isVisible={isDownloadFailureModalVisible} + onClose={() => setIsDownloadFailureModalVisible(false)} /> From 289faed1fe02641928ab97b27a959c8c092a1a3f Mon Sep 17 00:00:00 2001 From: cretadn22 Date: Wed, 18 Sep 2024 22:06:14 +0700 Subject: [PATCH 065/104] add comma --- src/pages/workspace/categories/WorkspaceCategoriesPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index 478510eae0a1..340bd991c609 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -327,7 +327,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { Category.downloadCategoriesCSV(policyId, () => { setIsDownloadFailureModalVisible(true); }); - }) + }); }, }); } From 0de8f42ed5080ac1ef0acbc3a0d5cb5edc60dc6a Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Wed, 18 Sep 2024 18:07:01 +0200 Subject: [PATCH 066/104] fix: change lodash imports --- src/components/ConnectionLayout.tsx | 2 +- src/components/ErrorMessageRow.tsx | 2 +- src/components/SelectionScreen.tsx | 2 +- src/components/VideoPlayer/BaseVideoPlayer.tsx | 2 +- src/hooks/useFetchRoute.ts | 2 +- src/languages/en.ts | 2 +- src/libs/Navigation/dismissModalWithReport.ts | 2 +- src/libs/Navigation/linkTo/index.ts | 2 +- src/libs/NetworkConnection.ts | 2 +- src/libs/ReportUtils.ts | 3 ++- src/libs/actions/Policy/Policy.ts | 2 +- src/libs/actions/Transaction.ts | 2 +- src/pages/home/report/comment/TextCommentFragment.tsx | 2 +- src/pages/iou/request/step/IOURequestStepDistance.tsx | 3 ++- .../intacct/export/SageIntacctPreferredExporterPage.tsx | 2 +- .../netsuite/export/NetSuitePreferredExporterSelectPage.tsx | 2 +- .../accounting/xero/export/XeroPreferredExporterSelectPage.tsx | 2 +- .../xero/export/XeroPurchaseBillStatusSelectorPage.tsx | 2 +- 18 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx index 3809b4f4f110..8646f3ce464a 100644 --- a/src/components/ConnectionLayout.tsx +++ b/src/components/ConnectionLayout.tsx @@ -1,4 +1,4 @@ -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {useMemo} from 'react'; import type {StyleProp, TextStyle, ViewStyle} from 'react-native'; import {View} from 'react-native'; diff --git a/src/components/ErrorMessageRow.tsx b/src/components/ErrorMessageRow.tsx index 2e6e41449274..7137def9a345 100644 --- a/src/components/ErrorMessageRow.tsx +++ b/src/components/ErrorMessageRow.tsx @@ -1,4 +1,4 @@ -import {mapValues} from 'lodash'; +import mapValues from 'lodash/mapValues'; import React from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; diff --git a/src/components/SelectionScreen.tsx b/src/components/SelectionScreen.tsx index b86084421fac..8382029bc12f 100644 --- a/src/components/SelectionScreen.tsx +++ b/src/components/SelectionScreen.tsx @@ -1,4 +1,4 @@ -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; import useLocalize from '@hooks/useLocalize'; diff --git a/src/components/VideoPlayer/BaseVideoPlayer.tsx b/src/components/VideoPlayer/BaseVideoPlayer.tsx index 1fd0fa4f669a..14943a42a9d8 100644 --- a/src/components/VideoPlayer/BaseVideoPlayer.tsx +++ b/src/components/VideoPlayer/BaseVideoPlayer.tsx @@ -1,7 +1,7 @@ /* eslint-disable no-underscore-dangle */ import type {AVPlaybackStatus, VideoFullscreenUpdateEvent} from 'expo-av'; import {ResizeMode, Video, VideoFullscreenUpdate} from 'expo-av'; -import {debounce} from 'lodash'; +import debounce from 'lodash/debounce'; import type {MutableRefObject} from 'react'; import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {GestureResponderEvent} from 'react-native'; diff --git a/src/hooks/useFetchRoute.ts b/src/hooks/useFetchRoute.ts index 736e99a31d66..4222f9f0183c 100644 --- a/src/hooks/useFetchRoute.ts +++ b/src/hooks/useFetchRoute.ts @@ -1,4 +1,4 @@ -import {isEqual} from 'lodash'; +import isEqual from 'lodash/isEqual'; import {useEffect} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import * as IOUUtils from '@libs/IOUUtils'; diff --git a/src/languages/en.ts b/src/languages/en.ts index a7ddea880161..4581ef33ed38 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1,5 +1,5 @@ import {CONST as COMMON_CONST, Str} from 'expensify-common'; -import {startCase} from 'lodash'; +import startCase from 'lodash/startCase'; import CONST from '@src/CONST'; import type {Country} from '@src/CONST'; import type {ConnectionName, PolicyConnectionSyncStage, SageIntacctMappingName} from '@src/types/onyx/Policy'; diff --git a/src/libs/Navigation/dismissModalWithReport.ts b/src/libs/Navigation/dismissModalWithReport.ts index 1579a0565726..854b2e586caf 100644 --- a/src/libs/Navigation/dismissModalWithReport.ts +++ b/src/libs/Navigation/dismissModalWithReport.ts @@ -1,7 +1,7 @@ import {getActionFromState} from '@react-navigation/core'; import type {NavigationContainerRef} from '@react-navigation/native'; import {StackActions} from '@react-navigation/native'; -import {findLastIndex} from 'lodash'; +import findLastIndex from 'lodash/findLastIndex'; import type {OnyxEntry} from 'react-native-onyx'; import Log from '@libs/Log'; import {isCentralPaneName} from '@libs/NavigationUtils'; diff --git a/src/libs/Navigation/linkTo/index.ts b/src/libs/Navigation/linkTo/index.ts index 1fc99c771ca5..3ca41846d2b4 100644 --- a/src/libs/Navigation/linkTo/index.ts +++ b/src/libs/Navigation/linkTo/index.ts @@ -1,7 +1,7 @@ import {getActionFromState} from '@react-navigation/core'; import type {NavigationContainerRef, NavigationState, PartialState} from '@react-navigation/native'; import {findFocusedRoute} from '@react-navigation/native'; -import {omitBy} from 'lodash'; +import omitBy from 'lodash/omitBy'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import isReportOpenInRHP from '@libs/Navigation/isReportOpenInRHP'; import {isCentralPaneName} from '@libs/NavigationUtils'; diff --git a/src/libs/NetworkConnection.ts b/src/libs/NetworkConnection.ts index c77ed94ca1bb..cb9faae31ddd 100644 --- a/src/libs/NetworkConnection.ts +++ b/src/libs/NetworkConnection.ts @@ -1,5 +1,5 @@ import NetInfo from '@react-native-community/netinfo'; -import {isBoolean} from 'lodash'; +import isBoolean from 'lodash/isBoolean'; import throttle from 'lodash/throttle'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index f37f3f940516..7e17dde901a5 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1,6 +1,7 @@ import {format} from 'date-fns'; import {Str} from 'expensify-common'; -import {isEmpty, isNumber} from 'lodash'; +import isNumber from 'lodash/isNumber'; +import isEmpty from 'lodash/isEmpty'; import lodashEscape from 'lodash/escape'; import lodashFindLastIndex from 'lodash/findLastIndex'; import lodashIntersection from 'lodash/intersection'; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index e30ddaf97e1f..df31b90c6831 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -1,6 +1,6 @@ import {PUBLIC_DOMAINS, Str} from 'expensify-common'; -import {escapeRegExp} from 'lodash'; import lodashClone from 'lodash/clone'; +import escapeRegExp from 'lodash/escapeRegExp'; import lodashUnion from 'lodash/union'; import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index d7223524b32b..e19251b62ce8 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -1,7 +1,7 @@ import {getUnixTime} from 'date-fns'; -import {isEqual} from 'lodash'; import lodashClone from 'lodash/clone'; import lodashHas from 'lodash/has'; +import isEqual from 'lodash/isEqual'; import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; diff --git a/src/pages/home/report/comment/TextCommentFragment.tsx b/src/pages/home/report/comment/TextCommentFragment.tsx index 2e64af6c534e..221e91b9ba4a 100644 --- a/src/pages/home/report/comment/TextCommentFragment.tsx +++ b/src/pages/home/report/comment/TextCommentFragment.tsx @@ -1,5 +1,5 @@ import {Str} from 'expensify-common'; -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {memo, useEffect} from 'react'; import type {StyleProp, TextStyle} from 'react-native'; import Text from '@components/Text'; diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 229d31959db7..14597df8e313 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -1,4 +1,5 @@ -import {isEmpty, isEqual} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; +import isEqual from 'lodash/isEqual'; import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; // eslint-disable-next-line no-restricted-imports diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx index 0617b8b690fe..25b42eca315b 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx @@ -1,4 +1,4 @@ -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import RadioListItem from '@components/SelectionList/RadioListItem'; diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx index b07a717a7abb..8e926995ec8e 100644 --- a/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx +++ b/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx @@ -1,4 +1,4 @@ -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import RadioListItem from '@components/SelectionList/RadioListItem'; diff --git a/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx index 23d178c725fe..ac3e37d60048 100644 --- a/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx +++ b/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx @@ -1,4 +1,4 @@ -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import RadioListItem from '@components/SelectionList/RadioListItem'; diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx index bf656da26fda..4d0af9eb26fb 100644 --- a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx +++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx @@ -1,4 +1,4 @@ -import {isEmpty} from 'lodash'; +import isEmpty from 'lodash/isEmpty'; import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import type {ValueOf} from 'type-fest'; From cbfa39eafaf9e30b9cda672178fe8fb8d2c6fa3c Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Wed, 18 Sep 2024 18:08:16 +0200 Subject: [PATCH 067/104] fix: remove unintented changes in `.github/actions/javascript/bumpVersion/index.js` --- .../actions/javascript/bumpVersion/index.js | 61 ++++++++++++++----- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/.github/actions/javascript/bumpVersion/index.js b/.github/actions/javascript/bumpVersion/index.js index 43bd09558c26..c8360931845a 100644 --- a/.github/actions/javascript/bumpVersion/index.js +++ b/.github/actions/javascript/bumpVersion/index.js @@ -1928,7 +1928,7 @@ class SemVer { do { const a = this.build[i] const b = other.build[i] - debug('prerelease compare', i, a, b) + debug('build compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { @@ -2154,6 +2154,10 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16 +// Max safe length for a build identifier. The max length minus 6 characters for +// the shortest version with a build 0.0.0+BUILD. +const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + const RELEASE_TYPES = [ 'major', 'premajor', @@ -2167,6 +2171,7 @@ const RELEASE_TYPES = [ module.exports = { MAX_LENGTH, MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, MAX_SAFE_INTEGER, RELEASE_TYPES, SEMVER_SPEC_VERSION, @@ -2248,7 +2253,11 @@ module.exports = parseOptions /***/ 9523: /***/ ((module, exports, __nccwpck_require__) => { -const { MAX_SAFE_COMPONENT_LENGTH } = __nccwpck_require__(2293) +const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, +} = __nccwpck_require__(2293) const debug = __nccwpck_require__(427) exports = module.exports = {} @@ -2259,16 +2268,31 @@ const src = exports.src = [] const t = exports.t = {} let R = 0 +const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`) + } + return value +} + const createToken = (name, value, isGlobal) => { - // Replace all greedy whitespace to prevent regex dos issues. These regex are - // used internally via the safeRe object since all inputs in this library get - // normalized first to trim and collapse all extra whitespace. The original - // regexes are exported for userland consumption and lower level usage. A - // future breaking change could export the safer regex only with a note that - // all input should have extra whitespace removed. - const safe = value - .split('\\s*').join('\\s{0,1}') - .split('\\s+').join('\\s') + const safe = makeSafeRegex(value) const index = R++ debug(name, index, value) t[name] = index @@ -2284,13 +2308,13 @@ const createToken = (name, value, isGlobal) => { // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') -createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') +createToken('NUMERICIDENTIFIERLOOSE', '\\d+') // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. -createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') +createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) // ## Main Version // Three dot-separated numeric identifiers. @@ -2325,7 +2349,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. -createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') +createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -2385,12 +2409,17 @@ createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) // Coercion. // Extract anything that could conceivably be a part of a valid semver -createToken('COERCE', `${'(^|[^\\d])' + +createToken('COERCEPLAIN', `${'(^|[^\\d])' + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) +createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) +createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + `(?:$|[^\\d])`) createToken('COERCERTL', src[t.COERCE], true) +createToken('COERCERTLFULL', src[t.COERCEFULL], true) // Tilde ranges. // Meaning is "reasonably at or greater than" From af507266110f20e05cd9fe742ce3d6ce22f3d4fe Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Wed, 18 Sep 2024 18:55:54 +0200 Subject: [PATCH 068/104] chore: lint files --- src/libs/ReportUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 7e17dde901a5..0b7d8c2ad2fc 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1,11 +1,11 @@ import {format} from 'date-fns'; import {Str} from 'expensify-common'; -import isNumber from 'lodash/isNumber'; -import isEmpty from 'lodash/isEmpty'; import lodashEscape from 'lodash/escape'; import lodashFindLastIndex from 'lodash/findLastIndex'; import lodashIntersection from 'lodash/intersection'; +import isEmpty from 'lodash/isEmpty'; import lodashIsEqual from 'lodash/isEqual'; +import isNumber from 'lodash/isNumber'; import lodashMaxBy from 'lodash/maxBy'; import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; From 684077ffcf459c3f63c74307224fa532cc9496ad Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Wed, 18 Sep 2024 23:58:33 +0700 Subject: [PATCH 069/104] fix: props object containing key is spread into jsx --- src/components/Form/InputWrapper.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index c966dd4456e9..f54009852b22 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -76,10 +76,16 @@ function InputWrapper(p const {registerInput} = useContext(FormContext); const {shouldSetTouchedOnBlurOnly, blurOnSubmit, shouldSubmitForm} = computeComponentSpecificRegistrationParams(props as InputComponentBaseProps); + const {key, ...registerInputProps} = registerInput(inputID, shouldSubmitForm, {ref, valueType, ...rest, shouldSetTouchedOnBlurOnly, blurOnSubmit}); - // TODO: Sometimes we return too many props with register input, so we need to consider if it's better to make the returned type more general and disregard the issue, or we would like to omit the unused props somehow. - // eslint-disable-next-line react/jsx-props-no-spreading - return ; + return ( + + ); } InputWrapper.displayName = 'InputWrapper'; From a3fb8392c2da69b03146e1882b41786fdf675280 Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Thu, 19 Sep 2024 02:24:07 +0700 Subject: [PATCH 070/104] fix: spread key prop warning in MenuItemList --- src/components/MenuItemList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MenuItemList.tsx b/src/components/MenuItemList.tsx index 2e732c691140..b5464aa9d9e8 100644 --- a/src/components/MenuItemList.tsx +++ b/src/components/MenuItemList.tsx @@ -82,7 +82,7 @@ function MenuItemList({ return ( <> - {menuItems.map((menuItemProps) => ( + {menuItems.map(({key, ...menuItemProps}) => ( secondaryInteraction(menuItemProps.link, e) : undefined} ref={popoverAnchor} From 29732647bc510d1a62b7457f50ec44227c50f3a0 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 19 Sep 2024 07:47:53 +0900 Subject: [PATCH 071/104] fix log calls --- .../SelectionList/Search/TransactionListItemRow.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/SelectionList/Search/TransactionListItemRow.tsx b/src/components/SelectionList/Search/TransactionListItemRow.tsx index 4a59b58a8273..f19105bd56dd 100644 --- a/src/components/SelectionList/Search/TransactionListItemRow.tsx +++ b/src/components/SelectionList/Search/TransactionListItemRow.tsx @@ -81,10 +81,13 @@ function ReceiptCell({transactionItem}: TransactionCellProps) { const backgroundStyles = transactionItem.isSelected ? StyleUtils.getBackgroundColorStyle(theme.buttonHoveredBG) : StyleUtils.getBackgroundColorStyle(theme.border); - const filename = getFileName(transactionItem?.receipt?.source ?? ''); - const receiptURIs = getThumbnailAndImageURIs(transactionItem, null, filename); - const isReceiptPDF = Str.isPDF(filename); - const source = tryResolveUrlFromApiRoot(isReceiptPDF && !receiptURIs.isLocalFile ? receiptURIs.thumbnail ?? '' : receiptURIs.image ?? ''); + let source = transactionItem?.receipt?.source ?? ''; + if (source) { + const filename = getFileName(transactionItem?.receipt?.source ?? ''); + const receiptURIs = getThumbnailAndImageURIs(transactionItem, null, filename); + const isReceiptPDF = Str.isPDF(filename); + source = tryResolveUrlFromApiRoot(isReceiptPDF && !receiptURIs.isLocalFile ? receiptURIs.thumbnail ?? '' : receiptURIs.image ?? ''); + } return ( Date: Thu, 19 Sep 2024 07:51:51 +0900 Subject: [PATCH 072/104] reuse variable --- src/components/SelectionList/Search/TransactionListItemRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SelectionList/Search/TransactionListItemRow.tsx b/src/components/SelectionList/Search/TransactionListItemRow.tsx index f19105bd56dd..7804ffa047f4 100644 --- a/src/components/SelectionList/Search/TransactionListItemRow.tsx +++ b/src/components/SelectionList/Search/TransactionListItemRow.tsx @@ -83,7 +83,7 @@ function ReceiptCell({transactionItem}: TransactionCellProps) { let source = transactionItem?.receipt?.source ?? ''; if (source) { - const filename = getFileName(transactionItem?.receipt?.source ?? ''); + const filename = getFileName(source); const receiptURIs = getThumbnailAndImageURIs(transactionItem, null, filename); const isReceiptPDF = Str.isPDF(filename); source = tryResolveUrlFromApiRoot(isReceiptPDF && !receiptURIs.isLocalFile ? receiptURIs.thumbnail ?? '' : receiptURIs.image ?? ''); From 631bd2aff94d2f7941c11d04ecc6a037a986d64d Mon Sep 17 00:00:00 2001 From: Rayane Djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Thu, 19 Sep 2024 01:01:07 +0100 Subject: [PATCH 073/104] don't skip jobs if one platform fails --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6ef9fe299510..cb797c9cb0b2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -482,7 +482,7 @@ jobs: createPrerelease: runs-on: ubuntu-latest - if: ${{ github.ref == 'refs/heads/staging' && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }} + if: ${{ always() && github.ref == 'refs/heads/staging' && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }} needs: [prep, checkDeploymentSuccess] steps: - name: Download all workflow run artifacts @@ -540,7 +540,7 @@ jobs: finalizeRelease: runs-on: ubuntu-latest - if: ${{ github.ref == 'refs/heads/production' && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }} + if: ${{ always() && github.ref == 'refs/heads/production' && fromJSON(needs.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED) }} needs: [prep, checkDeploymentSuccess] steps: - name: Download all workflow run artifacts From d4031c80ec5db0887d80e02638a2b601ce6f2d83 Mon Sep 17 00:00:00 2001 From: Rayane Djouah <77965000+rayane-djouah@users.noreply.github.com> Date: Thu, 19 Sep 2024 01:42:28 +0100 Subject: [PATCH 074/104] fix checkDeploymentSuccess job --- .github/workflows/deploy.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cb797c9cb0b2..2ab19d13183a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -455,30 +455,36 @@ jobs: checkDeploymentSuccess: runs-on: ubuntu-latest outputs: - IS_AT_LEAST_ONE_PLATFORM_DEPLOYED: ${{ steps.checkDeploymentSuccess.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED }} - IS_ALL_PLATFORMS_DEPLOYED: ${{ steps.checkDeploymentSuccess.outputs.IS_ALL_PLATFORMS_DEPLOYED }} + IS_AT_LEAST_ONE_PLATFORM_DEPLOYED: ${{ steps.checkDeploymentSuccessOnAtLeastOnePlatform.outputs.IS_AT_LEAST_ONE_PLATFORM_DEPLOYED }} + IS_ALL_PLATFORMS_DEPLOYED: ${{ steps.checkDeploymentSuccessOnAtLeastAllPlatform.outputs.IS_ALL_PLATFORMS_DEPLOYED }} needs: [android, desktop, iOS, web] if: ${{ always() }} steps: - name: Check deployment success on at least one platform - id: checkDeploymentSuccess + id: checkDeploymentSuccessOnAtLeastOnePlatform run: | isAtLeastOnePlatformDeployed="false" - isAllPlatformsDeployed="false" if [ "${{ needs.android.result }}" == "success" ] || \ [ "${{ needs.iOS.result }}" == "success" ] || \ [ "${{ needs.desktop.result }}" == "success" ] || \ [ "${{ needs.web.result }}" == "success" ]; then isAtLeastOnePlatformDeployed="true" fi + echo "IS_AT_LEAST_ONE_PLATFORM_DEPLOYED=$isAtLeastOnePlatformDeployed" >> "$GITHUB_OUTPUT" + echo "IS_AT_LEAST_ONE_PLATFORM_DEPLOYED is $isAtLeastOnePlatformDeployed" + + - name: Check deployment success on all platforms + id: checkDeploymentSuccessOnAtLeastAllPlatform + run: | + isAllPlatformsDeployed="false" if [ "${{ needs.android.result }}" == "success" ] && \ [ "${{ needs.iOS.result }}" == "success" ] && \ [ "${{ needs.desktop.result }}" == "success" ] && \ [ "${{ needs.web.result }}" == "success" ]; then isAllPlatformsDeployed="true" fi - echo "IS_AT_LEAST_ONE_PLATFORM_DEPLOYED=\"$isAtLeastOnePlatformDeployed\"" >> "$GITHUB_OUTPUT" - echo "IS_ALL_PLATFORMS_DEPLOYED=\"$isAllPlatformsDeployed\"" >> "$GITHUB_OUTPUT" + echo "IS_ALL_PLATFORMS_DEPLOYED=$isAllPlatformsDeployed" >> "$GITHUB_OUTPUT" + echo "IS_ALL_PLATFORMS_DEPLOYED is $isAllPlatformsDeployed" createPrerelease: runs-on: ubuntu-latest From 3bc40837efedd06f49e68fc7d1becdc807c5763a Mon Sep 17 00:00:00 2001 From: Jason Li <30815269+jliexpensify@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:31:16 +1000 Subject: [PATCH 075/104] Update Configure-Quickbooks-Desktop.md Added an info box to step 3 --- .../quickbooks-desktop/Configure-Quickbooks-Desktop.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md index d3dcda91ffcc..917c3c007b28 100644 --- a/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md +++ b/docs/articles/expensify-classic/connections/quickbooks-desktop/Configure-Quickbooks-Desktop.md @@ -42,6 +42,10 @@ The following steps help you determine the advanced settings for your connection 1. Click **Advanced** under the QuickBooks Desktop connection. 2. **Enable or disable Auto-Sync**: If enabled, QuickBooks Desktop automatically communicates changes with Expensify to ensure that the data shared between the two systems is up to date. New report approvals/reimbursements will be synced during the next auto-sync period. +{% include info.html %} +Please note that Auto-Sync will queue information to be added to your QuickBooks Company File the next time both your QuickBooks Company File and QuickBooks Web Connector are open. +{% include end-info.html %} + # FAQ ## **How do I manually sync my QuickBooks Desktop if I have Auto-Sync disabled?** From 94e6c2eb48f5d23c58613eb1cdbe427fa54c2d4a Mon Sep 17 00:00:00 2001 From: Jason Li <30815269+jliexpensify@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:46:13 +1000 Subject: [PATCH 076/104] Update Quickbooks-Desktop-Troubleshooting.md Added a section to the bottom - Reports not exporting to QBD --- .../Quickbooks-Desktop-Troubleshooting.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md b/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md index 09afd2e4e7f2..06f894ce7ef6 100644 --- a/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md +++ b/docs/articles/expensify-classic/connections/quickbooks-desktop/Quickbooks-Desktop-Troubleshooting.md @@ -89,3 +89,15 @@ If the problem persists, download the QuickBooks Desktop log file via the Web Co {% include info.html %} If you’re using a remote server (e.g. RightNetworks), you may need to contact that support team to request your logs. {% include end-info.html %} + +# Reports not exporting to QuickBooks Desktop + +Generally, this is the result of not having both the QuickBooks Web Connector and the Company File open, since the Report was exported. + +## How to resolve + +1. Make sure that the Web Connector and QuickBooks Desktop Company File are both open. +2. In the Web Connector, check that the Last Status is “Ok”. +3. Check the Report Comments in Expensify to confirm that the report has been successfully exported to QuickBooks Desktop. + +If these general troubleshooting steps don’t work, reach out to Concierge with your Expensify Report ID and a screenshot of your QuickBooks Web Connector. From 6a32eec6d95ca096d37e96cbada23dc6e4eb4234 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Thu, 19 Sep 2024 11:31:47 +0530 Subject: [PATCH 077/104] Fix warnings --- .../intacct/export/SageIntacctNonReimbursableExpensesPage.tsx | 3 ++- .../intacct/export/SageIntacctReimbursableExpensesPage.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx index a248bbfcb481..354111de1489 100644 --- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx +++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesPage.tsx @@ -105,9 +105,10 @@ function SageIntacctNonReimbursableExpensesPage({policy}: WithPolicyConnectionsP switch (item.type) { case 'toggle': // eslint-disable-next-line no-case-declarations - const {type, shouldHide, ...rest} = item; + const {type, shouldHide, key, ...rest} = item; return ( Date: Thu, 19 Sep 2024 10:42:54 +0200 Subject: [PATCH 078/104] rename connection --- src/libs/actions/Policy/Policy.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 79ae9a636870..50db00cc64df 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -71,7 +71,7 @@ import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; -import * as ReportAcionsConnection from '@libs/ReportActionsConnection'; +import * as ReportActionsConnection from '@libs/ReportActionsConnection'; import * as ReportConnection from '@libs/ReportConnection'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; @@ -2619,7 +2619,7 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF }); // We need to move the report preview action from the DM to the workspace chat. - const parentReport = ReportAcionsConnection.getAllReportActions()?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`]; + const parentReport = ReportActionsConnection.getAllReportActions()?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`]; const parentReportActionID = iouReport.parentReportActionID; const reportPreview = iouReport?.parentReportID && parentReportActionID ? parentReport?.[parentReportActionID] : undefined; From e5ad3d6549c2ee96dd0e5c4028b6c4b48fa84842 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Thu, 19 Sep 2024 15:46:44 +0700 Subject: [PATCH 079/104] revert extra changes --- src/components/LHNOptionsList/LHNOptionsList.tsx | 4 +--- src/components/LHNOptionsList/OptionRowLHNData.tsx | 3 --- src/components/LHNOptionsList/types.ts | 3 --- src/libs/OptionsListUtils.ts | 10 +++++----- src/libs/SidebarUtils.ts | 4 +--- src/libs/actions/IOU.ts | 2 -- tests/perf-test/SidebarUtils.perf-test.ts | 1 - 7 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index bad7fec04831..624e8f18e69e 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -132,7 +132,6 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio const iouReportIDOfLastAction = OptionsListUtils.getIOUReportIDOfLastAction(itemFullReport); const itemIouReportReportActions = iouReportIDOfLastAction ? reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportIDOfLastAction}`] : undefined; - const itemIouReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportIDOfLastAction}`]; const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`]; const transactionID = ReportActionsUtils.isMoneyRequestAction(itemParentReportAction) @@ -163,7 +162,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio } : null; } - const lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(itemFullReport, itemIouReport, lastActorDetails, itemPolicy); + const lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(itemFullReport, lastActorDetails, itemPolicy); return ( ; - /** IOU report related to the last action of this report */ - iouReport: OnyxEntry; - /** List of transaction violation */ transactionViolations: OnyxCollection; diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index a08f167f61d3..afedd308371c 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -588,7 +588,7 @@ function getIOUReportIDOfLastAction(report: OnyxEntry): string | undefin /** * Get the last message text from the report directly or from other sources for special cases. */ -function getLastMessageTextForReport(report: OnyxEntry, iouReport: OnyxEntry, lastActorDetails: Partial | null, policy?: OnyxEntry): string { +function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails: Partial | null, policy?: OnyxEntry): string { const reportID = report?.reportID ?? '-1'; const lastReportAction = lastVisibleReportActions[reportID] ?? null; @@ -622,15 +622,15 @@ function getLastMessageTextForReport(report: OnyxEntry, iouReport: OnyxE const properSchemaForMoneyRequestMessage = ReportUtils.getReportPreviewMessage(report, lastReportAction, true, false, null, true); lastMessageTextFromReport = ReportUtils.formatReportLastMessageText(properSchemaForMoneyRequestMessage); } else if (ReportActionUtils.isReportPreviewAction(lastReportAction)) { - const iouReportValue = iouReport ?? ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); - const lastIOUMoneyReportAction = allSortedReportActions[iouReportValue?.reportID ?? '-1']?.find( + const iouReport = ReportUtils.getReportOrDraftReport(ReportActionUtils.getIOUReportIDFromReportActionPreview(lastReportAction)); + const lastIOUMoneyReportAction = allSortedReportActions[iouReport?.reportID ?? '-1']?.find( (reportAction, key): reportAction is ReportAction => ReportActionUtils.shouldReportActionBeVisible(reportAction, key) && reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && ReportActionUtils.isMoneyRequestAction(reportAction), ); const reportPreviewMessage = ReportUtils.getReportPreviewMessage( - !isEmptyObject(iouReportValue) ? iouReportValue : null, + !isEmptyObject(iouReport) ? iouReport : null, lastIOUMoneyReportAction, true, ReportUtils.isChatReport(report), @@ -764,7 +764,7 @@ function createOption( const lastActorDetails = personalDetailMap[report.lastActorAccountID ?? -1] ?? null; const lastActorDisplayName = getLastActorDisplayName(lastActorDetails, hasMultipleParticipants); - const lastMessageTextFromReport = getLastMessageTextForReport(report, undefined, lastActorDetails); + const lastMessageTextFromReport = getLastMessageTextForReport(report, lastActorDetails); let lastMessageText = lastMessageTextFromReport; const lastAction = lastVisibleReportActions[report.reportID]; diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 8fc17dcf5339..d056f111695e 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -234,7 +234,6 @@ function getOrderedReportIDs( */ function getOptionData({ report, - iouReport, reportActions, personalDetails, preferredLocale, @@ -246,7 +245,6 @@ function getOptionData({ invoiceReceiverPolicy, }: { report: OnyxEntry; - iouReport: OnyxEntry; reportActions: OnyxEntry; personalDetails: OnyxEntry; preferredLocale: DeepValueOf; @@ -392,7 +390,7 @@ function getOptionData({ let lastMessageTextFromReport = lastMessageTextFromReportProp; if (!lastMessageTextFromReport) { - lastMessageTextFromReport = OptionsListUtils.getLastMessageTextForReport(report, iouReport, lastActorDetails, policy); + 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. diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 7c45cab582c4..6f694fd41403 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6745,7 +6745,6 @@ function getPayMoneyRequestParams( key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, value: { ...iouReport, - total, lastMessageText: ReportActionsUtils.getReportActionText(optimisticIOUReportAction), lastMessageHtml: ReportActionsUtils.getReportActionHtml(optimisticIOUReportAction), hasOutstandingChildRequest: false, @@ -7049,7 +7048,6 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.reportID}`, value: { ...expenseReport, - total, lastMessageText: ReportActionsUtils.getReportActionText(optimisticApprovedReportAction), lastMessageHtml: ReportActionsUtils.getReportActionHtml(optimisticApprovedReportAction), stateNum: predictedNextState, diff --git a/tests/perf-test/SidebarUtils.perf-test.ts b/tests/perf-test/SidebarUtils.perf-test.ts index 47595b207277..4a6b12d726d9 100644 --- a/tests/perf-test/SidebarUtils.perf-test.ts +++ b/tests/perf-test/SidebarUtils.perf-test.ts @@ -102,7 +102,6 @@ describe('SidebarUtils', () => { await measureFunction(() => SidebarUtils.getOptionData({ report, - iouReport: undefined, reportActions, personalDetails, preferredLocale, From aeacfe0b0a42ea9f5eaae0aa5d6f3366fc38df51 Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Thu, 19 Sep 2024 15:15:55 +0200 Subject: [PATCH 080/104] chore: build github actions --- .../actions/javascript/bumpVersion/index.js | 61 +++++-------------- 1 file changed, 16 insertions(+), 45 deletions(-) diff --git a/.github/actions/javascript/bumpVersion/index.js b/.github/actions/javascript/bumpVersion/index.js index c8360931845a..43bd09558c26 100644 --- a/.github/actions/javascript/bumpVersion/index.js +++ b/.github/actions/javascript/bumpVersion/index.js @@ -1928,7 +1928,7 @@ class SemVer { do { const a = this.build[i] const b = other.build[i] - debug('build compare', i, a, b) + debug('prerelease compare', i, a, b) if (a === undefined && b === undefined) { return 0 } else if (b === undefined) { @@ -2154,10 +2154,6 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16 -// Max safe length for a build identifier. The max length minus 6 characters for -// the shortest version with a build 0.0.0+BUILD. -const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 - const RELEASE_TYPES = [ 'major', 'premajor', @@ -2171,7 +2167,6 @@ const RELEASE_TYPES = [ module.exports = { MAX_LENGTH, MAX_SAFE_COMPONENT_LENGTH, - MAX_SAFE_BUILD_LENGTH, MAX_SAFE_INTEGER, RELEASE_TYPES, SEMVER_SPEC_VERSION, @@ -2253,11 +2248,7 @@ module.exports = parseOptions /***/ 9523: /***/ ((module, exports, __nccwpck_require__) => { -const { - MAX_SAFE_COMPONENT_LENGTH, - MAX_SAFE_BUILD_LENGTH, - MAX_LENGTH, -} = __nccwpck_require__(2293) +const { MAX_SAFE_COMPONENT_LENGTH } = __nccwpck_require__(2293) const debug = __nccwpck_require__(427) exports = module.exports = {} @@ -2268,31 +2259,16 @@ const src = exports.src = [] const t = exports.t = {} let R = 0 -const LETTERDASHNUMBER = '[a-zA-Z0-9-]' - -// Replace some greedy regex tokens to prevent regex dos issues. These regex are -// used internally via the safeRe object since all inputs in this library get -// normalized first to trim and collapse all extra whitespace. The original -// regexes are exported for userland consumption and lower level usage. A -// future breaking change could export the safer regex only with a note that -// all input should have extra whitespace removed. -const safeRegexReplacements = [ - ['\\s', 1], - ['\\d', MAX_LENGTH], - [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], -] - -const makeSafeRegex = (value) => { - for (const [token, max] of safeRegexReplacements) { - value = value - .split(`${token}*`).join(`${token}{0,${max}}`) - .split(`${token}+`).join(`${token}{1,${max}}`) - } - return value -} - const createToken = (name, value, isGlobal) => { - const safe = makeSafeRegex(value) + // Replace all greedy whitespace to prevent regex dos issues. These regex are + // used internally via the safeRe object since all inputs in this library get + // normalized first to trim and collapse all extra whitespace. The original + // regexes are exported for userland consumption and lower level usage. A + // future breaking change could export the safer regex only with a note that + // all input should have extra whitespace removed. + const safe = value + .split('\\s*').join('\\s{0,1}') + .split('\\s+').join('\\s') const index = R++ debug(name, index, value) t[name] = index @@ -2308,13 +2284,13 @@ const createToken = (name, value, isGlobal) => { // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') -createToken('NUMERICIDENTIFIERLOOSE', '\\d+') +createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. -createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) +createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') // ## Main Version // Three dot-separated numeric identifiers. @@ -2349,7 +2325,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. -createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) +createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -2409,17 +2385,12 @@ createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) // Coercion. // Extract anything that could conceivably be a part of a valid semver -createToken('COERCEPLAIN', `${'(^|[^\\d])' + +createToken('COERCE', `${'(^|[^\\d])' + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) -createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) -createToken('COERCEFULL', src[t.COERCEPLAIN] + - `(?:${src[t.PRERELEASE]})?` + - `(?:${src[t.BUILD]})?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + `(?:$|[^\\d])`) createToken('COERCERTL', src[t.COERCE], true) -createToken('COERCERTLFULL', src[t.COERCEFULL], true) // Tilde ranges. // Meaning is "reasonably at or greater than" From 6b71989b8c34d495ca59a1ddaea7f4c313b24eea Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Thu, 19 Sep 2024 20:28:56 +0700 Subject: [PATCH 081/104] do not spread key in MenuItemList --- src/components/MenuItemList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MenuItemList.tsx b/src/components/MenuItemList.tsx index 7b71e7cb27c2..d33a17f90a5e 100644 --- a/src/components/MenuItemList.tsx +++ b/src/components/MenuItemList.tsx @@ -84,7 +84,7 @@ function MenuItemList({ <> {menuItems.map(({key, ...menuItemProps}) => ( Date: Thu, 19 Sep 2024 15:40:34 +0100 Subject: [PATCH 082/104] fix private personal details loading --- src/pages/settings/Profile/ProfilePage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/settings/Profile/ProfilePage.tsx b/src/pages/settings/Profile/ProfilePage.tsx index 83fcdefb3529..ce4f2aec88d0 100755 --- a/src/pages/settings/Profile/ProfilePage.tsx +++ b/src/pages/settings/Profile/ProfilePage.tsx @@ -45,7 +45,7 @@ function ProfilePage() { const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); - const isLoadingApp = useOnyx(ONYXKEYS.IS_LOADING_APP); + const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP); const getPronouns = (): string => { const pronounsKey = currentUserPersonalDetails?.pronouns?.replace(CONST.PRONOUNS.PREFIX, '') ?? ''; From d96de1fa5576559418fc998988c5a049d22ce844 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 19 Sep 2024 20:29:58 +0530 Subject: [PATCH 083/104] fix: Distance rates - Change Rate to default leads to app crash. Signed-off-by: krishna2323 --- src/libs/actions/IOU.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 65cff5baf54a..94ea4ec81123 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3159,7 +3159,9 @@ function updateMoneyRequestDescription( data = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories, true); } const {params, onyxData} = data; - API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DESCRIPTION, params, onyxData); + // `taxAmount` & `taxCode` only needs to be updated in the optimistic data, so we need to remove them from the params object + const {taxAmount, taxCode, ...paramsWithoutTaxUpdated} = params; + API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DESCRIPTION, paramsWithoutTaxUpdated, onyxData); } /** Updates the distance rate of an expense */ From 533bba7b59dc48794b2d2a71bc6f25f869c86e3d Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 19 Sep 2024 20:56:26 +0530 Subject: [PATCH 084/104] minor update. Signed-off-by: krishna2323 --- src/libs/actions/IOU.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 94ea4ec81123..a16355cc478b 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3159,9 +3159,8 @@ function updateMoneyRequestDescription( data = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories, true); } const {params, onyxData} = data; - // `taxAmount` & `taxCode` only needs to be updated in the optimistic data, so we need to remove them from the params object - const {taxAmount, taxCode, ...paramsWithoutTaxUpdated} = params; - API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DESCRIPTION, paramsWithoutTaxUpdated, onyxData); + + API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DESCRIPTION, params, onyxData); } /** Updates the distance rate of an expense */ @@ -3172,13 +3171,13 @@ function updateMoneyRequestDistanceRate( policy: OnyxEntry, policyTagList: OnyxEntry, policyCategories: OnyxEntry, - taxAmount?: number, - taxCode?: string, + updatedTaxAmount?: number, + updatedTaxCode?: string, ) { const transactionChanges: TransactionChanges = { customUnitRateID: rateID, - ...(taxAmount ? {taxAmount} : {}), - ...(taxCode ? {taxCode} : {}), + ...(updatedTaxAmount ? {taxAmount: updatedTaxAmount} : {}), + ...(updatedTaxCode ? {taxCode: updatedTaxCode} : {}), }; const allReports = ReportConnection.getAllReports(); const transactionThreadReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; @@ -3190,7 +3189,9 @@ function updateMoneyRequestDistanceRate( data = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories, true); } const {params, onyxData} = data; - API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DISTANCE_RATE, params, onyxData); + // `taxAmount` & `taxCode` only needs to be updated in the optimistic data, so we need to remove them from the params + const {taxAmount, taxCode, ...paramsWithoutTaxUpdated} = params; + API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DISTANCE_RATE, paramsWithoutTaxUpdated, onyxData); } /** Edits an existing distance expense */ From 67e28f5f6ec03e7ca3cda78497b80a94ec14385f Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 19 Sep 2024 21:26:27 +0530 Subject: [PATCH 085/104] minor fix. Signed-off-by: krishna2323 --- src/libs/actions/IOU.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a16355cc478b..ad1b08b101e8 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3176,7 +3176,7 @@ function updateMoneyRequestDistanceRate( ) { const transactionChanges: TransactionChanges = { customUnitRateID: rateID, - ...(updatedTaxAmount ? {taxAmount: updatedTaxAmount} : {}), + ...(typeof updatedTaxAmount === 'number' ? {taxAmount: updatedTaxAmount} : {}), ...(updatedTaxCode ? {taxCode: updatedTaxCode} : {}), }; const allReports = ReportConnection.getAllReports(); From ce02d0e11d54a974945f001014fa9fa41b50abc4 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 19 Sep 2024 21:32:42 +0530 Subject: [PATCH 086/104] remove extra space. Signed-off-by: krishna2323 --- src/libs/actions/IOU.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index ad1b08b101e8..76376bba7eef 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3159,7 +3159,6 @@ function updateMoneyRequestDescription( data = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, policy, policyTagList, policyCategories, true); } const {params, onyxData} = data; - API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DESCRIPTION, params, onyxData); } From 6b99d02cf0f9dff0e274aa88d6aeb1b450753fac Mon Sep 17 00:00:00 2001 From: OSBotify Date: Thu, 19 Sep 2024 16:21:28 +0000 Subject: [PATCH 087/104] Update version to 9.0.38-1 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 75775aca06de..4e916a6c8842 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009003800 - versionName "9.0.38-0" + versionCode 1009003801 + versionName "9.0.38-1" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 1d7be504fd51..fa5101c66741 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.38.0 + 9.0.38.1 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index e4243d03b774..68c87e2b6637 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 9.0.38.0 + 9.0.38.1 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 1133bfbb4a0e..8f91128a947f 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.0.38 CFBundleVersion - 9.0.38.0 + 9.0.38.1 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 9ad25be47e38..03c2073ba055 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.38-0", + "version": "9.0.38-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.38-0", + "version": "9.0.38-1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 180ccba24a8b..e2a7421ade01 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.38-0", + "version": "9.0.38-1", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 962541e3aea5b9d4ade8e8e7d6e5db8927ac86dd Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Thu, 19 Sep 2024 23:24:50 +0530 Subject: [PATCH 088/104] fixes optimistc case and delay submission current user bad grammar --- src/libs/NextStepUtils.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 6dc12d6d1211..9f1b8ac7466b 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -38,14 +38,16 @@ Onyx.connect({ function parseMessage(messages: Message[] | undefined) { let nextStepHTML = ''; - messages?.forEach((part) => { + messages?.forEach((part, index) => { const isEmail = Str.isValidEmail(part.text); let tagType = part.type ?? 'span'; let content = Str.safeEscape(part.text); if (currentUserEmail === part.text || part.clickToCopyText === currentUserEmail) { tagType = 'strong'; - content = 'You'; + content = messages[index + 1].text === `'s` ? 'Your' : 'You'; + } else if (part.text === `'s` && (messages[index - 1].text === currentUserEmail || messages[index - 1].clickToCopyText === currentUserEmail)) { + content = ''; } else if (isEmail) { tagType = 'next-step-email'; content = EmailUtils.prefixMailSeparatorsWithBreakOpportunities(content); @@ -65,15 +67,15 @@ function parseMessage(messages: Message[] | undefined) { function getNextApproverDisplayName(policy: Policy, ownerAccountID: number, submitToAccountID: number, report: OnyxEntry) { const approvalChain = ReportUtils.getApprovalChain(policy, ownerAccountID, report?.total ?? 0); if (approvalChain.length === 0) { - return ReportUtils.getDisplayNameForParticipant(submitToAccountID); + return submitToAccountID === currentUserAccountID ? 'You' : ReportUtils.getDisplayNameForParticipant(submitToAccountID); } const nextApproverEmail = approvalChain.length === 1 ? approvalChain[0] : approvalChain[approvalChain.indexOf(currentUserEmail) + 1]; if (!nextApproverEmail) { - return ReportUtils.getDisplayNameForParticipant(submitToAccountID); + return submitToAccountID === currentUserAccountID ? 'You' : ReportUtils.getDisplayNameForParticipant(submitToAccountID); } - return PersonalDetailsUtils.getPersonalDetailByEmail(nextApproverEmail)?.displayName ?? nextApproverEmail; + return nextApproverEmail === currentUserEmail ? 'You' : PersonalDetailsUtils.getPersonalDetailByEmail(nextApproverEmail)?.displayName ?? nextApproverEmail; } /** @@ -98,9 +100,10 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf, predictedNextStatus: ValueOf, predictedNextStatus: ValueOf, predictedNextStatus: ValueOf Date: Thu, 19 Sep 2024 18:01:40 +0000 Subject: [PATCH 089/104] Update version to 9.0.38-2 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4e916a6c8842..52d38bf09122 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009003801 - versionName "9.0.38-1" + versionCode 1009003802 + versionName "9.0.38-2" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index fa5101c66741..f1b70749fcc2 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.38.1 + 9.0.38.2 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 68c87e2b6637..e9e228402364 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 9.0.38.1 + 9.0.38.2 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 8f91128a947f..7faad6d02883 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.0.38 CFBundleVersion - 9.0.38.1 + 9.0.38.2 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 03c2073ba055..9a385555d664 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.38-1", + "version": "9.0.38-2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.38-1", + "version": "9.0.38-2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index e2a7421ade01..f2df305294b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.38-1", + "version": "9.0.38-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 98dc643e14378f654e45a7ce96f35be9f407c007 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Thu, 19 Sep 2024 18:09:55 +0000 Subject: [PATCH 090/104] Update version to 9.0.38-3 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 52d38bf09122..f8eeed65eda6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009003802 - versionName "9.0.38-2" + versionCode 1009003803 + versionName "9.0.38-3" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index f1b70749fcc2..7c6546849327 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.38.2 + 9.0.38.3 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index e9e228402364..edd197041278 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 9.0.38.2 + 9.0.38.3 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 7faad6d02883..ec26f3390a38 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.0.38 CFBundleVersion - 9.0.38.2 + 9.0.38.3 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 9a385555d664..6a5ae0c2534f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.38-2", + "version": "9.0.38-3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.38-2", + "version": "9.0.38-3", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index f2df305294b4..1aafc3d6f323 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.38-2", + "version": "9.0.38-3", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 152dbd97adcd857a7c371842817f3f1a0e9af5d8 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 20 Sep 2024 00:08:36 +0530 Subject: [PATCH 091/104] resolve comments --- src/libs/NextStepUtils.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 9f1b8ac7466b..7b2df19580f9 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -43,10 +43,13 @@ function parseMessage(messages: Message[] | undefined) { let tagType = part.type ?? 'span'; let content = Str.safeEscape(part.text); + const previousPart = messages[index - 1]; + const nextPart = messages[index + 1]; + if (currentUserEmail === part.text || part.clickToCopyText === currentUserEmail) { tagType = 'strong'; - content = messages[index + 1].text === `'s` ? 'Your' : 'You'; - } else if (part.text === `'s` && (messages[index - 1].text === currentUserEmail || messages[index - 1].clickToCopyText === currentUserEmail)) { + content = nextPart.text === `'s` ? 'Your' : 'You'; + } else if (part.text === `'s` && (previousPart?.text === currentUserEmail || previousPart?.clickToCopyText === currentUserEmail)) { content = ''; } else if (isEmail) { tagType = 'next-step-email'; @@ -67,15 +70,15 @@ function parseMessage(messages: Message[] | undefined) { function getNextApproverDisplayName(policy: Policy, ownerAccountID: number, submitToAccountID: number, report: OnyxEntry) { const approvalChain = ReportUtils.getApprovalChain(policy, ownerAccountID, report?.total ?? 0); if (approvalChain.length === 0) { - return submitToAccountID === currentUserAccountID ? 'You' : ReportUtils.getDisplayNameForParticipant(submitToAccountID); + return ReportUtils.getDisplayNameForParticipant(submitToAccountID); } const nextApproverEmail = approvalChain.length === 1 ? approvalChain[0] : approvalChain[approvalChain.indexOf(currentUserEmail) + 1]; if (!nextApproverEmail) { - return submitToAccountID === currentUserAccountID ? 'You' : ReportUtils.getDisplayNameForParticipant(submitToAccountID); + return ReportUtils.getDisplayNameForParticipant(submitToAccountID); } - return nextApproverEmail === currentUserEmail ? 'You' : PersonalDetailsUtils.getPersonalDetailByEmail(nextApproverEmail)?.displayName ?? nextApproverEmail; + return PersonalDetailsUtils.getPersonalDetailByEmail(nextApproverEmail)?.displayName ?? nextApproverEmail; } /** @@ -103,7 +106,6 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf, predictedNextStatus: ValueOf, predictedNextStatus: ValueOf Date: Fri, 20 Sep 2024 00:13:16 +0530 Subject: [PATCH 092/104] resolve comments --- src/libs/NextStepUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 7b2df19580f9..6519c9c776fd 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -103,7 +103,7 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf Date: Fri, 20 Sep 2024 00:14:12 +0530 Subject: [PATCH 093/104] seperate 's --- src/libs/NextStepUtils.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 6519c9c776fd..a036503f5f14 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -140,9 +140,13 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf Date: Fri, 20 Sep 2024 00:15:15 +0530 Subject: [PATCH 094/104] lint fix --- src/libs/NextStepUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index a036503f5f14..543f76f07174 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -145,7 +145,7 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf Date: Fri, 20 Sep 2024 00:23:10 +0530 Subject: [PATCH 095/104] handle optimistic case --- src/libs/NextStepUtils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 543f76f07174..cc63d7837e1f 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -48,7 +48,7 @@ function parseMessage(messages: Message[] | undefined) { if (currentUserEmail === part.text || part.clickToCopyText === currentUserEmail) { tagType = 'strong'; - content = nextPart.text === `'s` ? 'Your' : 'You'; + content = nextPart?.text === `'s` ? 'Your' : 'You'; } else if (part.text === `'s` && (previousPart?.text === currentUserEmail || previousPart?.clickToCopyText === currentUserEmail)) { content = ''; } else if (isEmail) { @@ -121,6 +121,7 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf, predictedNextStatus: ValueOf Date: Fri, 20 Sep 2024 00:32:50 +0530 Subject: [PATCH 096/104] fix tests --- tests/unit/NextStepUtilsTest.ts | 61 ++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index 2b915fcfc4f0..fd03a36c66ee 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -1,15 +1,15 @@ -import {format, lastDayOfMonth, setDate} from 'date-fns'; +import { format, lastDayOfMonth, setDate } from 'date-fns'; import Onyx from 'react-native-onyx'; import DateUtils from '@libs/DateUtils'; import * as NextStepUtils from '@libs/NextStepUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Policy, Report, ReportNextStep} from '@src/types/onyx'; -import {toCollectionDataSet} from '@src/types/utils/CollectionDataSet'; +import type { Policy, Report, ReportNextStep } from '@src/types/onyx'; +import { toCollectionDataSet } from '@src/types/utils/CollectionDataSet'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -Onyx.init({keys: ONYXKEYS}); +Onyx.init({ keys: ONYXKEYS }); describe('libs/NextStepUtils', () => { describe('buildNextStep', () => { @@ -44,7 +44,7 @@ describe('libs/NextStepUtils', () => { const policyCollectionDataSet = toCollectionDataSet(ONYXKEYS.COLLECTION.POLICY, [policy], (item) => item.id); Onyx.multiSet({ - [ONYXKEYS.SESSION]: {email: currentUserEmail, accountID: currentUserAccountID}, + [ONYXKEYS.SESSION]: { email: currentUserEmail, accountID: currentUserAccountID }, [ONYXKEYS.PERSONAL_DETAILS_LIST]: { [strangeAccountID]: { accountID: strangeAccountID, @@ -113,7 +113,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -143,7 +148,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -173,7 +183,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -203,7 +218,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -234,7 +254,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -267,7 +292,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -298,7 +328,12 @@ describe('libs/NextStepUtils', () => { text: 'Waiting for ', }, { - text: `${currentUserEmail}'s`, + text: `${currentUserEmail}`, + clickToCopyText: `${currentUserEmail}`, + type: 'strong', + }, + { + text: "'s", type: 'strong', }, { @@ -515,7 +550,7 @@ describe('libs/NextStepUtils', () => { }, ]; // mock the report as approved - const originalState = {stateNum: report.stateNum, statusNum: report.statusNum}; + const originalState = { stateNum: report.stateNum, statusNum: report.statusNum }; report.stateNum = CONST.REPORT.STATE_NUM.APPROVED; report.statusNum = CONST.REPORT.STATUS_NUM.APPROVED; From 5ae21d1b108cbcf060a662042921e6c5adae29a7 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 20 Sep 2024 00:34:17 +0530 Subject: [PATCH 097/104] format with prettier --- tests/unit/NextStepUtilsTest.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index fd03a36c66ee..7777f04c92d7 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -1,15 +1,15 @@ -import { format, lastDayOfMonth, setDate } from 'date-fns'; +import {format, lastDayOfMonth, setDate} from 'date-fns'; import Onyx from 'react-native-onyx'; import DateUtils from '@libs/DateUtils'; import * as NextStepUtils from '@libs/NextStepUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type { Policy, Report, ReportNextStep } from '@src/types/onyx'; -import { toCollectionDataSet } from '@src/types/utils/CollectionDataSet'; +import type {Policy, Report, ReportNextStep} from '@src/types/onyx'; +import {toCollectionDataSet} from '@src/types/utils/CollectionDataSet'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -Onyx.init({ keys: ONYXKEYS }); +Onyx.init({keys: ONYXKEYS}); describe('libs/NextStepUtils', () => { describe('buildNextStep', () => { @@ -44,7 +44,7 @@ describe('libs/NextStepUtils', () => { const policyCollectionDataSet = toCollectionDataSet(ONYXKEYS.COLLECTION.POLICY, [policy], (item) => item.id); Onyx.multiSet({ - [ONYXKEYS.SESSION]: { email: currentUserEmail, accountID: currentUserAccountID }, + [ONYXKEYS.SESSION]: {email: currentUserEmail, accountID: currentUserAccountID}, [ONYXKEYS.PERSONAL_DETAILS_LIST]: { [strangeAccountID]: { accountID: strangeAccountID, @@ -550,7 +550,7 @@ describe('libs/NextStepUtils', () => { }, ]; // mock the report as approved - const originalState = { stateNum: report.stateNum, statusNum: report.statusNum }; + const originalState = {stateNum: report.stateNum, statusNum: report.statusNum}; report.stateNum = CONST.REPORT.STATE_NUM.APPROVED; report.statusNum = CONST.REPORT.STATUS_NUM.APPROVED; From 83f9fdfc069ab74074e32bcbc13bc7b600267e2f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh <104348397+ishpaul777@users.noreply.github.com> Date: Fri, 20 Sep 2024 00:54:50 +0530 Subject: [PATCH 098/104] add space --- src/libs/NextStepUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index cc63d7837e1f..7f13e1297b6f 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -134,6 +134,7 @@ function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf Date: Thu, 19 Sep 2024 20:20:43 +0000 Subject: [PATCH 099/104] Update version to 9.0.38-4 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index f8eeed65eda6..dd4f5b661e66 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009003803 - versionName "9.0.38-3" + versionCode 1009003804 + versionName "9.0.38-4" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 7c6546849327..a01d4fe324b5 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.38.3 + 9.0.38.4 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index edd197041278..42ecfefe8df0 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 9.0.38.3 + 9.0.38.4 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index ec26f3390a38..9cc5961cc9ac 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 9.0.38 CFBundleVersion - 9.0.38.3 + 9.0.38.4 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 6a5ae0c2534f..cee9869929dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.38-3", + "version": "9.0.38-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.38-3", + "version": "9.0.38-4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 1aafc3d6f323..cc38b5b9bbd9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.38-3", + "version": "9.0.38-4", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From 2c8485d835d60217d5be82922abdb28664eccc14 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 19 Sep 2024 17:07:49 -0400 Subject: [PATCH 100/104] use isThread for checks --- src/libs/ReportUtils.ts | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index dc0b444850f4..8b5c930e5314 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -491,6 +491,11 @@ type ParsingDetails = { policyID?: string; }; +type Thread = { + parentReportID: string; + parentReportActionID: string; +} & Report; + let currentUserEmail: string | undefined; let currentUserPrivateDomain: string | undefined; let currentUserAccountID: number | undefined; @@ -1111,14 +1116,14 @@ function isWorkspaceTaskReport(report: OnyxEntry): boolean { /** * Returns true if report has a parent */ -function isThread(report: OnyxInputOrEntry): boolean { +function isThread(report: OnyxInputOrEntry): report is Thread { return !!(report?.parentReportID && report?.parentReportActionID); } /** * Returns true if report is of type chat and has a parent and is therefore a Thread. */ -function isChatThread(report: OnyxInputOrEntry): boolean { +function isChatThread(report: OnyxInputOrEntry): report is Thread { return isThread(report) && report?.type === CONST.REPORT.TYPE.CHAT; } @@ -1535,7 +1540,7 @@ function isChildReport(report: OnyxEntry): boolean { * the parentReportAction is a transaction. */ function isExpenseRequest(report: OnyxInputOrEntry): boolean { - if (isThread(report) && report?.parentReportID && report.parentReportActionID) { + if (isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isExpenseReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); @@ -1548,7 +1553,7 @@ function isExpenseRequest(report: OnyxInputOrEntry): boolean { * the parentReportAction is a transaction. */ function isIOURequest(report: OnyxInputOrEntry): boolean { - if (isThread(report) && report?.parentReportID && report.parentReportActionID) { + if (isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isIOUReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); @@ -1561,7 +1566,7 @@ function isIOURequest(report: OnyxInputOrEntry): boolean { * parentReportAction has type of track. */ function isTrackExpenseReport(report: OnyxInputOrEntry): boolean { - if (isThread(report) && report?.parentReportID && report.parentReportActionID) { + if (isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; return !isEmptyObject(parentReportAction) && ReportActionsUtils.isTrackExpenseAction(parentReportAction); } @@ -2210,7 +2215,7 @@ function getIcons( }; return [fallbackIcon]; } - if (isExpenseRequest(report) && report?.parentReportID && report.parentReportActionID) { + if (isExpenseRequest(report) && isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const workspaceIcon = getWorkspaceIcon(report, policy); const memberIcon = { @@ -2223,7 +2228,7 @@ function getIcons( return [memberIcon, workspaceIcon]; } - if (isChatThread(report) && report?.parentReportID && report.parentReportActionID) { + if (isChatThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const actorAccountID = getReportActionActorAccountID(parentReportAction, report); @@ -3106,7 +3111,7 @@ function canHoldUnholdReportAction(reportAction: OnyxInputOrEntry) const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction); const parentReportAction = - moneyRequestReport?.parentReportID && moneyRequestReport.parentReportActionID + isThread(moneyRequestReport) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${moneyRequestReport.parentReportID}`]?.[moneyRequestReport.parentReportActionID] : undefined; @@ -3718,7 +3723,7 @@ function getReportName( let parentReportAction: OnyxEntry | undefined; if (parentReportActionParam) { parentReportAction = - report?.parentReportID && report.parentReportActionID + isThread(report) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; } @@ -6005,7 +6010,7 @@ function shouldReportBeInOptionList({ // Optionally exclude reports that do not belong to currently active workspace const parentReportAction = - report?.parentReportID && report.parentReportActionID + isThread(report) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; From bbdc0766dd282b246cf359c01afbb064ed8a7c6f Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 19 Sep 2024 17:13:06 -0400 Subject: [PATCH 101/104] one more --- src/libs/ReportUtils.ts | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 8b5c930e5314..8d4a157f1468 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1539,7 +1539,7 @@ function isChildReport(report: OnyxEntry): boolean { * An Expense Request is a thread where the parent report is an Expense Report and * the parentReportAction is a transaction. */ -function isExpenseRequest(report: OnyxInputOrEntry): boolean { +function isExpenseRequest(report: OnyxInputOrEntry): report is Thread { if (isThread(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const parentReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; @@ -2215,7 +2215,7 @@ function getIcons( }; return [fallbackIcon]; } - if (isExpenseRequest(report) && isThread(report)) { + if (isExpenseRequest(report)) { const parentReportAction = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; const workspaceIcon = getWorkspaceIcon(report, policy); const memberIcon = { @@ -3110,10 +3110,9 @@ function canHoldUnholdReportAction(reportAction: OnyxInputOrEntry) const transactionID = moneyRequestReport ? ReportActionsUtils.getOriginalMessage(reportAction)?.IOUTransactionID : 0; const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? ({} as Transaction); - const parentReportAction = - isThread(moneyRequestReport) - ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${moneyRequestReport.parentReportID}`]?.[moneyRequestReport.parentReportActionID] - : undefined; + const parentReportAction = isThread(moneyRequestReport) + ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${moneyRequestReport.parentReportID}`]?.[moneyRequestReport.parentReportActionID] + : undefined; const isRequestIOU = isIOUReport(moneyRequestReport); const isHoldActionCreator = isHoldCreator(transaction, reportAction.childReportID ?? '-1'); @@ -3720,13 +3719,8 @@ function getReportName( } let formattedName: string | undefined; - let parentReportAction: OnyxEntry | undefined; - if (parentReportActionParam) { - parentReportAction = - isThread(report) - ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] - : undefined; - } + const parentReportAction = + parentReportActionParam && isThread(report) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; const parentReportActionMessage = ReportActionsUtils.getReportActionMessage(parentReportAction); if (parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.SUBMITTED) { @@ -6009,10 +6003,7 @@ function shouldReportBeInOptionList({ // This can also happen for anyone accessing a public room or archived room for which they don't have access to the underlying policy. // Optionally exclude reports that do not belong to currently active workspace - const parentReportAction = - isThread(report) - ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] - : undefined; + const parentReportAction = isThread(report) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; if ( !report?.reportID || From 3bf7935824f1afec39ef745603bc7b82f0693903 Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 19 Sep 2024 17:27:00 -0400 Subject: [PATCH 102/104] null and specific error --- src/libs/ReportUtils.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 8d4a157f1468..e873981663ec 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3719,8 +3719,12 @@ function getReportName( } let formattedName: string | undefined; - const parentReportAction = - parentReportActionParam && isThread(report) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; + let parentReportAction: OnyxEntry; + if (parentReportActionParam) { + parentReportAction = parentReportActionParam; + } else { + parentReportAction = isThread(report) ? allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] : undefined; + } const parentReportActionMessage = ReportActionsUtils.getReportActionMessage(parentReportAction); if (parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.SUBMITTED) { @@ -4256,7 +4260,7 @@ function buildOptimisticTaskCommentReportAction( // These parameters are not saved on the reportAction, but are used to display the task in the UI // Added when we fetch the reportActions on a report - // eslint-disable-next-line + // eslint-disable-next-line deprecation/deprecation reportAction.reportAction.originalMessage = { html: ReportActionsUtils.getReportActionHtml(reportAction.reportAction), taskReportID: ReportActionsUtils.getReportActionMessage(reportAction.reportAction)?.taskReportID, From d79094031ec42f2a3a6ef903ca6301110a0e4e3f Mon Sep 17 00:00:00 2001 From: Srikar Parsi Date: Thu, 19 Sep 2024 18:08:21 -0400 Subject: [PATCH 103/104] dont specify error --- 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 e873981663ec..7d2cc4a27130 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4260,7 +4260,7 @@ function buildOptimisticTaskCommentReportAction( // These parameters are not saved on the reportAction, but are used to display the task in the UI // Added when we fetch the reportActions on a report - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line reportAction.reportAction.originalMessage = { html: ReportActionsUtils.getReportActionHtml(reportAction.reportAction), taskReportID: ReportActionsUtils.getReportActionMessage(reportAction.reportAction)?.taskReportID, From b0ce2068ee57c252ec47aa1f09319eee8b4f673c Mon Sep 17 00:00:00 2001 From: OSBotify Date: Thu, 19 Sep 2024 23:15:12 +0000 Subject: [PATCH 104/104] Update version to 9.0.39-0 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 4 ++-- ios/NewExpensifyTests/Info.plist | 4 ++-- ios/NotificationServiceExtension/Info.plist | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index dd4f5b661e66..5b5f9d40d4df 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -110,8 +110,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009003804 - versionName "9.0.38-4" + versionCode 1009003900 + versionName "9.0.39-0" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index a01d4fe324b5..bfea43969e01 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 9.0.38 + 9.0.39 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.38.4 + 9.0.39.0 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 42ecfefe8df0..2f8941238a2d 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 9.0.38 + 9.0.39 CFBundleSignature ???? CFBundleVersion - 9.0.38.4 + 9.0.39.0 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 9cc5961cc9ac..2b639ac81226 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 9.0.38 + 9.0.39 CFBundleVersion - 9.0.38.4 + 9.0.39.0 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index cee9869929dd..a5ae221a1e14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.38-4", + "version": "9.0.39-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.38-4", + "version": "9.0.39-0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index cc38b5b9bbd9..3d808af65ba2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.38-4", + "version": "9.0.39-0", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",