From 3ec0542bf73eb70e661b022fda578e51fc9ad278 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 19 Apr 2024 15:14:43 +0800 Subject: [PATCH 01/79] replace policy.submitsTo with PolicyUtils.getSubmitToAccountID --- src/libs/NextStepUtils.ts | 8 +++++--- src/libs/PolicyUtils.ts | 32 +++++++++++++++++++++++++++++++- src/libs/ReportUtils.ts | 9 +++++---- src/libs/actions/IOU.ts | 2 +- tests/unit/NextStepUtilsTest.ts | 32 ++++++++++++++++++++++++++------ 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 3b8fce748f45..66f63ddfd27f 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -12,6 +12,7 @@ import type {EmptyObject} from '@src/types/utils/EmptyObject'; import DateUtils from './DateUtils'; import EmailUtils from './EmailUtils'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; +import * as PolicyUtils from './PolicyUtils'; import * as ReportUtils from './ReportUtils'; let currentUserAccountID = -1; @@ -81,12 +82,13 @@ function buildNextStep( const {policyID = '', ownerAccountID = -1, managerID = -1} = report; const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); - const {submitsTo, harvesting, preventSelfApproval, autoReportingFrequency, autoReportingOffset} = policy; + const {harvesting, preventSelfApproval, autoReportingFrequency, autoReportingOffset} = policy; + const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, ownerAccountID); const isOwner = currentUserAccountID === ownerAccountID; const isManager = currentUserAccountID === managerID; - const isSelfApproval = currentUserAccountID === submitsTo; + const isSelfApproval = currentUserAccountID === submitToAccountID; const ownerLogin = PersonalDetailsUtils.getLoginsByAccountIDs([ownerAccountID])[0] ?? ''; - const managerDisplayName = isSelfApproval ? 'you' : ReportUtils.getDisplayNameForParticipant(submitsTo) ?? ''; + const managerDisplayName = isSelfApproval ? 'you' : ReportUtils.getDisplayNameForParticipant(submitToAccountID) ?? ''; const type: ReportNextStep['type'] = 'neutral'; let optimisticNextStep: ReportNextStep | null; diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index b4cf4b164a19..40c7f0b6a2e1 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -11,7 +11,7 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject'; import getPolicyIDFromState from './Navigation/getPolicyIDFromState'; import Navigation, {navigationRef} from './Navigation/Navigation'; import type {RootStackParamList, State} from './Navigation/types'; -import {getPersonalDetailByEmail} from './PersonalDetailsUtils'; +import {getAccountIDsByLogins, getLoginsByAccountIDs, getPersonalDetailByEmail} from './PersonalDetailsUtils'; type MemberEmailsToAccountIDs = Record; @@ -311,6 +311,35 @@ function isPolicyFeatureEnabled(policy: OnyxEntry | EmptyObject, feature return Boolean(policy?.[featureName]); } +function getApprovalWorkflow(policy: OnyxEntry | EmptyObject): ValueOf { + if (policy?.type === CONST.POLICY.TYPE.PERSONAL) { + return CONST.POLICY.APPROVAL_MODE.OPTIONAL; + } + + return policy?.approvalMode ?? CONST.POLICY.APPROVAL_MODE.ADVANCED; +} + +function getDefaultApprover(policy: OnyxEntry | EmptyObject): string { + return policy?.approver ?? policy?.owner ?? ''; +} + +function getSubmitToAccountID(policy: OnyxEntry | EmptyObject, employeeAccountID: number): number { + const employeeLogin = getLoginsByAccountIDs([employeeAccountID])[0]; + const defaultApprover = getDefaultApprover(policy); + // For policy using the optional or basic workflow, the manager is the policy default approver. + if (([CONST.POLICY.APPROVAL_MODE.OPTIONAL, CONST.POLICY.APPROVAL_MODE.BASIC] as Array>).includes(getApprovalWorkflow(policy))) { + return getAccountIDsByLogins([defaultApprover])[0]; + } + + const employee = policy?.employeeList?.[employeeLogin]; + + if (!employee) { + return -1; + } + + return getAccountIDsByLogins([employee.submitsTo ?? defaultApprover])[0]; +} + /** * Get the currently selected policy ID stored in the navigation state. */ @@ -357,6 +386,7 @@ export { getTaxByID, hasPolicyCategoriesError, getPolicyIDFromNavigationState, + getSubmitToAccountID, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a15e1937dbe2..6c4dcfc71a57 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3430,9 +3430,10 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa lastVisibleActionCreated: DateUtils.getDBTime(), }; + const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, payeeAccountID); // The account defined in the policy submitsTo field is the approver/ manager for this report - if (policy?.submitsTo) { - expenseReport.managerID = policy.submitsTo; + if (submitToAccountID) { + expenseReport.managerID = submitToAccountID; } const titleReportField = getTitleReportField(getReportFieldsByPolicyID(policyID) ?? {}); @@ -5870,9 +5871,9 @@ function isAllowedToApproveExpenseReport(report: OnyxEntry, approverAcco function isAllowedToSubmitDraftExpenseReport(report: OnyxEntry): boolean { const policy = getPolicy(report?.policyID); - const {submitsTo} = policy; + const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, report?.ownerAccountID ?? -1); - return isAllowedToApproveExpenseReport(report, submitsTo); + return isAllowedToApproveExpenseReport(report, submitToAccountID); } /** diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 7fed15335e2a..e74d2978d771 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5612,7 +5612,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { const parameters: SubmitReportParams = { reportID: expenseReport.reportID, - managerAccountID: policy.submitsTo ?? expenseReport.managerID, + managerAccountID: PolicyUtils.getSubmitToAccountID(policy, expenseReport.ownerAccountID ?? -1) ?? expenseReport.managerID, reportActionID: optimisticSubmittedReportAction.reportActionID, }; diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index 072a06748da9..7af6d35302bf 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -22,7 +22,6 @@ describe('libs/NextStepUtils', () => { // Important props id: policyID, owner: currentUserEmail, - submitsTo: currentUserAccountID, harvesting: { enabled: false, }, @@ -51,6 +50,11 @@ describe('libs/NextStepUtils', () => { login: strangeEmail, avatar: '', }, + [currentUserAccountID]: { + accountID: currentUserAccountID, + login: currentUserEmail, + avatar: '', + }, }, ...policyCollectionDataSet, }).then(waitForBatchedUpdates); @@ -341,10 +345,14 @@ describe('libs/NextStepUtils', () => { ]; return Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { - submitsTo: currentUserAccountID, preventSelfApproval: true, + employeeList: { + [currentUserEmail]: { + submitsTo: currentUserEmail, + }, + }, }).then(() => { - const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.OPEN); + const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.OPEN, undefined, true); expect(result).toMatchObject(optimisticNextStep); }); @@ -403,7 +411,11 @@ describe('libs/NextStepUtils', () => { ]; return Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { - submitsTo: strangeAccountID, + employeeList: { + [currentUserEmail]: { + submitsTo: strangeEmail, + }, + }, }).then(() => { const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.SUBMITTED); @@ -438,9 +450,17 @@ describe('libs/NextStepUtils', () => { }, ]; - const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.SUBMITTED); + return Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + employeeList: { + [strangeEmail]: { + submitsTo: currentUserEmail, + }, + }, + }).then(() => { + const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.SUBMITTED); - expect(result).toMatchObject(optimisticNextStep); + expect(result).toMatchObject(optimisticNextStep); + }); }); test('submit and close approval mode', () => { From 28e8945cc5138ec1e91d2b5b81b28ed43272a373 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 19 Apr 2024 15:38:33 +0800 Subject: [PATCH 02/79] remove code that is added when debugging --- tests/unit/NextStepUtilsTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/NextStepUtilsTest.ts b/tests/unit/NextStepUtilsTest.ts index 7af6d35302bf..65ce7352b6e6 100644 --- a/tests/unit/NextStepUtilsTest.ts +++ b/tests/unit/NextStepUtilsTest.ts @@ -352,7 +352,7 @@ describe('libs/NextStepUtils', () => { }, }, }).then(() => { - const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.OPEN, undefined, true); + const result = NextStepUtils.buildNextStep(report, CONST.REPORT.STATUS_NUM.OPEN); expect(result).toMatchObject(optimisticNextStep); }); From bae212fd87ccb52eb6a1a12f82f9b5b417c2dffc Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Fri, 19 Apr 2024 22:52:53 +0800 Subject: [PATCH 03/79] tidying up and update comment --- src/libs/PolicyUtils.ts | 2 +- src/libs/ReportUtils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 40c7f0b6a2e1..225e422a0ffc 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -326,13 +326,13 @@ function getDefaultApprover(policy: OnyxEntry | EmptyObject): string { function getSubmitToAccountID(policy: OnyxEntry | EmptyObject, employeeAccountID: number): number { const employeeLogin = getLoginsByAccountIDs([employeeAccountID])[0]; const defaultApprover = getDefaultApprover(policy); + // For policy using the optional or basic workflow, the manager is the policy default approver. if (([CONST.POLICY.APPROVAL_MODE.OPTIONAL, CONST.POLICY.APPROVAL_MODE.BASIC] as Array>).includes(getApprovalWorkflow(policy))) { return getAccountIDsByLogins([defaultApprover])[0]; } const employee = policy?.employeeList?.[employeeLogin]; - if (!employee) { return -1; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 6c4dcfc71a57..64aceba13ac4 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3430,8 +3430,8 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa lastVisibleActionCreated: DateUtils.getDBTime(), }; + // Get the approver/manager for this report to properly display the optimistic data const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, payeeAccountID); - // The account defined in the policy submitsTo field is the approver/ manager for this report if (submitToAccountID) { expenseReport.managerID = submitToAccountID; } From 0da9f7ff607bc223ec5ef80a7497678593ad0d52 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 01:09:21 +0200 Subject: [PATCH 04/79] Fix bug with Not here error appears briefly when enabling features --- src/components/Switch.tsx | 14 ++++-- src/libs/actions/Policy.ts | 4 +- .../FeatureEnabledAccessOrNotFoundWrapper.tsx | 30 ++++++++++- src/pages/workspace/WorkspaceInitialPage.tsx | 50 ++++++++++++++++--- 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index 1693bafe323d..30616e64755d 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -1,5 +1,5 @@ import React, {useEffect, useRef} from 'react'; -import {Animated} from 'react-native'; +import {Animated, InteractionManager} from 'react-native'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useNativeDriver from '@libs/useNativeDriver'; @@ -44,8 +44,16 @@ function Switch({isOn, onToggle, accessibilityLabel, disabled}: SwitchProps) { onToggle(!isOn)} - onLongPress={() => onToggle(!isOn)} + onPress={() => { + InteractionManager.runAfterInteractions(() => { + onToggle(!isOn); + }); + }} + onLongPress={() => { + InteractionManager.runAfterInteractions(() => { + onToggle(!isOn); + }); + }} role={CONST.ROLE.SWITCH} aria-checked={isOn} accessibilityLabel={accessibilityLabel} diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index cd375b580d85..0c6c371c0f09 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -3806,7 +3806,9 @@ function navigateWhenEnableFeature(policyID: string, featureRoute: Route) { new Promise((resolve) => { resolve(); }).then(() => { - Navigation.navigate(featureRoute); + requestAnimationFrame(() => { + Navigation.navigate(featureRoute); + }); }); } diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index 3bcdc1fe3303..a1337a38795a 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -1,9 +1,11 @@ /* eslint-disable rulesdir/no-negated-variables */ -import React, {useEffect} from 'react'; +import {useIsFocused} from '@react-navigation/native'; +import React, {useEffect, useState} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; +import useNetwork from '@hooks/useNetwork'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as Policy from '@userActions/Policy'; @@ -35,7 +37,31 @@ type FeatureEnabledAccessOrNotFoundComponentProps = FeatureEnabledAccessOrNotFou function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNotFoundComponentProps) { const isPolicyIDInRoute = !!props.policyID?.length; const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); - const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !PolicyUtils.isPolicyFeatureEnabled(props.policy, props.featureName); + const isFeatureEnabled = PolicyUtils.isPolicyFeatureEnabled(props.policy, props.featureName); + const [isPolicyFeatureEnabled, setIsPolicyFeatureEnabled] = useState(isFeatureEnabled); + const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; + const pendingField = props.policy?.pendingFields?.[props.featureName]; + const [isFeatureScreenOpen, setIsFeatureScreenOpen] = useState(false); + const isFocused = useIsFocused(); + const {isOffline} = useNetwork(); + + useEffect(() => { + if (!isFeatureScreenOpen && isFocused) { + setIsFeatureScreenOpen(true); + setIsPolicyFeatureEnabled(isFeatureEnabled); + return; + } + if (!isFocused) { + setIsFeatureScreenOpen(false); + return; + } + setIsPolicyFeatureEnabled((isPrevFeatureEnabled) => { + if (!pendingField || isOffline) { + return isFeatureEnabled; + } + return isPrevFeatureEnabled; + }); + }, [isFocused, pendingField, isOffline, isFeatureEnabled, isFeatureScreenOpen]); useEffect(() => { if (!isPolicyIDInRoute || !isEmptyObject(props.policy)) { diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 2f32034391a5..0eb5a38c3270 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -14,6 +14,7 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; import useLocalize from '@hooks/useLocalize'; +import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; import usePrevious from '@hooks/usePrevious'; import useSingleExecution from '@hooks/useSingleExecution'; @@ -33,6 +34,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; +import type {PolicyFeatureName} from '@src/types/onyx/Policy'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; @@ -86,6 +88,20 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const activeRoute = useNavigationState(getTopmostWorkspacesCentralPaneName); const {translate} = useLocalize(); const {canUseAccountingIntegrations} = usePermissions(); + const {isOffline} = useNetwork(); + + const prevPendingFields = usePrevious(policy?.pendingFields); + const policyFeatureStates = useMemo( + () => ({ + [CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED]: policy?.areDistanceRatesEnabled, + [CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED]: policy?.areWorkflowsEnabled, + [CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]: policy?.areCategoriesEnabled, + [CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED]: policy?.areTagsEnabled, + [CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED]: policy?.tax?.trackingEnabled, + [CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED]: policy?.areConnectionsEnabled, + }), + [policy], + ) as Record; const policyID = policy?.id ?? ''; const policyName = policy?.name ?? ''; @@ -122,6 +138,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy); const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); const isFreeGroupPolicy = PolicyUtils.isFreeGroupPolicy(policy); + const [featureStates, setFeatureStates] = useState(policyFeatureStates); const protectedFreePolicyMenuItems: WorkspaceMenuItem[] = [ { @@ -167,7 +184,28 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = []; - if (policy?.areDistanceRatesEnabled) { + useEffect(() => { + setFeatureStates((currentFeatureStates) => { + const newFeatureStates = {} as Record; + const keys = Object.keys(policy?.pendingFields ?? {}) as PolicyFeatureName[]; + keys.forEach((key) => { + const isFeatureEnabled = PolicyUtils.isPolicyFeatureEnabled(policy, key); + if (prevPendingFields?.[key] !== policy?.pendingFields?.[key] || isOffline || !policy?.pendingFields?.[key]) { + newFeatureStates[key] = isFeatureEnabled; + + return; + } + + newFeatureStates[key] = currentFeatureStates[key]; + }); + return { + ...policyFeatureStates, + ...newFeatureStates, + }; + }); + }, [policy, isOffline, policyFeatureStates, prevPendingFields]); + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED]) { protectedCollectPolicyMenuItems.push({ translationKey: 'workspace.common.distanceRates', icon: Expensicons.Car, @@ -176,7 +214,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc }); } - if (policy?.areWorkflowsEnabled) { + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED]) { protectedCollectPolicyMenuItems.push({ translationKey: 'workspace.common.workflows', icon: Expensicons.Workflows, @@ -186,7 +224,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc }); } - if (policy?.areCategoriesEnabled) { + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) { protectedCollectPolicyMenuItems.push({ translationKey: 'workspace.common.categories', icon: Expensicons.Folder, @@ -196,7 +234,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc }); } - if (policy?.areTagsEnabled) { + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED]) { protectedCollectPolicyMenuItems.push({ translationKey: 'workspace.common.tags', icon: Expensicons.Tag, @@ -205,7 +243,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc }); } - if (policy?.tax?.trackingEnabled) { + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED]) { protectedCollectPolicyMenuItems.push({ translationKey: 'workspace.common.taxes', icon: Expensicons.Tax, @@ -215,7 +253,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc }); } - if (policy?.areConnectionsEnabled && canUseAccountingIntegrations) { + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED] && canUseAccountingIntegrations) { protectedCollectPolicyMenuItems.push({ translationKey: 'workspace.common.accounting', icon: Expensicons.Sync, From 3f893fdacbedb9d1d446c43f5b966774b03a1b03 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 01:15:10 +0200 Subject: [PATCH 05/79] Refactor switch --- src/components/Switch.tsx | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index 30616e64755d..e6ab9a9f1c1c 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -32,6 +32,12 @@ function Switch({isOn, onToggle, accessibilityLabel, disabled}: SwitchProps) { const offsetX = useRef(new Animated.Value(isOn ? OFFSET_X.ON : OFFSET_X.OFF)); const theme = useTheme(); + const handleSwitchPress = () => { + InteractionManager.runAfterInteractions(() => { + onToggle(!isOn); + }); + }; + useEffect(() => { Animated.timing(offsetX.current, { toValue: isOn ? OFFSET_X.ON : OFFSET_X.OFF, @@ -44,16 +50,8 @@ function Switch({isOn, onToggle, accessibilityLabel, disabled}: SwitchProps) { { - InteractionManager.runAfterInteractions(() => { - onToggle(!isOn); - }); - }} - onLongPress={() => { - InteractionManager.runAfterInteractions(() => { - onToggle(!isOn); - }); - }} + onPress={handleSwitchPress} + onLongPress={handleSwitchPress} role={CONST.ROLE.SWITCH} aria-checked={isOn} accessibilityLabel={accessibilityLabel} From 0744c28555ce75b949505f68569472b107ae0d97 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 01:23:19 +0200 Subject: [PATCH 06/79] Refactor changes in FeatureEnabledAccessOrNotFoundComponent --- .../FeatureEnabledAccessOrNotFoundWrapper.tsx | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index a1337a38795a..f3974b353a5c 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -41,27 +41,17 @@ function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNo const [isPolicyFeatureEnabled, setIsPolicyFeatureEnabled] = useState(isFeatureEnabled); const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; const pendingField = props.policy?.pendingFields?.[props.featureName]; - const [isFeatureScreenOpen, setIsFeatureScreenOpen] = useState(false); const isFocused = useIsFocused(); const {isOffline} = useNetwork(); useEffect(() => { - if (!isFeatureScreenOpen && isFocused) { - setIsFeatureScreenOpen(true); - setIsPolicyFeatureEnabled(isFeatureEnabled); - return; - } if (!isFocused) { - setIsFeatureScreenOpen(false); return; } - setIsPolicyFeatureEnabled((isPrevFeatureEnabled) => { - if (!pendingField || isOffline) { - return isFeatureEnabled; - } - return isPrevFeatureEnabled; - }); - }, [isFocused, pendingField, isOffline, isFeatureEnabled, isFeatureScreenOpen]); + if (!pendingField || isOffline) { + setIsPolicyFeatureEnabled(isFeatureEnabled); + } + }, [isFocused, pendingField, isOffline, isFeatureEnabled]); useEffect(() => { if (!isPolicyIDInRoute || !isEmptyObject(props.policy)) { From 224c9eab5e50f21e42ceb86893d17798733f70a3 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 01:25:42 +0200 Subject: [PATCH 07/79] Refactor changes in FeatureEnabledAccessOrNotFoundComponent x2 --- .../workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index f3974b353a5c..eebdb3a280db 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -35,15 +35,17 @@ type FeatureEnabledAccessOrNotFoundComponentProps = FeatureEnabledAccessOrNotFou }; function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNotFoundComponentProps) { + const pendingField = props.policy?.pendingFields?.[props.featureName]; const isPolicyIDInRoute = !!props.policyID?.length; - const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); const isFeatureEnabled = PolicyUtils.isPolicyFeatureEnabled(props.policy, props.featureName); + const [isPolicyFeatureEnabled, setIsPolicyFeatureEnabled] = useState(isFeatureEnabled); - const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; - const pendingField = props.policy?.pendingFields?.[props.featureName]; const isFocused = useIsFocused(); const {isOffline} = useNetwork(); + const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; + const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); + useEffect(() => { if (!isFocused) { return; From b72180c831990875ee5991cccfeb84312f47f0a2 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 12:18:10 +0200 Subject: [PATCH 08/79] Add clearPendingFieldsForMoreFeatures and refactor WorkspaceInitialPage --- src/libs/actions/Policy.ts | 14 +++++++++++++ src/pages/workspace/WorkspaceInitialPage.tsx | 22 ++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 0c6c371c0f09..30027f626901 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -2382,6 +2382,19 @@ function openPolicyWorkflowsPage(policyID: string) { API.read(READ_COMMANDS.OPEN_POLICY_WORKFLOWS_PAGE, params, onyxData); } +function clearPendingFieldsForMoreFeatures(policyID: string) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + pendingFields: { + areDistanceRatesEnabled: null, + areWorkflowsEnabled: null, + areCategoriesEnabled: null, + areTagsEnabled: null, + tax: null, + areConnectionsEnabled: null, + }, + }); +} + function setPolicyIDForReimburseView(policyID: string) { Onyx.merge(ONYXKEYS.WORKSPACE_RATE_AND_UNIT, {policyID, rate: null, unit: null}); } @@ -5075,6 +5088,7 @@ export { updatePolicyDistanceRateValue, setPolicyDistanceRatesEnabled, deletePolicyDistanceRates, + clearPendingFieldsForMoreFeatures, }; export type {NewCustomUnit}; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 0eb5a38c3270..a11e723145c5 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -73,6 +73,8 @@ type WorkspaceInitialPageOnyxProps = { type WorkspaceInitialPageProps = WithPolicyAndFullscreenLoadingProps & WorkspaceInitialPageOnyxProps & StackScreenProps; +type PolicyFeatureStates = Record; + function dismissError(policyID: string) { PolicyUtils.goBackFromInvalidPolicy(); Policy.removeWorkspace(policyID); @@ -101,7 +103,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc [CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED]: policy?.areConnectionsEnabled, }), [policy], - ) as Record; + ) as PolicyFeatureStates; const policyID = policy?.id ?? ''; const policyName = policy?.name ?? ''; @@ -125,6 +127,10 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc setIsCurrencyModalOpen(false); }, [policy?.outputCurrency, isCurrencyModalOpen]); + useEffect(() => { + Policy.clearPendingFieldsForMoreFeatures(policyID); + }, [policyID]); + /** Call update workspace currency and hide the modal */ const confirmCurrencyChangeAndHideModal = useCallback(() => { Policy.updateGeneralSettings(policyID, policyName, CONST.CURRENCY.USD); @@ -186,17 +192,11 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc useEffect(() => { setFeatureStates((currentFeatureStates) => { - const newFeatureStates = {} as Record; - const keys = Object.keys(policy?.pendingFields ?? {}) as PolicyFeatureName[]; - keys.forEach((key) => { + const newFeatureStates = {} as PolicyFeatureStates; + (Object.keys(policy?.pendingFields ?? {}) as PolicyFeatureName[]).forEach((key) => { const isFeatureEnabled = PolicyUtils.isPolicyFeatureEnabled(policy, key); - if (prevPendingFields?.[key] !== policy?.pendingFields?.[key] || isOffline || !policy?.pendingFields?.[key]) { - newFeatureStates[key] = isFeatureEnabled; - - return; - } - - newFeatureStates[key] = currentFeatureStates[key]; + newFeatureStates[key] = + prevPendingFields?.[key] !== policy?.pendingFields?.[key] || isOffline || !policy?.pendingFields?.[key] ? isFeatureEnabled : currentFeatureStates[key]; }); return { ...policyFeatureStates, From 578b27e5e75cf559e2410d5b1eb1ddafe5caa530 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 15:36:06 +0200 Subject: [PATCH 09/79] Update condition for clearPendingFieldsForMoreFeatures --- src/pages/workspace/WorkspaceInitialPage.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index a11e723145c5..9343432a4836 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -128,7 +128,11 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc }, [policy?.outputCurrency, isCurrencyModalOpen]); useEffect(() => { + if (isOffline) { + return; + } Policy.clearPendingFieldsForMoreFeatures(policyID); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [policyID]); /** Call update workspace currency and hide the modal */ From cf28c35257980e6d9ad20791f3f7aeeb1efbbab5 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Sun, 21 Apr 2024 17:33:20 +0200 Subject: [PATCH 10/79] Remove clearPendingFieldsForMoreFeatures --- src/libs/actions/Policy.ts | 14 -------------- src/pages/workspace/WorkspaceInitialPage.tsx | 8 -------- 2 files changed, 22 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 30027f626901..0c6c371c0f09 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -2382,19 +2382,6 @@ function openPolicyWorkflowsPage(policyID: string) { API.read(READ_COMMANDS.OPEN_POLICY_WORKFLOWS_PAGE, params, onyxData); } -function clearPendingFieldsForMoreFeatures(policyID: string) { - Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { - pendingFields: { - areDistanceRatesEnabled: null, - areWorkflowsEnabled: null, - areCategoriesEnabled: null, - areTagsEnabled: null, - tax: null, - areConnectionsEnabled: null, - }, - }); -} - function setPolicyIDForReimburseView(policyID: string) { Onyx.merge(ONYXKEYS.WORKSPACE_RATE_AND_UNIT, {policyID, rate: null, unit: null}); } @@ -5088,7 +5075,6 @@ export { updatePolicyDistanceRateValue, setPolicyDistanceRatesEnabled, deletePolicyDistanceRates, - clearPendingFieldsForMoreFeatures, }; export type {NewCustomUnit}; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 9343432a4836..517c9b5251b9 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -127,14 +127,6 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc setIsCurrencyModalOpen(false); }, [policy?.outputCurrency, isCurrencyModalOpen]); - useEffect(() => { - if (isOffline) { - return; - } - Policy.clearPendingFieldsForMoreFeatures(policyID); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [policyID]); - /** Call update workspace currency and hide the modal */ const confirmCurrencyChangeAndHideModal = useCallback(() => { Policy.updateGeneralSettings(policyID, policyName, CONST.CURRENCY.USD); From 90834be4db9ffdcf72d07bf94a91676d4bcfa83e Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 13:33:21 +0700 Subject: [PATCH 11/79] fix allow to search selfDM in new chat page --- src/libs/OptionsListUtils.ts | 8 ++++++-- src/pages/NewChatPage.tsx | 14 +++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 2aad4179c337..049e538cb18a 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1505,7 +1505,8 @@ function createOptionList(personalDetails: OnyxEntry, repor } function createOptionFromReport(report: Report, personalDetails: OnyxEntry) { - const accountIDs = report.participantAccountIDs ?? []; + const isSelfDM = ReportUtils.isSelfDM(report); + const accountIDs = isSelfDM ? [currentUserAccountID ?? 0] : report.participantAccountIDs ?? []; return { item: report, @@ -1741,7 +1742,10 @@ function getOptions( } // Exclude the current user from the personal details list - const optionsToExclude: Option[] = [{login: currentUserLogin}, {login: CONST.EMAIL.NOTIFICATIONS}]; + const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}]; + if (!includeSelfDM) { + optionsToExclude.push({login: currentUserLogin}); + } // If we're including selected options from the search results, we only want to exclude them if the search input is empty // This is because on certain pages, we show the selected options at the top when the search input is empty diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 470afc28d76e..b3ac000daea7 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -25,7 +25,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import type {OptionData} from '@libs/ReportUtils'; +import {getReport, type OptionData} from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; @@ -68,6 +68,10 @@ function useOptions({isGroupChat}: NewChatPageProps) { {}, [], true, + undefined, + undefined, + undefined, + true, ); const maxParticipantsReached = selectedOptions.length === CONST.REPORT.MAXIMUM_PARTICIPANTS; @@ -182,6 +186,11 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { */ const createChat = useCallback( (option?: OptionsListUtils.Option) => { + const report = getReport(option?.reportID); + if (option?.isSelfDM && report) { + Navigation.dismissModalWithReport(report); + return; + } let login = ''; if (option?.login) { @@ -200,6 +209,9 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { const itemRightSideComponent = useCallback( (item: ListItem & OptionsListUtils.Option) => { + if (item.isSelfDM) { + return null; + } /** * Removes a selected option from list if already selected. If not already selected add this option to the list. * @param option From 4fa9decddd651f15dd24cc19aef277acaf837288 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 13:51:13 +0700 Subject: [PATCH 12/79] fix lint --- src/pages/NewChatPage.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index b3ac000daea7..f0b983033c94 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -25,7 +25,8 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import {getReport, type OptionData} from '@libs/ReportUtils'; +import type {OptionData} from '@libs/ReportUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; @@ -186,9 +187,9 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { */ const createChat = useCallback( (option?: OptionsListUtils.Option) => { - const report = getReport(option?.reportID); + const report = ReportUtils.getReport(option?.reportID); if (option?.isSelfDM && report) { - Navigation.dismissModalWithReport(report); + Navigation.dismissModal(report.reportID); return; } let login = ''; From 84605aad893eab7948de04f89f980eca8e372583 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:30:01 +0700 Subject: [PATCH 13/79] fix use option.reportID in createChat --- src/pages/NewChatPage.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index f0b983033c94..3e5a99c1b222 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -187,9 +187,8 @@ function NewChatPage({isGroupChat}: NewChatPageProps) { */ const createChat = useCallback( (option?: OptionsListUtils.Option) => { - const report = ReportUtils.getReport(option?.reportID); - if (option?.isSelfDM && report) { - Navigation.dismissModal(report.reportID); + if (option?.isSelfDM) { + Navigation.dismissModal(option.reportID); return; } let login = ''; From d40e0cf3c16eb0737d18b26b682d99cd192dd6c2 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:36:26 +0700 Subject: [PATCH 14/79] fix lint --- src/pages/NewChatPage.tsx | 1 - tests/unit/OptionsListUtilsTest.ts | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index 3e5a99c1b222..3f0c9a23da3f 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -26,7 +26,6 @@ import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import type {OptionData} from '@libs/ReportUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; diff --git a/tests/unit/OptionsListUtilsTest.ts b/tests/unit/OptionsListUtilsTest.ts index 75ed7fa9d5b1..4c332d0e2e07 100644 --- a/tests/unit/OptionsListUtilsTest.ts +++ b/tests/unit/OptionsListUtilsTest.ts @@ -368,7 +368,7 @@ describe('OptionsListUtils', () => { // When we filter in the Search view without providing a searchValue let results = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); // Then the 2 personalDetails that don't have reports should be returned - expect(results.personalDetails.length).toBe(2); + expect(results.personalDetails.length).toBe(3); // Then all of the reports should be shown including the archived rooms. expect(results.recentReports.length).toBe(Object.values(OPTIONS.reports).length); @@ -2618,7 +2618,7 @@ describe('OptionsListUtils', () => { const options = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); const filteredOptions = OptionsListUtils.filterOptions(options, searchText); - expect(filteredOptions.recentReports.length).toBe(5); + expect(filteredOptions.recentReports.length).toBe(6); expect(filteredOptions.recentReports[0].text).toBe('Invisible Woman'); expect(filteredOptions.recentReports[1].text).toBe('Spider-Man'); expect(filteredOptions.recentReports[2].text).toBe('Black Widow'); From d3eeff38c7d8bf1d576b7f3faca6aac06fbd6c06 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:49:07 +0700 Subject: [PATCH 15/79] fix unread issue in combine report --- .../LHNOptionsList/LHNOptionsList.tsx | 3 +++ .../LHNOptionsList/OptionRowLHNData.tsx | 2 ++ src/components/LHNOptionsList/types.ts | 3 +++ src/libs/SidebarUtils.ts | 4 +++- .../ContextMenu/BaseReportActionContextMenu.tsx | 5 +++++ .../report/ContextMenu/ContextMenuActions.tsx | 6 +++++- .../PopoverReportActionContextMenu.tsx | 4 ++++ .../ContextMenu/ReportActionContextMenu.ts | 3 +++ src/pages/home/report/ReportActionsList.tsx | 17 ++++++++++++++++- tests/perf-test/SidebarUtils.perf-test.ts | 1 + 10 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 8c43ae542932..469f17258a7f 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -116,6 +116,8 @@ function LHNOptionsList({ const hasDraftComment = DraftCommentUtils.isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions); const lastReportAction = sortedReportActions[0]; + const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(reportID, itemReportActions); + const transactionThreadReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null; // Get the transaction for the last report action let lastReportActionTransactionID = ''; @@ -129,6 +131,7 @@ function LHNOptionsList({ ; + /** The transaction thread report associated with the current report, if any */ + transactionThreadReport: OnyxEntry; + /** The policy which the user has access to and which the report could be tied to */ policy?: OnyxEntry; diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 7b0c28b76653..43b83a775b60 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -191,6 +191,7 @@ function getOptionData({ policy, parentReportAction, hasViolations, + transactionThreadReport, }: { report: OnyxEntry; reportActions: OnyxEntry; @@ -199,6 +200,7 @@ function getOptionData({ policy: OnyxEntry | undefined; parentReportAction: OnyxEntry | undefined; hasViolations: boolean; + transactionThreadReport: OnyxEntry; }): ReportUtils.OptionData | undefined { // When a user signs out, Onyx is cleared. Due to the lazy rendering with a virtual list, it's possible for // this method to be called after the Onyx data has been cleared out. In that case, it's fine to do @@ -267,7 +269,7 @@ function getOptionData({ result.statusNum = report.statusNum; // When the only message of a report is deleted lastVisibileActionCreated is not reset leading to wrongly // setting it Unread so we add additional condition here to avoid empty chat LHN from being bold. - result.isUnread = ReportUtils.isUnread(report) && !!report.lastActorAccountID; + result.isUnread = (ReportUtils.isUnread(report) && !!report.lastActorAccountID) || (ReportUtils.isUnread(transactionThreadReport) && !!transactionThreadReport?.lastActorAccountID); result.isUnreadWithMention = ReportUtils.isUnreadWithMention(report); result.isPinned = report.isPinned; result.iouReportID = report.iouReportID; diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 46ebdd751762..8e2c9d6f09b3 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -49,6 +49,9 @@ type BaseReportActionContextMenuProps = BaseReportActionContextMenuOnyxProps & { // eslint-disable-next-line react/no-unused-prop-types originalReportID: string; + /** The ID of transaction thread report associated with the current report, if any */ + transactionThreadReportID: string; + /** * If true, this component will be a small, row-oriented menu that displays icons but not text. * If false, this component will be a larger, column-oriented menu that displays icons alongside text in each row. @@ -117,6 +120,7 @@ function BaseReportActionContextMenu({ checkIfContextMenuActive, disabledActions = [], setIsEmojiPickerActive, + transactionThreadReportID, }: BaseReportActionContextMenuProps) { const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); @@ -245,6 +249,7 @@ function BaseReportActionContextMenu({ interceptAnonymousUser, openOverflowMenu, setIsEmojiPickerActive, + transactionThreadReportID, }; if ('renderContent' in contextAction) { diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index eb1e60461005..59c4042280ec 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -79,6 +79,7 @@ type ContextMenuActionPayload = { event?: GestureResponderEvent | MouseEvent | KeyboardEvent; setIsEmojiPickerActive?: (state: boolean) => void; anchorRef?: MutableRefObject; + transactionThreadReportID?: string; }; type OnPress = (closePopover: boolean, payload: ContextMenuActionPayload, selection?: string, reportID?: string, draftMessage?: string) => void; @@ -273,8 +274,11 @@ const ContextMenuActions: ContextMenuAction[] = [ successIcon: Expensicons.Checkmark, shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport, reportID, isPinnedChat, isUnreadChat) => type === CONST.CONTEXT_MENU_TYPES.REPORT && isUnreadChat, - onPress: (closePopover, {reportID}) => { + onPress: (closePopover, {reportID, transactionThreadReportID}) => { Report.readNewestAction(reportID); + if (transactionThreadReportID && transactionThreadReportID !== '0') { + Report.readNewestAction(transactionThreadReportID); + } if (closePopover) { hideContextMenu(true, ReportActionComposeFocusManager.focus); } diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx index 6cb688ff2558..38fd37ee4d26 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -37,6 +37,7 @@ function PopoverReportActionContextMenu(_props: unknown, ref: ForwardedRef>(null); const reportActionIDRef = useRef('0'); const originalReportIDRef = useRef('0'); + const transactionThreadReportIDRef = useRef('0'); const selectionRef = useRef(''); const reportActionDraftMessageRef = useRef(); @@ -171,6 +172,7 @@ function PopoverReportActionContextMenu(_props: unknown, ref: ForwardedRef {}, isOverflowMenu = false, + transactionThreadReportID = undefined, ) => { const {pageX = 0, pageY = 0} = extractPointerEvent(event); contextMenuAnchorRef.current = contextMenuAnchor; @@ -212,6 +214,7 @@ function PopoverReportActionContextMenu(_props: unknown, ref: ForwardedRef void, isOverflowMenu?: boolean, + transactionThreadReportID?: string, ) => void; type ReportActionContextMenu = { @@ -119,6 +120,7 @@ function showContextMenu( shouldCloseOnTarget = false, setIsEmojiPickerActive = () => {}, isOverflowMenu = false, + transactionThreadReportID = '0', ) { if (!contextMenuRef.current) { return; @@ -149,6 +151,7 @@ function showContextMenu( shouldCloseOnTarget, setIsEmojiPickerActive, isOverflowMenu, + transactionThreadReportID, ); } diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 206f7558baac..2f30db46c56b 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -294,6 +294,16 @@ function ReportActionsList({ setMessageManuallyMarkedUnread(0); }); + const unreadActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`unreadAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { + resetUnreadMarker(newLastReadTime); + setMessageManuallyMarkedUnread(new Date().getTime()); + }); + + const readNewestActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`readNewestAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { + resetUnreadMarker(newLastReadTime); + setMessageManuallyMarkedUnread(0); + }); + const deletedReportActionSubscription = DeviceEventEmitter.addListener(`deletedReportAction_${report.reportID}`, (reportActionID) => { if (cacheUnreadMarkers.get(report.reportID) !== reportActionID) { return; @@ -305,9 +315,11 @@ function ReportActionsList({ return () => { unreadActionSubscription.remove(); readNewestActionSubscription.remove(); + unreadActionSubscriptionForTransactionThread.remove(); + readNewestActionSubscriptionForTransactionThread.remove(); deletedReportActionSubscription.remove(); }; - }, [report.reportID]); + }, [report.reportID, transactionThreadReport?.reportID]); useEffect(() => { if (linkedReportActionID) { @@ -393,6 +405,9 @@ function ReportActionsList({ reportScrollManager.scrollToBottom(); readActionSkipped.current = false; Report.readNewestAction(report.reportID); + if (transactionThreadReport?.reportID) { + Report.readNewestAction(transactionThreadReport?.reportID); + } }; /** diff --git a/tests/perf-test/SidebarUtils.perf-test.ts b/tests/perf-test/SidebarUtils.perf-test.ts index 8566abb97c7f..b19e59dbdcc0 100644 --- a/tests/perf-test/SidebarUtils.perf-test.ts +++ b/tests/perf-test/SidebarUtils.perf-test.ts @@ -106,6 +106,7 @@ describe('SidebarUtils', () => { policy, parentReportAction, hasViolations: false, + transactionThreadReport: null, }), ); }); From ac68346d8a8bd3b0e91d5547af3dd295b1d090d0 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 14:50:03 +0700 Subject: [PATCH 16/79] fix revert fix jest --- tests/unit/OptionsListUtilsTest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/OptionsListUtilsTest.ts b/tests/unit/OptionsListUtilsTest.ts index 4c332d0e2e07..75ed7fa9d5b1 100644 --- a/tests/unit/OptionsListUtilsTest.ts +++ b/tests/unit/OptionsListUtilsTest.ts @@ -368,7 +368,7 @@ describe('OptionsListUtils', () => { // When we filter in the Search view without providing a searchValue let results = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); // Then the 2 personalDetails that don't have reports should be returned - expect(results.personalDetails.length).toBe(3); + expect(results.personalDetails.length).toBe(2); // Then all of the reports should be shown including the archived rooms. expect(results.recentReports.length).toBe(Object.values(OPTIONS.reports).length); @@ -2618,7 +2618,7 @@ describe('OptionsListUtils', () => { const options = OptionsListUtils.getSearchOptions(OPTIONS, '', [CONST.BETAS.ALL]); const filteredOptions = OptionsListUtils.filterOptions(options, searchText); - expect(filteredOptions.recentReports.length).toBe(6); + expect(filteredOptions.recentReports.length).toBe(5); expect(filteredOptions.recentReports[0].text).toBe('Invisible Woman'); expect(filteredOptions.recentReports[1].text).toBe('Spider-Man'); expect(filteredOptions.recentReports[2].text).toBe('Black Widow'); From a97a864a62c601732208fa68a3a570cf8de976a6 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 15:14:05 +0700 Subject: [PATCH 17/79] add transaction thread report ID to option item --- src/components/LHNOptionsList/OptionRowLHN.tsx | 5 +++++ src/components/LHNOptionsList/OptionRowLHNData.tsx | 1 + src/libs/ReportUtils.ts | 1 + src/libs/SidebarUtils.ts | 1 + src/pages/home/report/ReportActionsList.tsx | 3 ++- 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 9946dea9d5a7..2eba8b62dfd7 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -96,6 +96,11 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti false, optionItem.isPinned, !!optionItem.isUnread, + [], + false, + () => {}, + false, + optionItem.transactionThreadReportID, ); }; diff --git a/src/components/LHNOptionsList/OptionRowLHNData.tsx b/src/components/LHNOptionsList/OptionRowLHNData.tsx index 2d369ce02ab2..1d6cc636f939 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.tsx +++ b/src/components/LHNOptionsList/OptionRowLHNData.tsx @@ -72,6 +72,7 @@ function OptionRowLHNData({ transactionViolations, canUseViolations, receiptTransactions, + transactionThreadReport, ]); return ( diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index fc677dedc96e..ed3f217b38c8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -440,6 +440,7 @@ type OptionData = { reportID?: string; enabled?: boolean; data?: Partial; + transactionThreadReportID?: string | null; } & Report; type OnyxDataTaskAssigneeChat = { diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 43b83a775b60..a250a5cb2e1c 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -237,6 +237,7 @@ function getOptionData({ isWaitingOnBankAccount: false, isAllowedToComment: true, isDeletedParentAction: false, + transactionThreadReportID: transactionThreadReport?.reportID, }; let participantAccountIDs = report.participantAccountIDs ?? []; diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 2f30db46c56b..9792af1dae40 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -196,7 +196,8 @@ function ReportActionsList({ ); const lastActionIndex = sortedVisibleReportActions[0]?.reportActionID; const reportActionSize = useRef(sortedVisibleReportActions.length); - const hasNewestReportAction = sortedReportActions?.[0].created === report.lastVisibleActionCreated; + const hasNewestReportAction = + sortedReportActions?.[0].created === report.lastVisibleActionCreated || sortedReportActions?.[0].created === transactionThreadReport?.lastVisibleActionCreated; const hasNewestReportActionRef = useRef(hasNewestReportAction); hasNewestReportActionRef.current = hasNewestReportAction; const previousLastIndex = useRef(lastActionIndex); From 6a16d6d1aca61fe8a5b395a18b17c789f5ae346c Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Apr 2024 10:15:51 +0200 Subject: [PATCH 18/79] Remove isFocuesd from FeatureEnabledAccessOrNotFoundComponent --- .../FeatureEnabledAccessOrNotFoundWrapper.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index eebdb3a280db..cf5af04ac846 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -1,5 +1,4 @@ /* eslint-disable rulesdir/no-negated-variables */ -import {useIsFocused} from '@react-navigation/native'; import React, {useEffect, useState} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; @@ -40,20 +39,17 @@ function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNo const isFeatureEnabled = PolicyUtils.isPolicyFeatureEnabled(props.policy, props.featureName); const [isPolicyFeatureEnabled, setIsPolicyFeatureEnabled] = useState(isFeatureEnabled); - const isFocused = useIsFocused(); const {isOffline} = useNetwork(); const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); useEffect(() => { - if (!isFocused) { + if (pendingField && !isOffline) { return; } - if (!pendingField || isOffline) { - setIsPolicyFeatureEnabled(isFeatureEnabled); - } - }, [isFocused, pendingField, isOffline, isFeatureEnabled]); + setIsPolicyFeatureEnabled(isFeatureEnabled); + }, [pendingField, isOffline, isFeatureEnabled]); useEffect(() => { if (!isPolicyIDInRoute || !isEmptyObject(props.policy)) { From 27c8a30421b491bab331e652b01b419f31eb93b4 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 15:31:59 +0700 Subject: [PATCH 19/79] add missing prop --- src/pages/home/report/ReportActionItem.tsx | 1 + src/pages/home/report/ReportActionsList.tsx | 10 +++++----- src/pages/home/report/ReportActionsView.tsx | 13 +++++++------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index 8d11744740bd..3444063c48aa 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -914,6 +914,7 @@ function ReportActionItem({ isChronosReport={ReportUtils.chatIncludesChronos(originalReport)} checkIfContextMenuActive={toggleContextMenuFromActiveReportAction} setIsEmojiPickerActive={setIsEmojiPickerActive} + transactionThreadReportID={transactionThreadReport?.reportID ?? '0'} /> { - resetUnreadMarker(newLastReadTime); - setMessageManuallyMarkedUnread(0); - }); + // const readNewestActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`readNewestAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { + // resetUnreadMarker(newLastReadTime); + // setMessageManuallyMarkedUnread(0); + // }); const deletedReportActionSubscription = DeviceEventEmitter.addListener(`deletedReportAction_${report.reportID}`, (reportActionID) => { if (cacheUnreadMarkers.get(report.reportID) !== reportActionID) { @@ -317,7 +317,7 @@ function ReportActionsList({ unreadActionSubscription.remove(); readNewestActionSubscription.remove(); unreadActionSubscriptionForTransactionThread.remove(); - readNewestActionSubscriptionForTransactionThread.remove(); + // readNewestActionSubscriptionForTransactionThread.remove(); deletedReportActionSubscription.remove(); }; }, [report.reportID, transactionThreadReport?.reportID]); diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index 3e3ebf1a9cc3..65808e4e009f 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -197,7 +197,8 @@ function ReportActionsView({ } // If this is a one transaction report, ensure we load newer actions for both this report and the report associated with the transaction - if (!isEmptyObject(transactionThreadReport)) { + if (transactionThreadReport?.reportID) { + console.log("123455"); // Get newer actions based on the newest reportAction for the current report const newestActionCurrentReport = reportActionIDMap.find((item) => item.reportID === reportID); Report.getNewerActions(newestActionCurrentReport?.reportID ?? '0', newestActionCurrentReport?.reportActionID ?? '0'); @@ -209,7 +210,7 @@ function ReportActionsView({ Report.getNewerActions(reportID, newestReportAction.reportActionID); } }, - [isLoadingNewerReportActions, isLoadingInitialReportActions, reportID, transactionThreadReport, reportActionIDMap], + [isLoadingNewerReportActions, isLoadingInitialReportActions, reportID, transactionThreadReport?.reportID, reportActionIDMap], ); const hasMoreCached = reportActions.length < combinedReportActions.length; @@ -308,19 +309,19 @@ function ReportActionsView({ return; } - if (!isEmptyObject(transactionThreadReport)) { + if (transactionThreadReport?.reportID) { // Get newer actions based on the newest reportAction for the current report const oldestActionCurrentReport = reportActionIDMap.findLast((item) => item.reportID === reportID); - Report.getNewerActions(oldestActionCurrentReport?.reportID ?? '0', oldestActionCurrentReport?.reportActionID ?? '0'); + Report.getOlderActions(oldestActionCurrentReport?.reportID ?? '0', oldestActionCurrentReport?.reportActionID ?? '0'); // Get newer actions based on the newest reportAction for the transaction thread report const oldestActionTransactionThreadReport = reportActionIDMap.findLast((item) => item.reportID === transactionThreadReport.reportID); - Report.getNewerActions(oldestActionTransactionThreadReport?.reportID ?? '0', oldestActionTransactionThreadReport?.reportActionID ?? '0'); + Report.getOlderActions(oldestActionTransactionThreadReport?.reportID ?? '0', oldestActionTransactionThreadReport?.reportActionID ?? '0'); } else { // Retrieve the next REPORT.ACTIONS.LIMIT sized page of comments Report.getOlderActions(reportID, oldestReportAction.reportActionID); } - }, [network.isOffline, isLoadingOlderReportActions, isLoadingInitialReportActions, oldestReportAction, hasCreatedAction, reportID, reportActionIDMap, transactionThreadReport]); + }, [network.isOffline, isLoadingOlderReportActions, isLoadingInitialReportActions, oldestReportAction, hasCreatedAction, reportID, reportActionIDMap, transactionThreadReport?.reportID]); const loadNewerChats = useCallback(() => { if (isLoadingInitialReportActions || isLoadingOlderReportActions || network.isOffline || newestReportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { From bf3a0aaaa67bf42ab25465c6700ca470457710ed Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 15:39:41 +0700 Subject: [PATCH 20/79] reset hard code --- src/pages/home/report/ReportActionsList.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 5b118aeda63a..9792af1dae40 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -300,10 +300,10 @@ function ReportActionsList({ setMessageManuallyMarkedUnread(new Date().getTime()); }); - // const readNewestActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`readNewestAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { - // resetUnreadMarker(newLastReadTime); - // setMessageManuallyMarkedUnread(0); - // }); + const readNewestActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`readNewestAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { + resetUnreadMarker(newLastReadTime); + setMessageManuallyMarkedUnread(0); + }); const deletedReportActionSubscription = DeviceEventEmitter.addListener(`deletedReportAction_${report.reportID}`, (reportActionID) => { if (cacheUnreadMarkers.get(report.reportID) !== reportActionID) { @@ -317,7 +317,7 @@ function ReportActionsList({ unreadActionSubscription.remove(); readNewestActionSubscription.remove(); unreadActionSubscriptionForTransactionThread.remove(); - // readNewestActionSubscriptionForTransactionThread.remove(); + readNewestActionSubscriptionForTransactionThread.remove(); deletedReportActionSubscription.remove(); }; }, [report.reportID, transactionThreadReport?.reportID]); From bd426b3fcd302074d9c6c8591224a1c86dda5384 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Apr 2024 11:36:14 +0200 Subject: [PATCH 21/79] Update condition for FeatureEnabledAccessOrNotFoundComponent --- src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index cf5af04ac846..e7ea95ba44f4 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -45,7 +45,7 @@ function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNo const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); useEffect(() => { - if (pendingField && !isOffline) { + if (pendingField && !isOffline && !isFeatureEnabled) { return; } setIsPolicyFeatureEnabled(isFeatureEnabled); From 363d88b0a10449432094c5b28ffb183fc828e22d Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 16:51:43 +0700 Subject: [PATCH 22/79] fix lint --- src/pages/home/report/ReportActionsView.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index 65808e4e009f..fac51b33ed7d 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -198,7 +198,6 @@ function ReportActionsView({ // If this is a one transaction report, ensure we load newer actions for both this report and the report associated with the transaction if (transactionThreadReport?.reportID) { - console.log("123455"); // Get newer actions based on the newest reportAction for the current report const newestActionCurrentReport = reportActionIDMap.find((item) => item.reportID === reportID); Report.getNewerActions(newestActionCurrentReport?.reportID ?? '0', newestActionCurrentReport?.reportActionID ?? '0'); From 9e93ce6af10f261d204847e4dd5172648d60a346 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Mon, 22 Apr 2024 17:22:08 +0700 Subject: [PATCH 23/79] revert hard code --- src/pages/home/report/ReportActionsView.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index fac51b33ed7d..3e3ebf1a9cc3 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -197,7 +197,7 @@ function ReportActionsView({ } // If this is a one transaction report, ensure we load newer actions for both this report and the report associated with the transaction - if (transactionThreadReport?.reportID) { + if (!isEmptyObject(transactionThreadReport)) { // Get newer actions based on the newest reportAction for the current report const newestActionCurrentReport = reportActionIDMap.find((item) => item.reportID === reportID); Report.getNewerActions(newestActionCurrentReport?.reportID ?? '0', newestActionCurrentReport?.reportActionID ?? '0'); @@ -209,7 +209,7 @@ function ReportActionsView({ Report.getNewerActions(reportID, newestReportAction.reportActionID); } }, - [isLoadingNewerReportActions, isLoadingInitialReportActions, reportID, transactionThreadReport?.reportID, reportActionIDMap], + [isLoadingNewerReportActions, isLoadingInitialReportActions, reportID, transactionThreadReport, reportActionIDMap], ); const hasMoreCached = reportActions.length < combinedReportActions.length; @@ -308,19 +308,19 @@ function ReportActionsView({ return; } - if (transactionThreadReport?.reportID) { + if (!isEmptyObject(transactionThreadReport)) { // Get newer actions based on the newest reportAction for the current report const oldestActionCurrentReport = reportActionIDMap.findLast((item) => item.reportID === reportID); - Report.getOlderActions(oldestActionCurrentReport?.reportID ?? '0', oldestActionCurrentReport?.reportActionID ?? '0'); + Report.getNewerActions(oldestActionCurrentReport?.reportID ?? '0', oldestActionCurrentReport?.reportActionID ?? '0'); // Get newer actions based on the newest reportAction for the transaction thread report const oldestActionTransactionThreadReport = reportActionIDMap.findLast((item) => item.reportID === transactionThreadReport.reportID); - Report.getOlderActions(oldestActionTransactionThreadReport?.reportID ?? '0', oldestActionTransactionThreadReport?.reportActionID ?? '0'); + Report.getNewerActions(oldestActionTransactionThreadReport?.reportID ?? '0', oldestActionTransactionThreadReport?.reportActionID ?? '0'); } else { // Retrieve the next REPORT.ACTIONS.LIMIT sized page of comments Report.getOlderActions(reportID, oldestReportAction.reportActionID); } - }, [network.isOffline, isLoadingOlderReportActions, isLoadingInitialReportActions, oldestReportAction, hasCreatedAction, reportID, reportActionIDMap, transactionThreadReport?.reportID]); + }, [network.isOffline, isLoadingOlderReportActions, isLoadingInitialReportActions, oldestReportAction, hasCreatedAction, reportID, reportActionIDMap, transactionThreadReport]); const loadNewerChats = useCallback(() => { if (isLoadingInitialReportActions || isLoadingOlderReportActions || network.isOffline || newestReportAction.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { From 2e68cfb9717f8cf074e245c6eebb76e184b72170 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Apr 2024 13:21:46 +0200 Subject: [PATCH 24/79] fix nav options --- src/libs/Navigation/AppNavigator/AuthScreens.tsx | 8 ++++++-- .../getOnboardingModalScreenOptions/index.native.ts | 9 +++++++++ .../Navigation/getOnboardingModalScreenOptions/index.ts | 9 +++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/libs/Navigation/getOnboardingModalScreenOptions/index.native.ts create mode 100644 src/libs/Navigation/getOnboardingModalScreenOptions/index.ts diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 096a88254eae..17f7b946c7ab 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -10,6 +10,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import Log from '@libs/Log'; import getCurrentUrl from '@libs/Navigation/currentUrl'; +import getOnboardingModalScreenOptions from '@libs/Navigation/getOnboardingModalScreenOptions'; import Navigation from '@libs/Navigation/Navigation'; import type {AuthScreensParamList} from '@libs/Navigation/types'; import NetworkConnection from '@libs/NetworkConnection'; @@ -160,7 +161,10 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie const {isSmallScreenWidth} = useWindowDimensions(); const {shouldUseNarrowLayout} = useOnboardingLayout(); const screenOptions = getRootNavigatorScreenOptions(isSmallScreenWidth, styles, StyleUtils); - const onboardingScreenOptions = useMemo(() => screenOptions.onboardingModalNavigator(shouldUseNarrowLayout), [screenOptions, shouldUseNarrowLayout]); + const onboardingScreenOptions = useMemo( + () => getOnboardingModalScreenOptions(isSmallScreenWidth, styles, StyleUtils, shouldUseNarrowLayout), + [StyleUtils, isSmallScreenWidth, shouldUseNarrowLayout, styles], + ); const isInitialRender = useRef(true); if (isInitialRender.current) { @@ -369,7 +373,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie /> Date: Mon, 22 Apr 2024 13:22:14 +0200 Subject: [PATCH 25/79] fix reply counter --- src/libs/actions/Report.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 8b0dbf8a37a9..4bc72b59293c 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3047,6 +3047,7 @@ function completeOnboarding( }; const tasksData = data.tasks.map((task, index) => { + const hasSubtitle = !!task.subtitle; const currentTask = ReportUtils.buildOptimisticTaskReport( actorAccountID, undefined, @@ -3066,13 +3067,13 @@ function completeOnboarding( actorAccountID, index + 3, { - childVisibleActionCount: 2, + childVisibleActionCount: hasSubtitle ? 2 : 1, childCommenterCount: 1, childLastVisibleActionCreated: DateUtils.getDBTime(), childOldestFourAccountIDs: `${actorAccountID}`, }, ); - const subtitleComment = task.subtitle ? ReportUtils.buildOptimisticAddCommentReportAction(task.subtitle, undefined, actorAccountID) : null; + const subtitleComment = hasSubtitle ? ReportUtils.buildOptimisticAddCommentReportAction(task.subtitle, undefined, actorAccountID) : null; const isTaskMessageFunction = typeof task.message === 'function'; const taskMessage = isTaskMessageFunction ? task.message({ From 0ef0b24fc8c14cd6e8999192e352aa76f8fc05aa Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Apr 2024 14:00:03 +0200 Subject: [PATCH 26/79] fix subtitle bold texts --- src/CONST.ts | 48 +++++++++++++++++++------------------- src/libs/actions/Report.ts | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index ab5a67274955..724e93bc740b 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3624,24 +3624,24 @@ const CONST = { type: 'createWorkspace', autoCompleted: true, title: 'Create a workspace', - subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', + subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', message: 'Here’s how to create a workspace:\n' + '\n' + '1. Click your profile picture.\n' + '2. Click Workspaces > New workspace.\n' + '\n' + - 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', + 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', }, { type: 'trackExpense', autoCompleted: false, title: 'Track an expense', - subtitle: 'Track an expense in any currency, in just a few clicks.', + subtitle: 'Track an expense in any currency, in just a few clicks.', message: 'Here’s how to track an expense:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Track expense.\n' + '3. Enter an amount or scan a receipt.\n' + '4. Click Track.\n' + @@ -3664,11 +3664,11 @@ const CONST = { type: 'submitExpense', autoCompleted: false, title: 'Submit an expense', - subtitle: 'Submit an expense by entering an amount or scanning a receipt.', + subtitle: 'Submit an expense by entering an amount or scanning a receipt.', message: 'Here’s how to submit an expense:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Submit expense.\n' + '3. Enter an amount or scan a receipt.\n' + '4. Add your reimburser to the request.\n' + @@ -3679,7 +3679,7 @@ const CONST = { type: 'enableWallet', autoCompleted: false, title: 'Enable your wallet', - subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', + subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', message: 'Here’s how to set up your wallet:\n' + '\n' + @@ -3705,14 +3705,14 @@ const CONST = { type: 'createWorkspace', autoCompleted: true, title: 'Create a workspace', - subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', + subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', message: 'Here’s how to create a workspace:\n' + '\n' + '1. Click your profile picture.\n' + '2. Click Workspaces > New workspace.\n' + '\n' + - 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', + 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', }, { type: 'meetGuide', @@ -3728,7 +3728,7 @@ const CONST = { type: 'setupCategories', autoCompleted: false, title: 'Set up categories', - subtitle: 'Set up categories so your team can code expenses for easy reporting.', + subtitle: 'Set up categories so your team can code expenses for easy reporting.', message: 'Here’s how to set up categories:\n' + '\n' + @@ -3738,21 +3738,21 @@ const CONST = { '4. Enable and disable default categories.\n' + '5. Click Add categories to make your own.\n' + '\n' + - 'For more controls like requiring a category for every expense, click Settings.', + 'For more controls like requiring a category for every expense, click Settings.', }, { type: 'addExpenseApprovals', autoCompleted: false, title: 'Add expense approvals', - subtitle: 'Add expense approvals to review your team’s spend and keep it under control.', + subtitle: 'Add expense approvals to review your team’s spend and keep it under control.', message: 'Here’s how to add expense approvals:\n' + '\n' + '1. Click your profile picture.\n' + - '2. Go to Workspaces > [your workspace].\n' + + '2. Go to Workspaces > [your workspace].\n' + '3. Click More features.\n' + '4. Enable Workflows.\n' + - '5. In Workflows, enable Add approvals.\n' + + '5. In Workflows, enable Add approvals.\n' + '\n' + 'You’ll be set as the expense approver. You can change this to any admin once you invite your team.', }, @@ -3760,7 +3760,7 @@ const CONST = { type: 'inviteTeam', autoCompleted: false, title: 'Invite your team', - subtitle: 'Invite your team to Expensify so they can start tracking expenses today.', + subtitle: 'Invite your team to Expensify so they can start tracking expenses today.', message: 'Here’s how to invite your team:\n' + '\n' + @@ -3788,14 +3788,14 @@ const CONST = { type: 'trackExpense', autoCompleted: false, title: 'Track an expense', - subtitle: 'Track an expense in any currency, whether you have a receipt or not.', + subtitle: 'Track an expense in any currency, whether you have a receipt or not.', message: 'Here’s how to track an expense:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Track expense.\n' + '3. Enter an amount or scan a receipt.\n' + - '4. Click Track.\n' + + '4. Click Track.\n' + '\n' + 'And you’re done! Yep, it’s that easy.', }, @@ -3815,15 +3815,15 @@ const CONST = { type: 'startChat', autoCompleted: false, title: 'Start a chat', - subtitle: 'Start a chat with a friend or group using their email or phone number.', + subtitle: 'Start a chat with a friend or group using their email or phone number.', message: 'Here’s how to start a chat:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Start chat.\n' + '3. Enter emails or phone numbers.\n' + '\n' + - 'If any of your friends aren’t using Expensify already, they’ll be invited automatically. \n' + + 'If any of your friends aren’t using Expensify already, they’ll be invited automatically.\n' + '\n' + 'Every chat will also turn into an email or text that they can respond to directly.', }, @@ -3831,11 +3831,11 @@ const CONST = { type: 'splitExpense', autoCompleted: false, title: 'Split an expense', - subtitle: 'Split an expense right in your chat with one or more friends.', + subtitle: 'Split an expense right in your chat with one or more friends.', message: 'Here’s how to request money:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Split expense.\n' + '3. Scan a receipt or enter an amount.\n' + '4. Add your friend(s) to the request.\n' + @@ -3846,7 +3846,7 @@ const CONST = { type: 'enableWallet', autoCompleted: false, title: 'Enable your wallet', - subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', + subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', message: 'Here’s how to enable your wallet:\n' + '\n' + diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 4bc72b59293c..4f1f2c41b258 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3073,7 +3073,7 @@ function completeOnboarding( childOldestFourAccountIDs: `${actorAccountID}`, }, ); - const subtitleComment = hasSubtitle ? ReportUtils.buildOptimisticAddCommentReportAction(task.subtitle, undefined, actorAccountID) : null; + const subtitleComment = hasSubtitle ? ReportUtils.buildOptimisticAddCommentReportAction(task.subtitle, undefined, actorAccountID, 0, false) : null; const isTaskMessageFunction = typeof task.message === 'function'; const taskMessage = isTaskMessageFunction ? task.message({ From 10ff1935692695a473f78ffaffb336db1e2975d9 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Mon, 22 Apr 2024 23:13:25 +0800 Subject: [PATCH 27/79] add comment --- src/libs/PolicyUtils.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index de2731bba752..731dc5700c8e 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -333,6 +333,9 @@ function getDefaultApprover(policy: OnyxEntry | EmptyObject): string { return policy?.approver ?? policy?.owner ?? ''; } +/** + * Returns the accountID to whom the given employeeAccountID submits reports to in the given Policy. + */ function getSubmitToAccountID(policy: OnyxEntry | EmptyObject, employeeAccountID: number): number { const employeeLogin = getLoginsByAccountIDs([employeeAccountID])[0]; const defaultApprover = getDefaultApprover(policy); From 7ee2d7aefb90e3158a560a2aaa1bb3af0486f1a3 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Apr 2024 18:35:33 +0200 Subject: [PATCH 28/79] implement failure data --- src/libs/actions/Report.ts | 75 +++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 4f1f2c41b258..bd3e749d0473 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -3220,6 +3220,33 @@ function completeOnboarding( [], ); + const tasksForFailureData = tasksData.reduce((acc, {currentTask, taskReportAction}) => { + const tasksForFailureDataAcc: OnyxUpdate[] = [ + ...acc, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${targetChatReportID}`, + value: { + [taskReportAction.reportAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${currentTask.reportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${currentTask.reportID}`, + value: null, + }, + ]; + + return tasksForFailureDataAcc; + }, []); + const optimisticData: OnyxUpdate[] = [ ...tasksForOptimisticData, { @@ -3255,6 +3282,52 @@ function completeOnboarding( }, }, ]; + let failureReport: Partial = { + lastMessageTranslationKey: '', + lastMessageText: '', + lastVisibleActionCreated: '', + }; + const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportActionsUtils.getLastVisibleMessage(targetChatReportID); + if (lastMessageText || lastMessageTranslationKey) { + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(targetChatReportID); + const lastVisibleActionCreated = lastVisibleAction?.created; + const lastActorAccountID = lastVisibleAction?.actorAccountID; + failureReport = { + lastMessageTranslationKey, + lastMessageText, + lastVisibleActionCreated, + lastActorAccountID, + }; + } + + const failureData: OnyxUpdate[] = [ + ...tasksForFailureData, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`, + value: failureReport, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${targetChatReportID}`, + value: { + [mentionCommentAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + [textCommentAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + [videoCommentAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_INTRO_SELECTED, + value: {choice: null}, + }, + ]; const guidedSetupData: GuidedSetupData = [ {type: 'message', ...mentionMessage}, @@ -3270,7 +3343,7 @@ function completeOnboarding( guidedSetupData: JSON.stringify(guidedSetupData), }; - API.write(WRITE_COMMANDS.COMPLETE_GUIDED_SETUP, parameters, {optimisticData, successData}); + API.write(WRITE_COMMANDS.COMPLETE_GUIDED_SETUP, parameters, {optimisticData, successData, failureData}); } /** From 77f0fb359e00585dacf1d55333259dccf3d17113 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 22 Apr 2024 15:07:08 -0600 Subject: [PATCH 29/79] rename search page --- src/languages/en.ts | 3 ++- src/languages/es.ts | 3 ++- .../AppNavigator/createCustomBottomTabNavigator/TopBar.tsx | 4 ++-- src/pages/ChatFinderPage/index.tsx | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index e00325837af2..3faff138db9b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -129,6 +129,7 @@ export default { optional: 'Optional', new: 'New', search: 'Search', + find: 'Find', searchWithThreeDots: 'Search...', next: 'Next', previous: 'Previous', @@ -550,7 +551,7 @@ export default { }, }, sidebarScreen: { - buttonSearch: 'Search for something...', + buttonFind: 'Find something...', buttonMySettings: 'My settings', fabNewChat: 'Start chat', fabNewChatExplained: 'Start chat (Floating action)', diff --git a/src/languages/es.ts b/src/languages/es.ts index 5011793b3295..782d14ffe20b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -119,6 +119,7 @@ export default { optional: 'Opcional', new: 'Nuevo', search: 'Buscar', + find: 'Encontrar', searchWithThreeDots: 'Buscar...', select: 'Seleccionar', next: 'Siguiente', @@ -543,7 +544,7 @@ export default { }, }, sidebarScreen: { - buttonSearch: 'Busca algo...', + buttonFind: 'Encuentre algo...', buttonMySettings: 'Mi configuración', fabNewChat: 'Iniciar chat', fabNewChatExplained: 'Iniciar chat (Acción flotante)', diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx index a06c9d08c529..d867ae779a9c 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx @@ -62,9 +62,9 @@ function TopBar({policy, session}: TopBarProps) { {isAnonymousUser ? ( ) : ( - + Navigation.navigate(ROUTES.CHAT_FINDER))} > diff --git a/src/pages/ChatFinderPage/index.tsx b/src/pages/ChatFinderPage/index.tsx index f992fa37d8c5..ccac9bac21ed 100644 --- a/src/pages/ChatFinderPage/index.tsx +++ b/src/pages/ChatFinderPage/index.tsx @@ -169,7 +169,7 @@ function ChatFinderPage({betas, isSearchingForReports, navigation}: ChatFinderPa > From 8f0fc1e176d81a306b20a1f79d1d5347c206686e Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 23 Apr 2024 04:25:33 +0700 Subject: [PATCH 30/79] fix workspace list does not show --- src/components/OptionListContextProvider.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/OptionListContextProvider.tsx b/src/components/OptionListContextProvider.tsx index a83eeda5a419..a8441cfad7af 100644 --- a/src/components/OptionListContextProvider.tsx +++ b/src/components/OptionListContextProvider.tsx @@ -84,16 +84,18 @@ function OptionsListContextProvider({reports, children}: OptionsListProviderProp if (!areOptionsInitialized.current || !reports) { return; } - const missingReportId = Object.keys(reports).find((key) => prevReports && !(key in prevReports)); - const report = missingReportId ? reports[missingReportId] : null; - if (!missingReportId || !report) { - return; - } + const missingReportIds = Object.keys(reports).filter((key) => prevReports && !(key in prevReports)); - const reportOption = OptionsListUtils.createOptionFromReport(report, personalDetails); setOptions((prevOptions) => { const newOptions = {...prevOptions}; - newOptions.reports.push(reportOption); + missingReportIds.forEach((missingReportId) => { + const report = missingReportId ? reports[missingReportId] : null; + if (!missingReportId || !report) { + return; + } + const reportOption = OptionsListUtils.createOptionFromReport(report, personalDetails); + newOptions.reports.push(reportOption); + }); return newOptions; }); // eslint-disable-next-line react-hooks/exhaustive-deps From dd18fab4d470bfe9d2ab20adb5c4372074b40d41 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Mon, 22 Apr 2024 23:31:28 +0200 Subject: [PATCH 31/79] Add comments for useEffects --- src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx | 1 + src/pages/workspace/WorkspaceInitialPage.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index e7ea95ba44f4..a2bd6ff4a31e 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -44,6 +44,7 @@ function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNo const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); + // If the feature is pending, we should not update the feature state useEffect(() => { if (pendingField && !isOffline && !isFeatureEnabled) { return; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 517c9b5251b9..951eaed7564b 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -186,6 +186,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = []; + // If features are pending, we should not update feature states useEffect(() => { setFeatureStates((currentFeatureStates) => { const newFeatureStates = {} as PolicyFeatureStates; From b1295523820d2a3b76c5b1fb6a6ec8ecf23ae5ad Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Tue, 23 Apr 2024 11:08:14 +0200 Subject: [PATCH 32/79] update translation --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 112993f848f6..97e716caeb44 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -313,7 +313,7 @@ export default { subtitleText2: 'o crea algo usando el botón', subtitleText3: '.', }, - businessName: 'Nombre del Negocio', + businessName: 'Nombre de la empresa', }, location: { useCurrent: 'Usar ubicación actual', From 0ebd5be3aad16bfcab6585dced597bf5b5e5202e Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:59:35 +0700 Subject: [PATCH 33/79] Update src/components/LHNOptionsList/types.ts Co-authored-by: Pavlo Tsimura --- src/components/LHNOptionsList/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/types.ts b/src/components/LHNOptionsList/types.ts index 83601b4553d4..79b5f5ad3889 100644 --- a/src/components/LHNOptionsList/types.ts +++ b/src/components/LHNOptionsList/types.ts @@ -74,7 +74,7 @@ type OptionRowLHNDataProps = { /** The full data of the report */ fullReport: OnyxEntry; - /** The transaction thread report associated with the current report, if any */ + /** The transaction thread report associated with the current report – applicable only for one-transaction money reports */ transactionThreadReport: OnyxEntry; /** The policy which the user has access to and which the report could be tied to */ From d62791a94177b32be70f1560893c3801008d4a87 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 23 Apr 2024 17:08:55 +0700 Subject: [PATCH 34/79] wrap subscribe into check transaction thread report --- src/pages/home/report/ReportActionsList.tsx | 32 +++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 8eb8c25f83d3..b1fcd4040f99 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -299,16 +299,6 @@ function ReportActionsList({ setMessageManuallyMarkedUnread(0); }); - const unreadActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`unreadAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { - resetUnreadMarker(newLastReadTime); - setMessageManuallyMarkedUnread(new Date().getTime()); - }); - - const readNewestActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`readNewestAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { - resetUnreadMarker(newLastReadTime); - setMessageManuallyMarkedUnread(0); - }); - const deletedReportActionSubscription = DeviceEventEmitter.addListener(`deletedReportAction_${report.reportID}`, (reportActionID) => { if (cacheUnreadMarkers.get(report.reportID) !== reportActionID) { return; @@ -317,12 +307,30 @@ function ReportActionsList({ setMessageManuallyMarkedUnread(new Date().getTime()); }); + let unreadActionSubscriptionForTransactionThread = null; + let readNewestActionSubscriptionForTransactionThread = null; + if (transactionThreadReport?.reportID) { + unreadActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`unreadAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { + resetUnreadMarker(newLastReadTime); + setMessageManuallyMarkedUnread(new Date().getTime()); + }); + + readNewestActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`readNewestAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { + resetUnreadMarker(newLastReadTime); + setMessageManuallyMarkedUnread(0); + }); + } + return () => { unreadActionSubscription.remove(); readNewestActionSubscription.remove(); - unreadActionSubscriptionForTransactionThread.remove(); - readNewestActionSubscriptionForTransactionThread.remove(); deletedReportActionSubscription.remove(); + if (unreadActionSubscriptionForTransactionThread) { + unreadActionSubscriptionForTransactionThread.remove(); + } + if (readNewestActionSubscriptionForTransactionThread) { + readNewestActionSubscriptionForTransactionThread.remove(); + } }; }, [report.reportID, transactionThreadReport?.reportID]); From 553ab3e29d13a18e27934846b8da4b921a159ed3 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Tue, 23 Apr 2024 18:17:16 +0700 Subject: [PATCH 35/79] fix typescript check --- src/pages/home/report/ReportActionsList.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index b1fcd4040f99..4f1288181b29 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -4,7 +4,7 @@ import type {RouteProp} from '@react-navigation/native'; import type {DebouncedFunc} from 'lodash'; import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {DeviceEventEmitter, InteractionManager} from 'react-native'; -import type {LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, StyleProp, ViewStyle} from 'react-native'; +import type {EmitterSubscription, LayoutChangeEvent, NativeScrollEvent, NativeSyntheticEvent, StyleProp, ViewStyle} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import InvertedFlatList from '@components/InvertedFlatList'; @@ -307,8 +307,8 @@ function ReportActionsList({ setMessageManuallyMarkedUnread(new Date().getTime()); }); - let unreadActionSubscriptionForTransactionThread = null; - let readNewestActionSubscriptionForTransactionThread = null; + let unreadActionSubscriptionForTransactionThread: EmitterSubscription | null = null; + let readNewestActionSubscriptionForTransactionThread: EmitterSubscription | null = null; if (transactionThreadReport?.reportID) { unreadActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`unreadAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { resetUnreadMarker(newLastReadTime); From 29269b72f55eba0248ba07633a5c9ef26647d7b5 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Tue, 23 Apr 2024 17:37:09 +0200 Subject: [PATCH 36/79] Update comments --- src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx | 3 ++- src/pages/workspace/WorkspaceInitialPage.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index a2bd6ff4a31e..c7152db715c3 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -44,7 +44,8 @@ function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNo const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); - // If the feature is pending, we should not update the feature state + // If the feature is pending, we should not update the feature state. + // This is due to that during the creation of a workspace the feature state changes several times while we are waiting for a response from the backend, what unexpectedly causes 'Not Found' to be shown. useEffect(() => { if (pendingField && !isOffline && !isFeatureEnabled) { return; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 951eaed7564b..d2f242a9d360 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -186,7 +186,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = []; - // If features are pending, we should not update feature states + // If features are pending, we should not update feature states. + // These changes are made to synchronously change feature states along with FeatureEnabledAccessOrNotFoundComponent. useEffect(() => { setFeatureStates((currentFeatureStates) => { const newFeatureStates = {} as PolicyFeatureStates; From 7752289a55ed15da5cfa3f4a10294d968442b9a4 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Tue, 23 Apr 2024 20:01:21 +0200 Subject: [PATCH 37/79] Update comments x3 --- .../workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx | 5 +++-- src/pages/workspace/WorkspaceInitialPage.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx index c7152db715c3..f3a1c51238e5 100644 --- a/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/FeatureEnabledAccessOrNotFoundWrapper.tsx @@ -44,8 +44,9 @@ function FeatureEnabledAccessOrNotFoundComponent(props: FeatureEnabledAccessOrNo const shouldShowNotFoundPage = isEmptyObject(props.policy) || !props.policy?.id || !isPolicyFeatureEnabled; const shouldShowFullScreenLoadingIndicator = props.isLoadingReportData !== false && (!Object.entries(props.policy ?? {}).length || !props.policy?.id); - // If the feature is pending, we should not update the feature state. - // This is due to that during the creation of a workspace the feature state changes several times while we are waiting for a response from the backend, what unexpectedly causes 'Not Found' to be shown. + // We only update the feature state if it isn't pending. + // This is because the feature state changes several times during the creation of a workspace, while we are waiting for a response from the backend. + // Without this, we can have unexpectedly have 'Not Found' be shown. useEffect(() => { if (pendingField && !isOffline && !isFeatureEnabled) { return; diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index d2f242a9d360..eb41089160e3 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -186,7 +186,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, reimbursementAcc const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = []; - // If features are pending, we should not update feature states. + // We only update feature states if they aren't pending. // These changes are made to synchronously change feature states along with FeatureEnabledAccessOrNotFoundComponent. useEffect(() => { setFeatureStates((currentFeatureStates) => { From 666e9dab5eb4d064dec1d018b76e9f27e5a0fbb4 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 02:48:13 +0700 Subject: [PATCH 38/79] fix jest test --- src/libs/OptionsListUtils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 049e538cb18a..4f647e760519 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1743,9 +1743,6 @@ function getOptions( // Exclude the current user from the personal details list const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}]; - if (!includeSelfDM) { - optionsToExclude.push({login: currentUserLogin}); - } // If we're including selected options from the search results, we only want to exclude them if the search input is empty // This is because on certain pages, we show the selected options at the top when the search input is empty @@ -1824,6 +1821,7 @@ function getOptions( } if (includePersonalDetails) { + optionsToExclude.push({login: currentUserLogin}); // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { From f60a61093e447477b14b65a5ef96caa3df36bbb6 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 03:00:39 +0700 Subject: [PATCH 39/79] fix move logic push currentUserLogin to top --- src/libs/OptionsListUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 4f647e760519..de1f1ca797f4 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1820,8 +1820,8 @@ function getOptions( } } + optionsToExclude.push({login: currentUserLogin}); if (includePersonalDetails) { - optionsToExclude.push({login: currentUserLogin}); // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { From 6698121471588e6138e368126802df2d5182ab03 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 10:00:06 +0700 Subject: [PATCH 40/79] fix create new var personalDetailsOptionsToExclude --- src/libs/OptionsListUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index de1f1ca797f4..508aead725a4 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1820,11 +1820,11 @@ function getOptions( } } - optionsToExclude.push({login: currentUserLogin}); if (includePersonalDetails) { + const personalDetailsOptionsToExclude = [...optionsToExclude, {login: currentUserLogin}]; // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { - if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { + if (personalDetailsOptionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { return; } const {searchText, participantsList, isChatRoom} = personalDetailOption; From 003defb7825d83f3b6d8406351b549c0880342a1 Mon Sep 17 00:00:00 2001 From: nkdengineer Date: Wed, 24 Apr 2024 10:00:48 +0700 Subject: [PATCH 41/79] fix remove comment --- src/libs/OptionsListUtils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 508aead725a4..b9e62be19769 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1741,7 +1741,6 @@ function getOptions( allPersonalDetailsOptions = lodashOrderBy(allPersonalDetailsOptions, [(personalDetail) => personalDetail.text?.toLowerCase()], 'asc'); } - // Exclude the current user from the personal details list const optionsToExclude: Option[] = [{login: CONST.EMAIL.NOTIFICATIONS}]; // If we're including selected options from the search results, we only want to exclude them if the search input is empty From 3c63a696208078b9206b516201f64787a9b53f43 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 24 Apr 2024 12:20:16 +0800 Subject: [PATCH 42/79] set auto grow height input max height from a different prop --- .../TextInput/BaseTextInput/index.native.tsx | 10 +++++----- src/components/TextInput/BaseTextInput/index.tsx | 10 +++++----- src/components/TextInput/BaseTextInput/types.ts | 5 +++++ src/pages/PrivateNotes/PrivateNotesEditPage.tsx | 3 ++- src/pages/RoomDescriptionPage.tsx | 3 ++- .../iou/request/step/IOURequestStepDescription.tsx | 3 ++- .../settings/ExitSurvey/ExitSurveyResponsePage.tsx | 3 ++- src/pages/settings/Security/CloseAccountPage.tsx | 4 +++- src/pages/tasks/NewTaskDescriptionPage.tsx | 3 ++- src/pages/tasks/NewTaskDetailsPage.tsx | 3 ++- src/pages/tasks/TaskDescriptionPage.tsx | 3 ++- src/pages/workspace/WorkspaceInviteMessagePage.tsx | 3 ++- src/pages/workspace/WorkspaceNewRoomPage.tsx | 2 +- .../workspace/WorkspaceProfileDescriptionPage.tsx | 3 ++- src/stories/TextInput.stories.tsx | 7 ++----- src/styles/index.ts | 4 ---- src/styles/variables.ts | 1 + 17 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index 25d91bbabc91..4c2d5e3aea82 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -49,6 +49,7 @@ function BaseTextInput( disableKeyboard = false, autoGrow = false, autoGrowHeight = false, + maxAutoGrowHeight, hideFocusedState = false, maxLength = undefined, hint = '', @@ -245,14 +246,13 @@ function BaseTextInput( // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const inputHelpText = errorText || hint; const placeholderValue = !!prefixCharacter || isFocused || !hasLabel || (hasLabel && forceActiveLabel) ? placeholder : undefined; - const maxHeight = StyleSheet.flatten(containerStyles)?.maxHeight; const newTextInputContainerStyles: StyleProp = StyleSheet.flatten([ styles.textInputContainer, textInputContainerStyles, autoGrow && StyleUtils.getWidthStyle(textInputWidth), !hideFocusedState && isFocused && styles.borderColorFocus, (!!hasError || !!errorText) && styles.borderColorDanger, - autoGrowHeight && {scrollPaddingTop: typeof maxHeight === 'number' ? 2 * maxHeight : undefined}, + autoGrowHeight && {scrollPaddingTop: typeof maxAutoGrowHeight === 'number' ? 2 * maxAutoGrowHeight : undefined}, ]); return ( @@ -267,7 +267,7 @@ function BaseTextInput( onLayout={onLayout} accessibilityLabel={label} style={[ - autoGrowHeight && styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxHeight === 'number' ? maxHeight : 0), + autoGrowHeight && styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), !isMultiline && styles.componentHeightLarge, touchableInputWrapperStyle, ]} @@ -346,7 +346,7 @@ function BaseTextInput( // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. ...(autoGrowHeight - ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, typeof maxHeight === 'number' ? maxHeight : 0), styles.verticalAlignTop] + ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), styles.verticalAlignTop] : []), // Add disabled color theme when field is not editable. inputProps.disabled && styles.textInputDisabled, @@ -421,7 +421,7 @@ function BaseTextInput( = StyleSheet.flatten([ styles.textInputContainer, textInputContainerStyles, autoGrow && StyleUtils.getWidthStyle(textInputWidth), !hideFocusedState && isFocused && styles.borderColorFocus, (!!hasError || !!errorText) && styles.borderColorDanger, - autoGrowHeight && {scrollPaddingTop: typeof maxHeight === 'number' ? 2 * maxHeight : undefined}, + autoGrowHeight && {scrollPaddingTop: typeof maxAutoGrowHeight === 'number' ? 2 * maxAutoGrowHeight : undefined}, ]); const isMultiline = multiline || autoGrowHeight; @@ -287,7 +287,7 @@ function BaseTextInput( // or if multiline is not supplied we calculate the textinput height, using onLayout. onLayout={onLayout} style={[ - autoGrowHeight && styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxHeight === 'number' ? maxHeight : 0), + autoGrowHeight && styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), !isMultiline && styles.componentHeightLarge, touchableInputWrapperStyle, ]} @@ -372,7 +372,7 @@ function BaseTextInput( // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. ...(autoGrowHeight - ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, typeof maxHeight === 'number' ? maxHeight : 0), styles.verticalAlignTop] + ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), styles.verticalAlignTop] : []), // Add disabled color theme when field is not editable. @@ -448,7 +448,7 @@ function BaseTextInput( { diff --git a/src/pages/RoomDescriptionPage.tsx b/src/pages/RoomDescriptionPage.tsx index 9d26de1da9f1..ac3d182b9189 100644 --- a/src/pages/RoomDescriptionPage.tsx +++ b/src/pages/RoomDescriptionPage.tsx @@ -15,6 +15,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ReportUtils from '@libs/ReportUtils'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; +import variables from '@styles/variables'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -84,6 +85,7 @@ function RoomDescriptionPage({report, policies}: RoomDescriptionPageProps) { accessibilityLabel={translate('reportDescriptionPage.roomDescription')} role={CONST.ROLE.PRESENTATION} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} maxLength={CONST.REPORT_DESCRIPTION.MAX_LENGTH} ref={(el: BaseTextInputRef | null): void => { if (!el) { @@ -95,7 +97,6 @@ function RoomDescriptionPage({report, policies}: RoomDescriptionPageProps) { value={description} onChangeText={handleReportDescriptionChange} autoCapitalize="none" - containerStyles={[styles.autoGrowHeightMultilineInput]} /> diff --git a/src/pages/iou/request/step/IOURequestStepDescription.tsx b/src/pages/iou/request/step/IOURequestStepDescription.tsx index 4dd47def2d48..dfc2a8e379ca 100644 --- a/src/pages/iou/request/step/IOURequestStepDescription.tsx +++ b/src/pages/iou/request/step/IOURequestStepDescription.tsx @@ -17,6 +17,7 @@ import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; +import variables from '@styles/variables'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -176,7 +177,7 @@ function IOURequestStepDescription({ updateMultilineInputRange(inputRef.current); }} autoGrowHeight - containerStyles={[styles.autoGrowHeightMultilineInput]} + maxAutoGrowHeight={variables.maxAutoGrowHeight} shouldSubmitForm isMarkdownEnabled /> diff --git a/src/pages/settings/ExitSurvey/ExitSurveyResponsePage.tsx b/src/pages/settings/ExitSurvey/ExitSurveyResponsePage.tsx index badbdeb86d14..62183b0ebc26 100644 --- a/src/pages/settings/ExitSurvey/ExitSurveyResponsePage.tsx +++ b/src/pages/settings/ExitSurvey/ExitSurveyResponsePage.tsx @@ -128,6 +128,7 @@ function ExitSurveyResponsePage({draftResponse, route, navigation}: ExitSurveyRe accessibilityLabel={translate(`exitSurvey.responsePlaceholder`)} role={CONST.ROLE.PRESENTATION} autoGrowHeight + maxAutoGrowHeight={responseInputMaxHeight} maxLength={CONST.MAX_COMMENT_LENGTH} ref={(el: AnimatedTextInputRef) => { if (!el) { @@ -136,7 +137,7 @@ function ExitSurveyResponsePage({draftResponse, route, navigation}: ExitSurveyRe updateMultilineInputRange(el); inputCallbackRef(el); }} - containerStyles={[baseResponseInputContainerStyle, StyleUtils.getMaximumHeight(responseInputMaxHeight)]} + containerStyles={[baseResponseInputContainerStyle]} shouldSaveDraft /> diff --git a/src/pages/settings/Security/CloseAccountPage.tsx b/src/pages/settings/Security/CloseAccountPage.tsx index bcf65ecfe837..58acfeeb0f5c 100644 --- a/src/pages/settings/Security/CloseAccountPage.tsx +++ b/src/pages/settings/Security/CloseAccountPage.tsx @@ -17,6 +17,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as ValidationUtils from '@libs/ValidationUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; +import variables from '@styles/variables'; import * as CloseAccount from '@userActions/CloseAccount'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; @@ -101,10 +102,11 @@ function CloseAccountPage({session}: CloseAccountPageProps) { InputComponent={TextInput} inputID={INPUT_IDS.REASON_FOR_LEAVING} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} label={translate('closeAccountPage.enterMessageHere')} aria-label={translate('closeAccountPage.enterMessageHere')} role={CONST.ROLE.PRESENTATION} - containerStyles={[styles.mt5, styles.autoGrowHeightMultilineInput]} + containerStyles={[styles.mt5]} /> {translate('closeAccountPage.enterDefaultContactToConfirm')} {userEmailOrPhone} diff --git a/src/pages/tasks/NewTaskDescriptionPage.tsx b/src/pages/tasks/NewTaskDescriptionPage.tsx index e33241c52f4a..8c4fb4199180 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.tsx +++ b/src/pages/tasks/NewTaskDescriptionPage.tsx @@ -24,6 +24,7 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; +import variables from '@styles/variables'; type NewTaskDescriptionPageOnyxProps = { /** Task Creation Data */ @@ -87,8 +88,8 @@ function NewTaskDescriptionPage({task}: NewTaskDescriptionPageProps) { updateMultilineInputRange(el); }} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} shouldSubmitForm - containerStyles={styles.autoGrowHeightMultilineInput} isMarkdownEnabled /> diff --git a/src/pages/tasks/NewTaskDetailsPage.tsx b/src/pages/tasks/NewTaskDetailsPage.tsx index 6e58219051db..b8c16644c19c 100644 --- a/src/pages/tasks/NewTaskDetailsPage.tsx +++ b/src/pages/tasks/NewTaskDetailsPage.tsx @@ -17,6 +17,7 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {NewTaskNavigatorParamList} from '@libs/Navigation/types'; import playSound, {SOUNDS} from '@libs/Sound'; +import variables from '@styles/variables'; import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -130,8 +131,8 @@ function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { label={translate('newTaskPage.descriptionOptional')} accessibilityLabel={translate('newTaskPage.descriptionOptional')} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} shouldSubmitForm - containerStyles={styles.autoGrowHeightMultilineInput} defaultValue={parser.htmlToMarkdown(parser.replace(taskDescription))} value={taskDescription} onValueChange={setTaskDescription} diff --git a/src/pages/tasks/TaskDescriptionPage.tsx b/src/pages/tasks/TaskDescriptionPage.tsx index 9abe15a5bb80..fb3425cb2adb 100644 --- a/src/pages/tasks/TaskDescriptionPage.tsx +++ b/src/pages/tasks/TaskDescriptionPage.tsx @@ -20,6 +20,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import withReportOrNotFound from '@pages/home/report/withReportOrNotFound'; import type {WithReportOrNotFoundProps} from '@pages/home/report/withReportOrNotFound'; +import variables from '@styles/variables'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -118,8 +119,8 @@ function TaskDescriptionPage({report, currentUserPersonalDetails}: TaskDescripti updateMultilineInputRange(inputRef.current); }} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} shouldSubmitForm - containerStyles={[styles.autoGrowHeightMultilineInput]} isMarkdownEnabled /> diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/WorkspaceInviteMessagePage.tsx index 30d66662b996..7bc601252c79 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/WorkspaceInviteMessagePage.tsx @@ -27,6 +27,7 @@ import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; import type {SettingsNavigatorParamList} from '@navigation/types'; +import variables from '@styles/variables'; import * as Link from '@userActions/Link'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; @@ -198,7 +199,7 @@ function WorkspaceInviteMessagePage({ autoCompleteType="off" autoCorrect={false} autoGrowHeight - containerStyles={[styles.autoGrowHeightMultilineInput]} + maxAutoGrowHeight={variables.maxAutoGrowHeight} defaultValue={getDefaultWelcomeNote()} value={welcomeNote} onChangeText={(text: string) => { diff --git a/src/pages/workspace/WorkspaceNewRoomPage.tsx b/src/pages/workspace/WorkspaceNewRoomPage.tsx index 46a5b533372a..2d7fd946dc22 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.tsx +++ b/src/pages/workspace/WorkspaceNewRoomPage.tsx @@ -291,9 +291,9 @@ function WorkspaceNewRoomPage({policies, reports, formState, session, activePoli accessibilityLabel={translate('reportDescriptionPage.roomDescriptionOptional')} role={CONST.ROLE.PRESENTATION} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} maxLength={CONST.REPORT_DESCRIPTION.MAX_LENGTH} autoCapitalize="none" - containerStyles={[styles.autoGrowHeightMultilineInput]} shouldInterceptSwipe /> diff --git a/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx b/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx index 8086f2414e42..bcc2b0c210c7 100644 --- a/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx +++ b/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx @@ -13,6 +13,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; +import variables from '@styles/variables'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -99,11 +100,11 @@ function WorkspaceProfileDescriptionPage({policy}: Props) { autoFocus onChangeText={setDescription} autoGrowHeight + maxAutoGrowHeight={variables.maxAutoGrowHeight} isMarkdownEnabled ref={(el: BaseTextInputRef | null): void => { updateMultilineInputRange(el); }} - containerStyles={[styles.autoGrowHeightMultilineInput]} /> diff --git a/src/stories/TextInput.stories.tsx b/src/stories/TextInput.stories.tsx index a9ccc94f7c8d..98017c0b5db9 100644 --- a/src/stories/TextInput.stories.tsx +++ b/src/stories/TextInput.stories.tsx @@ -2,6 +2,7 @@ import type {Meta, StoryFn} from '@storybook/react'; import React, {useState} from 'react'; import TextInput from '@components/TextInput'; import type {BaseTextInputProps} from '@components/TextInput/BaseTextInput/types'; +import variables from '@styles/variables'; type TextInputStory = StoryFn; @@ -142,11 +143,7 @@ AutoGrowHeightInput.args = { name: 'AutoGrowHeight', placeholder: 'My placeholder text', autoGrowHeight: true, - textInputContainerStyles: [ - { - maxHeight: 115, - }, - ], + maxAutoGrowHeight: variables.maxAutoGrowHeight, }; export default story; diff --git a/src/styles/index.ts b/src/styles/index.ts index 2a5e9f13b932..1e2f2ba799bb 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -3275,10 +3275,6 @@ const styles = (theme: ThemeColors) => marginTop: 6, }, - autoGrowHeightMultilineInput: { - maxHeight: 115, - }, - peopleRow: { width: '100%', flexDirection: 'row', diff --git a/src/styles/variables.ts b/src/styles/variables.ts index ff1b20893110..00dcec7cbfdb 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -229,4 +229,5 @@ export default { mushroomTopHatWidth: 138, mushroomTopHatHeight: 128, bankButtonMargin: 23, + maxAutoGrowHeight: 115, } as const; From 6a83a06c98479f5d57c6729a9dd7805eaee7765d Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:38:33 +0700 Subject: [PATCH 43/79] Update src/pages/home/report/ReportActionsList.tsx Co-authored-by: Pavlo Tsimura --- src/pages/home/report/ReportActionsList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 778d69ce95ce..dfa5d9c10335 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -309,8 +309,8 @@ function ReportActionsList({ setMessageManuallyMarkedUnread(new Date().getTime()); }); - let unreadActionSubscriptionForTransactionThread: EmitterSubscription | null = null; - let readNewestActionSubscriptionForTransactionThread: EmitterSubscription | null = null; + let unreadActionSubscriptionForTransactionThread: EmitterSubscription | undefined; + let readNewestActionSubscriptionForTransactionThread: EmitterSubscription | undefined; if (transactionThreadReport?.reportID) { unreadActionSubscriptionForTransactionThread = DeviceEventEmitter.addListener(`unreadAction_${transactionThreadReport?.reportID}`, (newLastReadTime) => { resetUnreadMarker(newLastReadTime); From c07e107066b3d899a91635666f5b2e7af597734f Mon Sep 17 00:00:00 2001 From: nkdengineer <161821005+nkdengineer@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:38:40 +0700 Subject: [PATCH 44/79] Update src/pages/home/report/ReportActionsList.tsx Co-authored-by: Pavlo Tsimura --- src/pages/home/report/ReportActionsList.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index dfa5d9c10335..335737dbe8a3 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -327,12 +327,8 @@ function ReportActionsList({ unreadActionSubscription.remove(); readNewestActionSubscription.remove(); deletedReportActionSubscription.remove(); - if (unreadActionSubscriptionForTransactionThread) { - unreadActionSubscriptionForTransactionThread.remove(); - } - if (readNewestActionSubscriptionForTransactionThread) { - readNewestActionSubscriptionForTransactionThread.remove(); - } + unreadActionSubscriptionForTransactionThread?.remove(); + readNewestActionSubscriptionForTransactionThread?.remove(); }; }, [report.reportID, transactionThreadReport?.reportID]); From 5af49ecacd240177812594ae1cd0dfa785f5698b Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 24 Apr 2024 16:15:58 +0800 Subject: [PATCH 45/79] prettier --- src/pages/tasks/NewTaskDescriptionPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/tasks/NewTaskDescriptionPage.tsx b/src/pages/tasks/NewTaskDescriptionPage.tsx index 8c4fb4199180..34d842c39317 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.tsx +++ b/src/pages/tasks/NewTaskDescriptionPage.tsx @@ -17,6 +17,7 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {NewTaskNavigatorParamList} from '@libs/Navigation/types'; import updateMultilineInputRange from '@libs/updateMultilineInputRange'; +import variables from '@styles/variables'; import * as TaskActions from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -24,7 +25,6 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/NewTaskForm'; import type {Task} from '@src/types/onyx'; -import variables from '@styles/variables'; type NewTaskDescriptionPageOnyxProps = { /** Task Creation Data */ From a00ef2c85a74671c1361873d9c3da6be3d0ba5fc Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Thu, 18 Apr 2024 12:18:13 +0200 Subject: [PATCH 46/79] Add first version of SearchFilters component --- assets/images/all.svg | 1 + src/components/Icon/Expensicons.ts | 2 + src/pages/Search/SearchFilters.tsx | 93 ++++++++++++++++++++++++ src/pages/Search/SearchPageBottomTab.tsx | 51 +------------ 4 files changed, 99 insertions(+), 48 deletions(-) create mode 100644 assets/images/all.svg create mode 100644 src/pages/Search/SearchFilters.tsx diff --git a/assets/images/all.svg b/assets/images/all.svg new file mode 100644 index 000000000000..d1a833d280ce --- /dev/null +++ b/assets/images/all.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 877e4972a3ec..8d57e672141a 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -1,4 +1,5 @@ import AddReaction from '@assets/images/add-reaction.svg'; +import All from "@assets/images/all.svg"; import Android from '@assets/images/android.svg'; import Apple from '@assets/images/apple.svg'; import ArrowRightLong from '@assets/images/arrow-right-long.svg'; @@ -165,6 +166,7 @@ export { ActiveRoomAvatar, AddReaction, AdminRoomAvatar, + All, Android, AnnounceRoomAvatar, Apple, diff --git a/src/pages/Search/SearchFilters.tsx b/src/pages/Search/SearchFilters.tsx new file mode 100644 index 000000000000..175c630e672b --- /dev/null +++ b/src/pages/Search/SearchFilters.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import {View} from 'react-native'; +import MenuItem from '@components/MenuItem'; +import TabSelectorItem from '@components/TabSelector/TabSelectorItem'; +import useActiveRoute from '@hooks/useActiveRoute'; +import useSingleExecution from '@hooks/useSingleExecution'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import Navigation from '@libs/Navigation/Navigation'; +import * as Expensicons from '@src/components/Icon/Expensicons'; +import CONST from '@src/CONST'; +import type {Route} from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; +import type IconAsset from '@src/types/utils/IconAsset'; + +type SearchMenuItem = { + title: string; + icon: IconAsset; + route: Route; +}; + +const searchMenuItems: SearchMenuItem[] = [ + { + title: 'All', + icon: Expensicons.All, + route: ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.ALL), + }, + // More tabs prepared for final version but in v1 we support only "All" + // { + // title: 'Sent', + // icon: Expensicons.Send, + // route: ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.SENT), + // }, + // { + // title: 'Drafts', + // icon: Expensicons.Pencil, + // route: ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.DRAFTS), + // }, +]; + +function SearchFilters() { + const theme = useTheme(); + const styles = useThemeStyles(); + const {singleExecution} = useSingleExecution(); + const activeRoute = useActiveRoute(); + const {isSmallScreenWidth} = useWindowDimensions(); + + const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; + const flexDirection = isSmallScreenWidth && styles.flexRow; + + return ( + + {searchMenuItems.map((item) => { + const isActive = item.title.toLowerCase() === currentQuery; + const onPress = singleExecution(() => Navigation.navigate(item.route)); + + if (isSmallScreenWidth) { + return ( + + ); + } + + return ( + + ); + })} + + ); +} + +SearchFilters.displayName = 'SearchFilters'; + +export default SearchFilters; diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index f90f066d72a7..197b703404c3 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -1,14 +1,6 @@ import React from 'react'; -import {View} from 'react-native'; -import MenuItem from '@components/MenuItem'; import ScreenWrapper from '@components/ScreenWrapper'; -import useActiveRoute from '@hooks/useActiveRoute'; -import useSingleExecution from '@hooks/useSingleExecution'; -import useThemeStyles from '@hooks/useThemeStyles'; -import Navigation from '@libs/Navigation/Navigation'; -import * as Expensicons from '@src/components/Icon/Expensicons'; -import CONST from '@src/CONST'; -import ROUTES from '@src/ROUTES'; +import SearchFilters from './SearchFilters'; import type IconAsset from '@src/types/utils/IconAsset'; // import EmptySearchView from './EmptySearchView'; @@ -20,48 +12,11 @@ type SearchMenuItem = { }; function SearchPageBottomTab() { - const styles = useThemeStyles(); - const {singleExecution} = useSingleExecution(); - const activeRoute = useActiveRoute(); - const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; - - const searchMenuItems: SearchMenuItem[] = [ - { - title: 'All', - icon: Expensicons.ExpensifyLogoNew, - action: singleExecution(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.ALL))), - }, - { - title: 'Sent', - icon: Expensicons.ExpensifyLogoNew, - action: singleExecution(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.SENT))), - }, - { - title: 'Drafts', - icon: Expensicons.ExpensifyLogoNew, - action: singleExecution(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.TAB_SEARCH.DRAFTS))), - }, - ]; - return ( - - {searchMenuItems.map((item) => ( - - ))} - {/* */} + + {/* Search results list goes here */} ); } From 95da343e22bd6722dac3a83792671289108f6781 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Mon, 22 Apr 2024 11:58:16 +0200 Subject: [PATCH 47/79] Improve SearchFilters and add breadcrumbs --- .../createCustomBottomTabNavigator/TopBar.tsx | 14 +++++++------ src/pages/Search/SearchFilters.tsx | 20 +++++++++++-------- src/pages/Search/SearchPageBottomTab.tsx | 17 ++++++++-------- .../SidebarScreen/BaseSidebarScreen.tsx | 8 +++++++- src/styles/index.ts | 5 +++++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx index a06c9d08c529..573f2349d953 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar.tsx @@ -25,9 +25,9 @@ type TopBarOnyxProps = { }; // eslint-disable-next-line react/no-unused-prop-types -type TopBarProps = {activeWorkspaceID?: string} & TopBarOnyxProps; +type TopBarProps = {breadcrumbLabel: string; activeWorkspaceID?: string; shouldDisplaySearch?: boolean} & TopBarOnyxProps; -function TopBar({policy, session}: TopBarProps) { +function TopBar({policy, session, breadcrumbLabel, shouldDisplaySearch = true}: TopBarProps) { const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); @@ -39,6 +39,9 @@ function TopBar({policy, session}: TopBarProps) { type: CONST.BREADCRUMB_TYPE.ROOT, }; + const displaySignIn = isAnonymousUser; + const displaySearch = !isAnonymousUser && shouldDisplaySearch; + return ( - {isAnonymousUser ? ( - - ) : ( + {displaySignIn && } + {displaySearch && ( + style={[styles.searchFiltersTabItem]} + > + + ); } diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index 197b703404c3..fc95e59309c9 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -1,21 +1,22 @@ import React from 'react'; import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; +import TopBar from '@navigation/AppNavigator/createCustomBottomTabNavigator/TopBar'; import SearchFilters from './SearchFilters'; -import type IconAsset from '@src/types/utils/IconAsset'; // import EmptySearchView from './EmptySearchView'; -type SearchMenuItem = { - title: string; - icon: IconAsset; - action: () => void; -}; - function SearchPageBottomTab() { + const {translate} = useLocalize(); + return ( - {/* */} + + {/* */} {/* Search results list goes here */} ); diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx index fe61af021d7f..db30773f5155 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.tsx @@ -1,6 +1,7 @@ import React, {useEffect} from 'react'; import {View} from 'react-native'; import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Browser from '@libs/Browser'; import TopBar from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator/TopBar'; @@ -21,6 +22,8 @@ const startTimer = () => { function BaseSidebarScreen() { const styles = useThemeStyles(); const activeWorkspaceID = getPolicyIDFromNavigationState(); + const {translate} = useLocalize(); + useEffect(() => { Performance.markStart(CONST.TIMING.SIDEBAR_LOADED); Timing.start(CONST.TIMING.SIDEBAR_LOADED, true); @@ -36,7 +39,10 @@ function BaseSidebarScreen() { > {({insets}) => ( <> - + textLineThrough: { textDecorationLine: 'line-through', }, + + searchFiltersTabItem: { + flexBasis: '33%', + minWidth: 200, + }, } satisfies Styles); type ThemeStyles = ReturnType; From 66c8f860afebeee9e55a32507837c5513c31d3c1 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Mon, 22 Apr 2024 12:23:47 +0200 Subject: [PATCH 48/79] Add v2 styling of SearchFilters --- src/components/Icon/Expensicons.ts | 2 +- src/pages/Search/SearchFilters.tsx | 43 ++++++------- src/pages/Search/SearchFiltersNarrow.tsx | 78 ++++++++++++++++++++++++ src/styles/index.ts | 7 ++- 4 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 src/pages/Search/SearchFiltersNarrow.tsx diff --git a/src/components/Icon/Expensicons.ts b/src/components/Icon/Expensicons.ts index 8d57e672141a..2f0d8a05a572 100644 --- a/src/components/Icon/Expensicons.ts +++ b/src/components/Icon/Expensicons.ts @@ -1,5 +1,5 @@ import AddReaction from '@assets/images/add-reaction.svg'; -import All from "@assets/images/all.svg"; +import All from '@assets/images/all.svg'; import Android from '@assets/images/android.svg'; import Apple from '@assets/images/apple.svg'; import ArrowRightLong from '@assets/images/arrow-right-long.svg'; diff --git a/src/pages/Search/SearchFilters.tsx b/src/pages/Search/SearchFilters.tsx index 732fb47bb83a..d701057e44d3 100644 --- a/src/pages/Search/SearchFilters.tsx +++ b/src/pages/Search/SearchFilters.tsx @@ -1,10 +1,8 @@ import React from 'react'; import {View} from 'react-native'; import MenuItem from '@components/MenuItem'; -import TabSelectorItem from '@components/TabSelector/TabSelectorItem'; import useActiveRoute from '@hooks/useActiveRoute'; import useSingleExecution from '@hooks/useSingleExecution'; -import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import Navigation from '@libs/Navigation/Navigation'; @@ -13,14 +11,15 @@ import CONST from '@src/CONST'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type IconAsset from '@src/types/utils/IconAsset'; +import SearchFiltersNarrow from './SearchFiltersNarrow'; -type SearchMenuItem = { +type SearchMenuFilterItem = { title: string; icon: IconAsset; route: Route; }; -const searchMenuItems: SearchMenuItem[] = [ +const filterItems: SearchMenuFilterItem[] = [ { title: 'All', icon: Expensicons.All, @@ -40,39 +39,30 @@ const searchMenuItems: SearchMenuItem[] = [ ]; function SearchFilters() { - const theme = useTheme(); const styles = useThemeStyles(); const {singleExecution} = useSingleExecution(); const activeRoute = useActiveRoute(); const {isSmallScreenWidth} = useWindowDimensions(); const currentQuery = activeRoute?.params && 'query' in activeRoute.params ? activeRoute?.params?.query : ''; - const flexDirection = isSmallScreenWidth && styles.flexRow; + + if (isSmallScreenWidth) { + const activeItemLabel = String(currentQuery); + + return ( + + ); + } return ( - - {searchMenuItems.map((item) => { + + {filterItems.map((item) => { const isActive = item.title.toLowerCase() === currentQuery; const onPress = singleExecution(() => Navigation.navigate(item.route)); - if (isSmallScreenWidth) { - return ( - - - - ); - } - return ( (null); + + const openMenu = () => setIsPopoverVisible(true); + const closeMenu = () => setIsPopoverVisible(false); + + const activeItem = filterItems.find((item) => item.title.toLowerCase() === activeItemLabel); + const popoverMenuItems = filterItems.map((item) => ({ + text: item.title, + onSelected: singleExecution(() => Navigation.navigate(item.route)), + })); + + return ( + <> + + {({hovered}) => ( + + + + {activeItem?.title} + + + + )} + + + + ); +} + +SearchFiltersNarrow.displayName = 'SearchFiltersNarrow'; + +export default SearchFiltersNarrow; diff --git a/src/styles/index.ts b/src/styles/index.ts index 6d28f3c8bdc2..2e070b2e1d6d 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4875,9 +4875,10 @@ const styles = (theme: ThemeColors) => textDecorationLine: 'line-through', }, - searchFiltersTabItem: { - flexBasis: '33%', - minWidth: 200, + searchFiltersButtonText: { + marginLeft: 4, + marginRight: 4, + fontWeight: 'bold', }, } satisfies Styles); From c3f41b33447b66fdf2618731e8cd9798297ab37d Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 24 Apr 2024 11:48:23 +0200 Subject: [PATCH 49/79] update text on welcome video modal --- src/components/OnboardingWelcomeVideo.tsx | 2 +- src/languages/en.ts | 3 +-- src/languages/es.ts | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/OnboardingWelcomeVideo.tsx b/src/components/OnboardingWelcomeVideo.tsx index 6858d29f4d3c..8c851a452eda 100644 --- a/src/components/OnboardingWelcomeVideo.tsx +++ b/src/components/OnboardingWelcomeVideo.tsx @@ -148,7 +148,7 @@ function OnboardingWelcomeVideo() { success pressOnEnter onPress={closeModal} - text={translate('onboarding.welcomeVideo.button')} + text={translate('footer.getStarted')} /> diff --git a/src/languages/en.ts b/src/languages/en.ts index d3ffbc9bb368..6dab9fb4d03d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1319,8 +1319,7 @@ export default { onboarding: { welcomeVideo: { title: 'Welcome to Expensify', - description: 'Getting paid is as easy as sending a message.', - button: "Let's go", + description: 'One app to handle all your business and personal spend in a chat. Built for your business, your team, and your friends.', }, whatsYourName: "What's your name?", whereYouWork: 'Where do you work?', diff --git a/src/languages/es.ts b/src/languages/es.ts index d2f6eb9df514..28b98f2ee4a6 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1318,8 +1318,7 @@ export default { onboarding: { welcomeVideo: { title: 'Bienvenido a Expensify', - description: 'Cobrar es tan fácil como enviar un mensaje.', - button: 'Vámonos', + description: 'Una aplicación para gestionar todos tus gastos empresariales y personales en un chat. Pensada para tu empresa, tu equipo y tus amigos.', }, whatsYourName: '¿Cómo te llamas?', whereYouWork: '¿Dónde trabajas?', From 6d6a26ea785c6707adc0d76e8657fd843d46d6c0 Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 24 Apr 2024 12:15:54 +0200 Subject: [PATCH 50/79] increase time --- src/styles/variables.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/variables.ts b/src/styles/variables.ts index ff1b20893110..c7de01fdf6c6 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -203,7 +203,7 @@ export default { sectionIllustrationHeight: 220, photoUploadPopoverWidth: 335, onboardingModalWidth: 500, - welcomeVideoDelay: 500, + welcomeVideoDelay: 1000, // The height of the empty list is 14px (2px for borders and 12px for vertical padding) // This is calculated based on the values specified in the 'getGoogleListViewStyle' function of the 'StyleUtils' utility From 996886524b9b5d1201de3cb5ac2f989b4c06fadd Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 24 Apr 2024 12:49:12 +0200 Subject: [PATCH 51/79] fix translation --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 28b98f2ee4a6..5a19cae91e6c 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1318,7 +1318,7 @@ export default { onboarding: { welcomeVideo: { title: 'Bienvenido a Expensify', - description: 'Una aplicación para gestionar todos tus gastos empresariales y personales en un chat. Pensada para tu empresa, tu equipo y tus amigos.', + description: 'Una aplicación para gestionar todos tus gastos de empresa y personales en un chat. Pensada para tu empresa, tu equipo y tus amigos.', }, whatsYourName: '¿Cómo te llamas?', whereYouWork: '¿Dónde trabajas?', From 2353824775b40a7cb71dcad1f90a20b13ece9e8f Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Wed, 24 Apr 2024 14:32:52 +0200 Subject: [PATCH 52/79] fix welcome video modal options --- src/libs/Navigation/AppNavigator/AuthScreens.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 17f7b946c7ab..917f206cf4f0 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -161,6 +161,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie const {isSmallScreenWidth} = useWindowDimensions(); const {shouldUseNarrowLayout} = useOnboardingLayout(); const screenOptions = getRootNavigatorScreenOptions(isSmallScreenWidth, styles, StyleUtils); + const onboardingModalScreenOptions = useMemo(() => screenOptions.onboardingModalNavigator(shouldUseNarrowLayout), [screenOptions, shouldUseNarrowLayout]); const onboardingScreenOptions = useMemo( () => getOnboardingModalScreenOptions(isSmallScreenWidth, styles, StyleUtils, shouldUseNarrowLayout), [StyleUtils, isSmallScreenWidth, shouldUseNarrowLayout, styles], @@ -368,7 +369,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie /> Date: Wed, 24 Apr 2024 09:47:21 -0300 Subject: [PATCH 53/79] Edit ROUTES.ts and remove MONEY_REQUEST_* routes --- src/ROUTES.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 809f0778c3e4..aaff4dcf44e9 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -310,14 +310,6 @@ const ROUTES = { getRoute: (type: ValueOf, transactionID: string, reportID: string, backTo: string) => `${type}/edit/reason/${transactionID}?backTo=${backTo}&reportID=${reportID}` as const, }, - MONEY_REQUEST_MERCHANT: { - route: ':iouType/new/merchant/:reportID?', - getRoute: (iouType: IOUType, reportID = '') => `${iouType}/new/merchant/${reportID}` as const, - }, - MONEY_REQUEST_RECEIPT: { - route: ':iouType/new/receipt/:reportID?', - getRoute: (iouType: IOUType, reportID = '') => `${iouType}/new/receipt/${reportID}` as const, - }, MONEY_REQUEST_CREATE: { route: ':action/:iouType/start/:transactionID/:reportID', getRoute: (action: IOUAction, iouType: IOUType, transactionID: string, reportID: string) => `${action as string}/${iouType as string}/start/${transactionID}/${reportID}` as const, From ca99afa25b9c6a6f9b987dd7e23fa950e24f467e Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 09:48:29 -0300 Subject: [PATCH 54/79] Edit linkgingConfig.js and remove Money_Request* screens --- src/libs/Navigation/linkingConfig/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index f309b19563e1..439fba4dbf42 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -600,7 +600,6 @@ const config: LinkingOptions['config'] = { [SCREENS.MONEY_REQUEST.STEP_WAYPOINT]: ROUTES.MONEY_REQUEST_STEP_WAYPOINT.route, [SCREENS.MONEY_REQUEST.STEP_TAX_AMOUNT]: ROUTES.MONEY_REQUEST_STEP_TAX_AMOUNT.route, [SCREENS.MONEY_REQUEST.STEP_TAX_RATE]: ROUTES.MONEY_REQUEST_STEP_TAX_RATE.route, - [SCREENS.MONEY_REQUEST.RECEIPT]: ROUTES.MONEY_REQUEST_RECEIPT.route, [SCREENS.MONEY_REQUEST.STATE_SELECTOR]: {path: ROUTES.MONEY_REQUEST_STATE_SELECTOR.route, exact: true}, [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: ROUTES.IOU_SEND_ENABLE_PAYMENTS, [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: ROUTES.IOU_SEND_ADD_BANK_ACCOUNT, From e816dd569badc3de0831ac4ea9a23a088458dd97 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 09:49:21 -0300 Subject: [PATCH 55/79] Edit ModalStackNavigators.js remove old Money_Request* components --- src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index c1ead29096b2..2188941c96d2 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -91,7 +91,6 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator require('../../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: () => require('../../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.WAYPOINT]: () => require('../../../../pages/iou/MoneyRequestWaypointPage').default as React.ComponentType, - [SCREENS.MONEY_REQUEST.RECEIPT]: () => require('../../../../pages/EditRequestReceiptPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.STATE_SELECTOR]: () => require('../../../../pages/settings/Profile/PersonalDetails/StateSelectionPage').default as React.ComponentType, }); From c1d8cbc254290049bf62af54d8b69f17ba569090 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 09:58:32 -0300 Subject: [PATCH 56/79] Edit IOU.js and remove _temporaryForRefactor from the name of any methods --- src/libs/actions/IOU.ts | 21 +++---------------- .../step/IOURequestStepConfirmation.tsx | 6 +++--- .../request/step/IOURequestStepCurrency.tsx | 2 +- .../step/IOURequestStepParticipants.tsx | 2 +- .../step/IOURequestStepTaxAmountPage.tsx | 2 +- 5 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index ed83267e11e7..1539e88b1328 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -357,7 +357,7 @@ function setMoneyRequestCreated(transactionID: string, created: string, isDraft: } // eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestCurrency_temporaryForRefactor(transactionID: string, currency: string, isEditing = false) { +function setMoneyRequestCurrency(transactionID: string, currency: string, isEditing = false) { const fieldToUpdate = isEditing ? 'modifiedCurrency' : 'currency'; Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {[fieldToUpdate]: currency}); } @@ -383,12 +383,12 @@ function setMoneyRequestTag(transactionID: string, tag: string) { } // eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestBillable_temporaryForRefactor(transactionID: string, billable: boolean) { +function setMoneyRequestBillable(transactionID: string, billable: boolean) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {billable}); } // eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestParticipants_temporaryForRefactor(transactionID: string, participants: Participant[] = []) { +function setMoneyRequestParticipants(transactionID: string, participants: Participant[] = []) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {participants}); } @@ -5829,10 +5829,6 @@ function setMoneyRequestId(id: string) { Onyx.merge(ONYXKEYS.IOU, {id}); } -function setMoneyRequestCurrency(currency: string) { - Onyx.merge(ONYXKEYS.IOU, {currency}); -} - function setMoneyRequestTaxRate(transactionID: string, taxRate: TaxRatesOption) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {taxRate}); } @@ -5841,14 +5837,6 @@ function setMoneyRequestTaxAmount(transactionID: string, taxAmount: number, isDr Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {taxAmount}); } -function setMoneyRequestBillable(billable: boolean) { - Onyx.merge(ONYXKEYS.IOU, {billable}); -} - -function setMoneyRequestParticipants(participants: Participant[], isSplitRequest?: boolean) { - Onyx.merge(ONYXKEYS.IOU, {participants, isSplitRequest}); -} - function setShownHoldUseExplanation() { Onyx.set(ONYXKEYS.NVP_HOLD_USE_EXPLAINED, true); } @@ -6033,17 +6021,14 @@ export { setDraftSplitTransaction, setMoneyRequestAmount, setMoneyRequestBillable, - setMoneyRequestBillable_temporaryForRefactor, setMoneyRequestCategory, setMoneyRequestCreated, setMoneyRequestCurrency, - setMoneyRequestCurrency_temporaryForRefactor, setMoneyRequestDescription, setMoneyRequestId, setMoneyRequestMerchant, setMoneyRequestParticipants, setMoneyRequestParticipantsFromReport, - setMoneyRequestParticipants_temporaryForRefactor, setMoneyRequestPendingFields, setMoneyRequestReceipt, setMoneyRequestTag, diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index 0abc5ab06116..7a580b07b292 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -123,7 +123,7 @@ function IOURequestStepConfirmation({ const defaultBillable = !!policy?.defaultBillable; useEffect(() => { - IOU.setMoneyRequestBillable_temporaryForRefactor(transactionID, defaultBillable); + IOU.setMoneyRequestBillable(transactionID, defaultBillable); }, [transactionID, defaultBillable]); useEffect(() => { @@ -478,11 +478,11 @@ function IOURequestStepConfirmation({ } return participant; }); - IOU.setMoneyRequestParticipants_temporaryForRefactor(transactionID, newParticipants); + IOU.setMoneyRequestParticipants(transactionID, newParticipants); }; const setBillable = (billable: boolean) => { - IOU.setMoneyRequestBillable_temporaryForRefactor(transactionID, billable); + IOU.setMoneyRequestBillable(transactionID, billable); }; return ( diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.tsx b/src/pages/iou/request/step/IOURequestStepCurrency.tsx index c7c596d27a67..d03136063b61 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.tsx +++ b/src/pages/iou/request/step/IOURequestStepCurrency.tsx @@ -71,7 +71,7 @@ function IOURequestStepCurrency({ const confirmCurrencySelection = (option: CurrencyListItem) => { Keyboard.dismiss(); if (pageIndex !== 'confirm') { - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, option.currencyCode, action === CONST.IOU.ACTION.EDIT); + IOU.setMoneyRequestCurrency(transactionID, option.currencyCode, action === CONST.IOU.ACTION.EDIT); } navigateBack(option.currencyCode); }; diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index c071bacca44b..374d4e9777cf 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -75,7 +75,7 @@ function IOURequestStepParticipants({ const addParticipant = useCallback( (val: Participant[]) => { - IOU.setMoneyRequestParticipants_temporaryForRefactor(transactionID, val); + IOU.setMoneyRequestParticipants(transactionID, val); const rateID = DistanceRequestUtils.getCustomUnitRateID(val[0]?.reportID ?? ''); IOU.setCustomUnitRateID(transactionID, rateID); diff --git a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx index 8021282cf098..dfb5ec1ad81a 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx +++ b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx @@ -116,7 +116,7 @@ function IOURequestStepTaxAmountPage({ IOU.setMoneyRequestTaxAmount(transactionID, amountInSmallestCurrencyUnits, true); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency || CONST.CURRENCY.USD); + IOU.setMoneyRequestCurrency(transactionID, currency || CONST.CURRENCY.USD); if (backTo) { Navigation.goBack(backTo); From d69b9f172dc1c44b15b14384e0ace220dfb9e58d Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 09:59:55 -0300 Subject: [PATCH 57/79] remove EditRequestReceiptPage, EditSplitBillPage and EditRequestTagPage --- src/pages/EditRequestReceiptPage.js | 56 ----------------- src/pages/EditRequestTagPage.js | 67 --------------------- src/pages/EditSplitBillPage.tsx | 93 ----------------------------- 3 files changed, 216 deletions(-) delete mode 100644 src/pages/EditRequestReceiptPage.js delete mode 100644 src/pages/EditRequestTagPage.js delete mode 100644 src/pages/EditSplitBillPage.tsx diff --git a/src/pages/EditRequestReceiptPage.js b/src/pages/EditRequestReceiptPage.js deleted file mode 100644 index 40fe64da7eed..000000000000 --- a/src/pages/EditRequestReceiptPage.js +++ /dev/null @@ -1,56 +0,0 @@ -import PropTypes from 'prop-types'; -import React, {useState} from 'react'; -import {View} from 'react-native'; -import DragAndDropProvider from '@components/DragAndDrop/Provider'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import Navigation from '@libs/Navigation/Navigation'; -import IOURequestStepScan from './iou/request/step/IOURequestStepScan'; - -const propTypes = { - /** React Navigation route */ - route: PropTypes.shape({ - /** Params from the route */ - params: PropTypes.shape({ - /** The type of IOU report, i.e. bill, request, send */ - iouType: PropTypes.string, - - /** The report ID of the IOU */ - reportID: PropTypes.string, - }), - }).isRequired, -}; - -function EditRequestReceiptPage({route}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const [isDraggingOver, setIsDraggingOver] = useState(false); - - return ( - - {({safeAreaPaddingBottomStyle}) => ( - - - - - - - )} - - ); -} - -EditRequestReceiptPage.propTypes = propTypes; -EditRequestReceiptPage.displayName = 'EditRequestReceiptPage'; - -export default EditRequestReceiptPage; diff --git a/src/pages/EditRequestTagPage.js b/src/pages/EditRequestTagPage.js deleted file mode 100644 index fd9064f8b6fc..000000000000 --- a/src/pages/EditRequestTagPage.js +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import TagPicker from '@components/TagPicker'; -import Text from '@components/Text'; -import useLocalize from '@hooks/useLocalize'; -import useThemeStyles from '@hooks/useThemeStyles'; -import Navigation from '@libs/Navigation/Navigation'; - -const propTypes = { - /** Transaction default tag value */ - defaultTag: PropTypes.string.isRequired, - - /** The policyID we are getting tags for */ - policyID: PropTypes.string.isRequired, - - /** The tag list name to which the default tag belongs to */ - tagListName: PropTypes.string, - - /** Indicates which tag list index was selected */ - tagListIndex: PropTypes.number.isRequired, - - /** Callback to fire when the Save button is pressed */ - onSubmit: PropTypes.func.isRequired, -}; - -const defaultProps = { - tagListName: '', -}; - -function EditRequestTagPage({defaultTag, policyID, tagListName, tagListIndex, onSubmit}) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - - const selectTag = (tag) => { - onSubmit({tag: tag.searchText}); - }; - - return ( - - - {translate('iou.tagSelection')} - - - ); -} - -EditRequestTagPage.propTypes = propTypes; -EditRequestTagPage.defaultProps = defaultProps; -EditRequestTagPage.displayName = 'EditRequestTagPage'; - -export default EditRequestTagPage; diff --git a/src/pages/EditSplitBillPage.tsx b/src/pages/EditSplitBillPage.tsx deleted file mode 100644 index 26e08d8347f7..000000000000 --- a/src/pages/EditSplitBillPage.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; -import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; -import Navigation from '@libs/Navigation/Navigation'; -import type {SplitDetailsNavigatorParamList} from '@libs/Navigation/types'; -import * as ReportUtils from '@libs/ReportUtils'; -import type {TransactionChanges} from '@libs/TransactionUtils'; -import * as IOU from '@userActions/IOU'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import type SCREENS from '@src/SCREENS'; -import type {Report, ReportActions, Transaction} from '@src/types/onyx'; -import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; -import EditRequestTagPage from './EditRequestTagPage'; - -type EditSplitBillOnyxProps = { - /** The report currently being used */ - report: OnyxEntry; - - /** The report action for currently used report */ - // Used in withOnyx - // eslint-disable-next-line react/no-unused-prop-types - reportActions: OnyxEntry; - - /** The current transaction */ - transaction: OnyxEntry; - - /** The draft transaction that holds data to be persisted on the current transaction */ - draftTransaction: OnyxEntry; -}; - -type EditSplitBillProps = EditSplitBillOnyxProps & StackScreenProps; - -function EditSplitBillPage({route, transaction, draftTransaction, report}: EditSplitBillProps) { - const {field: fieldToEdit, reportID, reportActionID, tagIndex} = route.params; - - const {tag: transactionTag} = ReportUtils.getTransactionDetails(draftTransaction ?? transaction) ?? {}; - - function navigateBackToSplitDetails() { - Navigation.navigate(ROUTES.SPLIT_BILL_DETAILS.getRoute(reportID, reportActionID)); - } - - const setDraftSplitTransaction = (transactionChanges: TransactionChanges) => { - if (transaction) { - IOU.setDraftSplitTransaction(transaction.transactionID, transactionChanges); - } - navigateBackToSplitDetails(); - }; - - if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.TAG) { - return ( - { - setDraftSplitTransaction({tag: transactionChanges.tag.trim()}); - }} - /> - ); - } - - return ; -} - -EditSplitBillPage.displayName = 'EditSplitBillPage'; - -export default withOnyx({ - report: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID}`, - }, - reportActions: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${route.params.reportID}`, - canEvict: false, - }, - transaction: { - key: ({route, reportActions}: Partial) => { - const reportAction = reportActions?.[`${route?.params.reportActionID.toString()}`]; - const transactionID = (reportAction as OriginalMessageIOU)?.originalMessage.IOUTransactionID ? (reportAction as OriginalMessageIOU).originalMessage.IOUTransactionID : 0; - return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`; - }, - }, - draftTransaction: { - key: ({route, reportActions}: Partial) => { - const reportAction = reportActions?.[`${route?.params.reportActionID.toString()}`]; - const transactionID = (reportAction as OriginalMessageIOU)?.originalMessage.IOUTransactionID ? (reportAction as OriginalMessageIOU).originalMessage.IOUTransactionID : 0; - return `${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`; - }, - }, -})(EditSplitBillPage); From 90135a1dee292e65967e5a76858e8080656859fc Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 10:12:31 -0300 Subject: [PATCH 58/79] remove EditSplitBillPage related route and navigation --- src/ROUTES.ts | 5 ----- .../Navigation/AppNavigator/ModalStackNavigators/index.tsx | 1 - src/libs/Navigation/linkingConfig/config.ts | 1 - 3 files changed, 7 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index aaff4dcf44e9..b9dad98e27af 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -272,11 +272,6 @@ const ROUTES = { route: 'r/:reportID/split/:reportActionID', getRoute: (reportID: string, reportActionID: string) => `r/${reportID}/split/${reportActionID}` as const, }, - EDIT_SPLIT_BILL: { - route: `r/:reportID/split/:reportActionID/edit/:field/:tagIndex?`, - getRoute: (reportID: string, reportActionID: string, field: ValueOf, tagIndex?: number) => - `r/${reportID}/split/${reportActionID}/edit/${field as string}${typeof tagIndex === 'number' ? `/${tagIndex}` : ''}` as const, - }, TASK_TITLE: { route: 'r/:reportID/title', getRoute: (reportID: string) => `r/${reportID}/title` as const, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 2188941c96d2..7b7b5480267a 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -96,7 +96,6 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator({ [SCREENS.SPLIT_DETAILS.ROOT]: () => require('../../../../pages/iou/SplitBillDetailsPage').default as React.ComponentType, - [SCREENS.SPLIT_DETAILS.EDIT_REQUEST]: () => require('../../../../pages/EditSplitBillPage').default as React.ComponentType, }); const DetailsModalStackNavigator = createModalStackNavigator({ diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 439fba4dbf42..beca960d8e23 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -609,7 +609,6 @@ const config: LinkingOptions['config'] = { [SCREENS.RIGHT_MODAL.SPLIT_DETAILS]: { screens: { [SCREENS.SPLIT_DETAILS.ROOT]: ROUTES.SPLIT_BILL_DETAILS.route, - [SCREENS.SPLIT_DETAILS.EDIT_REQUEST]: ROUTES.EDIT_SPLIT_BILL.route, }, }, [SCREENS.RIGHT_MODAL.TASK_DETAILS]: { From 21e7b1ffc3d2edb8c0b026dec0db622b398093fb Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 24 Apr 2024 21:31:12 +0800 Subject: [PATCH 59/79] rename --- src/pages/PrivateNotes/PrivateNotesEditPage.tsx | 2 +- src/pages/RoomDescriptionPage.tsx | 2 +- src/pages/iou/request/step/IOURequestStepDescription.tsx | 2 +- src/pages/settings/Security/CloseAccountPage.tsx | 2 +- src/pages/tasks/NewTaskDescriptionPage.tsx | 2 +- src/pages/tasks/NewTaskDetailsPage.tsx | 2 +- src/pages/tasks/TaskDescriptionPage.tsx | 2 +- src/pages/workspace/WorkspaceInviteMessagePage.tsx | 2 +- src/pages/workspace/WorkspaceNewRoomPage.tsx | 2 +- src/pages/workspace/WorkspaceProfileDescriptionPage.tsx | 2 +- src/stories/TextInput.stories.tsx | 2 +- src/styles/variables.ts | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx index cac89cb14555..f9560edf7486 100644 --- a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx @@ -152,7 +152,7 @@ function PrivateNotesEditPage({route, personalDetailsList, report}: PrivateNotes maxLength={CONST.MAX_COMMENT_LENGTH} autoCorrect={false} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} defaultValue={privateNote} value={privateNote} onChangeText={(text: string) => { diff --git a/src/pages/RoomDescriptionPage.tsx b/src/pages/RoomDescriptionPage.tsx index ac3d182b9189..3992dff188e2 100644 --- a/src/pages/RoomDescriptionPage.tsx +++ b/src/pages/RoomDescriptionPage.tsx @@ -85,7 +85,7 @@ function RoomDescriptionPage({report, policies}: RoomDescriptionPageProps) { accessibilityLabel={translate('reportDescriptionPage.roomDescription')} role={CONST.ROLE.PRESENTATION} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} maxLength={CONST.REPORT_DESCRIPTION.MAX_LENGTH} ref={(el: BaseTextInputRef | null): void => { if (!el) { diff --git a/src/pages/iou/request/step/IOURequestStepDescription.tsx b/src/pages/iou/request/step/IOURequestStepDescription.tsx index dfc2a8e379ca..afa1e166ddfc 100644 --- a/src/pages/iou/request/step/IOURequestStepDescription.tsx +++ b/src/pages/iou/request/step/IOURequestStepDescription.tsx @@ -177,7 +177,7 @@ function IOURequestStepDescription({ updateMultilineInputRange(inputRef.current); }} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} shouldSubmitForm isMarkdownEnabled /> diff --git a/src/pages/settings/Security/CloseAccountPage.tsx b/src/pages/settings/Security/CloseAccountPage.tsx index 58acfeeb0f5c..0fc0f5b7790a 100644 --- a/src/pages/settings/Security/CloseAccountPage.tsx +++ b/src/pages/settings/Security/CloseAccountPage.tsx @@ -102,7 +102,7 @@ function CloseAccountPage({session}: CloseAccountPageProps) { InputComponent={TextInput} inputID={INPUT_IDS.REASON_FOR_LEAVING} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} label={translate('closeAccountPage.enterMessageHere')} aria-label={translate('closeAccountPage.enterMessageHere')} role={CONST.ROLE.PRESENTATION} diff --git a/src/pages/tasks/NewTaskDescriptionPage.tsx b/src/pages/tasks/NewTaskDescriptionPage.tsx index 34d842c39317..93ad5e63f3d7 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.tsx +++ b/src/pages/tasks/NewTaskDescriptionPage.tsx @@ -88,7 +88,7 @@ function NewTaskDescriptionPage({task}: NewTaskDescriptionPageProps) { updateMultilineInputRange(el); }} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} shouldSubmitForm isMarkdownEnabled /> diff --git a/src/pages/tasks/NewTaskDetailsPage.tsx b/src/pages/tasks/NewTaskDetailsPage.tsx index b8c16644c19c..52fdbf5523a2 100644 --- a/src/pages/tasks/NewTaskDetailsPage.tsx +++ b/src/pages/tasks/NewTaskDetailsPage.tsx @@ -131,7 +131,7 @@ function NewTaskDetailsPage({task}: NewTaskDetailsPageProps) { label={translate('newTaskPage.descriptionOptional')} accessibilityLabel={translate('newTaskPage.descriptionOptional')} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} shouldSubmitForm defaultValue={parser.htmlToMarkdown(parser.replace(taskDescription))} value={taskDescription} diff --git a/src/pages/tasks/TaskDescriptionPage.tsx b/src/pages/tasks/TaskDescriptionPage.tsx index fb3425cb2adb..58fddda73bd2 100644 --- a/src/pages/tasks/TaskDescriptionPage.tsx +++ b/src/pages/tasks/TaskDescriptionPage.tsx @@ -119,7 +119,7 @@ function TaskDescriptionPage({report, currentUserPersonalDetails}: TaskDescripti updateMultilineInputRange(inputRef.current); }} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} shouldSubmitForm isMarkdownEnabled /> diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/WorkspaceInviteMessagePage.tsx index 7bc601252c79..ff606e26e707 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/WorkspaceInviteMessagePage.tsx @@ -199,7 +199,7 @@ function WorkspaceInviteMessagePage({ autoCompleteType="off" autoCorrect={false} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} defaultValue={getDefaultWelcomeNote()} value={welcomeNote} onChangeText={(text: string) => { diff --git a/src/pages/workspace/WorkspaceNewRoomPage.tsx b/src/pages/workspace/WorkspaceNewRoomPage.tsx index 2d7fd946dc22..5716812ced16 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.tsx +++ b/src/pages/workspace/WorkspaceNewRoomPage.tsx @@ -291,7 +291,7 @@ function WorkspaceNewRoomPage({policies, reports, formState, session, activePoli accessibilityLabel={translate('reportDescriptionPage.roomDescriptionOptional')} role={CONST.ROLE.PRESENTATION} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} maxLength={CONST.REPORT_DESCRIPTION.MAX_LENGTH} autoCapitalize="none" shouldInterceptSwipe diff --git a/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx b/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx index bcc2b0c210c7..7787be42de71 100644 --- a/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx +++ b/src/pages/workspace/WorkspaceProfileDescriptionPage.tsx @@ -100,7 +100,7 @@ function WorkspaceProfileDescriptionPage({policy}: Props) { autoFocus onChangeText={setDescription} autoGrowHeight - maxAutoGrowHeight={variables.maxAutoGrowHeight} + maxAutoGrowHeight={variables.textInputAutoGrowMaxHeight} isMarkdownEnabled ref={(el: BaseTextInputRef | null): void => { updateMultilineInputRange(el); diff --git a/src/stories/TextInput.stories.tsx b/src/stories/TextInput.stories.tsx index 98017c0b5db9..fc24c4df3d07 100644 --- a/src/stories/TextInput.stories.tsx +++ b/src/stories/TextInput.stories.tsx @@ -143,7 +143,7 @@ AutoGrowHeightInput.args = { name: 'AutoGrowHeight', placeholder: 'My placeholder text', autoGrowHeight: true, - maxAutoGrowHeight: variables.maxAutoGrowHeight, + maxAutoGrowHeight: variables.textInputAutoGrowMaxHeight, }; export default story; diff --git a/src/styles/variables.ts b/src/styles/variables.ts index 00dcec7cbfdb..a431741d1394 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -229,5 +229,5 @@ export default { mushroomTopHatWidth: 138, mushroomTopHatHeight: 128, bankButtonMargin: 23, - maxAutoGrowHeight: 115, + textInputAutoGrowMaxHeight: 115, } as const; From 7177a0a560b5d0644660b5accdadd0caf60ab391 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 10:32:44 -0300 Subject: [PATCH 60/79] remove MoneyRequestWaypointPage and related route and navigation --- .../ModalStackNavigators/index.tsx | 1 - src/libs/Navigation/types.ts | 6 ---- src/pages/iou/MoneyRequestWaypointPage.tsx | 36 ------------------- 3 files changed, 43 deletions(-) delete mode 100644 src/pages/iou/MoneyRequestWaypointPage.tsx diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 7b7b5480267a..7c908ba7cfec 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -90,7 +90,6 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator require('../../../../pages/AddPersonalBankAccountPage').default as React.ComponentType, [SCREENS.IOU_SEND.ADD_DEBIT_CARD]: () => require('../../../../pages/settings/Wallet/AddDebitCardPage').default as React.ComponentType, [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: () => require('../../../../pages/EnablePayments/EnablePaymentsPage').default as React.ComponentType, - [SCREENS.MONEY_REQUEST.WAYPOINT]: () => require('../../../../pages/iou/MoneyRequestWaypointPage').default as React.ComponentType, [SCREENS.MONEY_REQUEST.STATE_SELECTOR]: () => require('../../../../pages/settings/Profile/PersonalDetails/StateSelectionPage').default as React.ComponentType, }); diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 87fad1064e75..2f17645a3451 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -465,12 +465,6 @@ type MoneyRequestNavigatorParamList = { [SCREENS.IOU_SEND.ENABLE_PAYMENTS]: undefined; [SCREENS.IOU_SEND.ADD_BANK_ACCOUNT]: undefined; [SCREENS.IOU_SEND.ADD_DEBIT_CARD]: undefined; - [SCREENS.MONEY_REQUEST.WAYPOINT]: { - iouType: string; - transactionID: string; - waypointIndex: string; - threadReportID: number; - }; [SCREENS.MONEY_REQUEST.STEP_DISTANCE]: { action: IOUAction; iouType: IOUType; diff --git a/src/pages/iou/MoneyRequestWaypointPage.tsx b/src/pages/iou/MoneyRequestWaypointPage.tsx deleted file mode 100644 index 35778f37a9ef..000000000000 --- a/src/pages/iou/MoneyRequestWaypointPage.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; -import {withOnyx} from 'react-native-onyx'; -import type {MoneyRequestNavigatorParamList} from '@libs/Navigation/types'; -import ONYXKEYS from '@src/ONYXKEYS'; -import type SCREENS from '@src/SCREENS'; -import IOURequestStepWaypoint from './request/step/IOURequestStepWaypoint'; - -type MoneyRequestWaypointPageOnyxProps = { - transactionID: string | undefined; -}; -type MoneyRequestWaypointPageProps = StackScreenProps & MoneyRequestWaypointPageOnyxProps; - -// This component is responsible for grabbing the transactionID from the IOU key -// You can't use Onyx props in the withOnyx mapping, so we need to set up and access the transactionID here, and then pass it down so that WaypointEditor can subscribe to the transaction. -function MoneyRequestWaypointPage({transactionID = '', route}: MoneyRequestWaypointPageProps) { - return ( - - ); -} - -MoneyRequestWaypointPage.displayName = 'MoneyRequestWaypointPage'; - -export default withOnyx({ - transactionID: {key: ONYXKEYS.IOU, selector: (iou) => iou?.transactionID}, -})(MoneyRequestWaypointPage); From d8848d6adbd5b2479b416dd0138cca4d31fffb0c Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 10:35:10 -0300 Subject: [PATCH 61/79] move src/pages/iou/steps/MoneyRequestAmountForm.tsx to src/pages/iou/ --- src/pages/iou/{steps => }/MoneyRequestAmountForm.tsx | 0 src/pages/iou/request/step/IOURequestStepAmount.tsx | 2 +- src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/pages/iou/{steps => }/MoneyRequestAmountForm.tsx (100%) diff --git a/src/pages/iou/steps/MoneyRequestAmountForm.tsx b/src/pages/iou/MoneyRequestAmountForm.tsx similarity index 100% rename from src/pages/iou/steps/MoneyRequestAmountForm.tsx rename to src/pages/iou/MoneyRequestAmountForm.tsx diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 79b7b13e4fde..64112afecd3d 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -13,7 +13,7 @@ import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import {getRequestType} from '@libs/TransactionUtils'; -import MoneyRequestAmountForm from '@pages/iou/steps/MoneyRequestAmountForm'; +import MoneyRequestAmountForm from '@pages/iou/MoneyRequestAmountForm'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; diff --git a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx index dfb5ec1ad81a..22a00591b4fc 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx +++ b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx @@ -8,8 +8,8 @@ import * as CurrencyUtils from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; -import type {CurrentMoney} from '@pages/iou/steps/MoneyRequestAmountForm'; -import MoneyRequestAmountForm from '@pages/iou/steps/MoneyRequestAmountForm'; +import type {CurrentMoney} from '@pages/iou/MoneyRequestAmountForm'; +import MoneyRequestAmountForm from '@pages/iou/MoneyRequestAmountForm'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; From df8d7e32f6c749cdf8a973cc1350c8fdcec7b623 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 19:25:08 +0530 Subject: [PATCH 62/79] Revert "Merge pull request #40807 from Expensify/dsilva_changingPropertyBeingUsedByFullstory" This reverts commit 51372ab1171059ff514ffed1dc1511452aee6a57, reversing changes made to e58ec4940cbed9352266760bebee0a03257c4717. --- src/ONYXKEYS.ts | 4 -- src/libs/actions/Session/index.ts | 2 +- src/libs/fullstory/index.native.ts | 33 +++++++++------- src/libs/fullstory/index.ts | 61 ++++++++++++++---------------- src/libs/fullstory/types.ts | 7 +++- src/types/onyx/UserMetadata.ts | 8 ---- src/types/onyx/index.ts | 2 - 7 files changed, 55 insertions(+), 62 deletions(-) delete mode 100644 src/types/onyx/UserMetadata.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index c17c911d18b3..45c2d152542d 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -188,9 +188,6 @@ const ONYXKEYS = { /** User's Expensify Wallet */ USER_WALLET: 'userWallet', - /** User's metadata that will be used to segmentation */ - USER_METADATA: 'userMetadata', - /** Object containing Onfido SDK Token + applicantID */ WALLET_ONFIDO: 'walletOnfido', @@ -600,7 +597,6 @@ type OnyxValuesMapping = { [ONYXKEYS.USER_LOCATION]: OnyxTypes.UserLocation; [ONYXKEYS.LOGIN_LIST]: OnyxTypes.LoginList; [ONYXKEYS.SESSION]: OnyxTypes.Session; - [ONYXKEYS.USER_METADATA]: OnyxTypes.UserMetadata; [ONYXKEYS.STASHED_SESSION]: OnyxTypes.Session; [ONYXKEYS.BETAS]: OnyxTypes.Beta[]; [ONYXKEYS.NVP_PRIORITY_MODE]: ValueOf; diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index aa83d14a1675..cef66487a438 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -66,7 +66,7 @@ Onyx.connect({ }); Onyx.connect({ - key: ONYXKEYS.USER_METADATA, + key: ONYXKEYS.SESSION, callback: Fullstory.consentAndIdentify, }); diff --git a/src/libs/fullstory/index.native.ts b/src/libs/fullstory/index.native.ts index 67d7c7f2fe90..548598bf60bc 100644 --- a/src/libs/fullstory/index.native.ts +++ b/src/libs/fullstory/index.native.ts @@ -1,6 +1,7 @@ import FullStory, {FSPage} from '@fullstory/react-native'; import type {OnyxEntry} from 'react-native-onyx'; -import type {UserMetadata} from '@src/types/onyx'; +import type Session from '@src/types/onyx/Session'; +import type {UserSession} from './types'; /** * Fullstory React-Native lib adapter @@ -18,31 +19,37 @@ const FS = { consent: (c: boolean) => FullStory.consent(c), /** - * Initializes the FullStory metadata with the provided metadata information. + * Initializes the FullStory session with the provided session information. */ - consentAndIdentify: (value: OnyxEntry) => { + consentAndIdentify: (value: OnyxEntry) => { try { - // We only use FullStory in production environment + const session: UserSession = { + email: value?.email, + accountID: value?.accountID, + }; + // set consent FullStory.consent(true); - FS.fsIdentify(value); + FS.fsIdentify(session); } catch (e) { // error handler } }, /** - * Sets the FullStory user identity based on the provided metadata information. - * If the metadata is null or the email is 'undefined', the user identity is anonymized. - * If the metadata contains an accountID, the user identity is defined with it. + * Sets the FullStory user identity based on the provided session information. + * If the session is null or the email is 'undefined', the user identity is anonymized. + * If the session contains an email, the user identity is defined with the email and account ID. */ - fsIdentify: (metadata: UserMetadata | null) => { - if (!metadata?.accountID) { - // anonymize FullStory user identity metadata + fsIdentify: (session: UserSession) => { + if (!session || session.email === 'undefined') { + // anonymize FullStory user identity session FullStory.anonymize(); } else { // define FullStory user identity - FullStory.identify(String(metadata.accountID), { - properties: metadata, + FullStory.identify(String(session.accountID), { + properties: { + accountID: session.accountID, + }, }); } }, diff --git a/src/libs/fullstory/index.ts b/src/libs/fullstory/index.ts index 5b60f20f9ddf..0cb849983c80 100644 --- a/src/libs/fullstory/index.ts +++ b/src/libs/fullstory/index.ts @@ -1,9 +1,7 @@ import {FullStory, init, isInitialized} from '@fullstory/browser'; import type {OnyxEntry} from 'react-native-onyx'; -import CONST from '@src/CONST'; -import * as Environment from '@src/libs/Environment/Environment'; -import type {UserMetadata} from '@src/types/onyx'; -import type NavigationProperties from './types'; +import type Session from '@src/types/onyx/Session'; +import type {NavigationProperties, UserSession} from './types'; // Placeholder Browser API does not support Manual Page definition class FSPage { @@ -29,17 +27,12 @@ const FS = { */ onReady: () => new Promise((resolve) => { - Environment.getEnvironment().then((envName: string) => { - if (CONST.ENVIRONMENT.PRODUCTION !== envName) { - return; - } - // Initialised via HEAD snippet - if (!isInitialized()) { - init({orgId: ''}, resolve); - } else { - FullStory('observe', {type: 'start', callback: resolve}); - } - }); + // Initialised via HEAD snippet + if (isInitialized()) { + init({orgId: ''}, resolve); + } else { + FullStory('observe', {type: 'start', callback: resolve}); + } }), /** @@ -53,18 +46,18 @@ const FS = { consent: (c: boolean) => FullStory('setIdentity', {consent: c}), /** - * Initializes the FullStory metadata with the provided metadata information. + * Initializes the FullStory session with the provided session information. */ - consentAndIdentify: (value: OnyxEntry) => { + consentAndIdentify: (value: OnyxEntry) => { try { - Environment.getEnvironment().then((envName: string) => { - if (CONST.ENVIRONMENT.PRODUCTION !== envName) { - return; - } - FS.onReady().then(() => { - FS.consent(true); - FS.fsIdentify(value); - }); + FS.onReady().then(() => { + const session: UserSession = { + email: value?.email, + accountID: value?.accountID, + }; + // set consent + FS.consent(true); + FS.fsIdentify(session); }); } catch (e) { // error handler @@ -72,19 +65,21 @@ const FS = { }, /** - * Sets the FullStory user identity based on the provided metadata information. - * If the metadata does not contain an email, the user identity is anonymized. - * If the metadata contains an accountID, the user identity is defined with it. + * Sets the FullStory user identity based on the provided session information. + * If the session does not contain an email, the user identity is anonymized. + * If the session contains an email, the user identity is defined with the email and account ID. */ - fsIdentify: (metadata: UserMetadata | null) => { - if (!metadata?.accountID) { - // anonymize FullStory user identity metadata + fsIdentify: (session: UserSession) => { + if (typeof session.email === 'undefined') { + // anonymize FullStory user identity session FS.anonymize(); } else { // define FullStory user identity FullStory('setIdentity', { - uid: String(metadata.accountID), - properties: metadata, + uid: String(session.accountID), + properties: { + accountID: session.accountID, + }, }); } }, diff --git a/src/libs/fullstory/types.ts b/src/libs/fullstory/types.ts index 24878fd0fbd3..386e35536d97 100644 --- a/src/libs/fullstory/types.ts +++ b/src/libs/fullstory/types.ts @@ -1,5 +1,10 @@ +type UserSession = { + email: string | undefined; + accountID: number | undefined; +}; + type NavigationProperties = { path: string; }; -export default NavigationProperties; +export type {UserSession, NavigationProperties}; diff --git a/src/types/onyx/UserMetadata.ts b/src/types/onyx/UserMetadata.ts deleted file mode 100644 index fc6490264087..000000000000 --- a/src/types/onyx/UserMetadata.ts +++ /dev/null @@ -1,8 +0,0 @@ -type UserMetadata = { - planType?: string; - role?: string; - freeTrial?: boolean; - accountID?: number; -}; - -export default UserMetadata; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 84a8d5c85c40..ea0870a7b8c6 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -72,7 +72,6 @@ import type {TransactionViolation, ViolationName} from './TransactionViolation'; import type TransactionViolations from './TransactionViolation'; import type User from './User'; import type UserLocation from './UserLocation'; -import type UserMetadata from './UserMetadata'; import type UserWallet from './UserWallet'; import type WalletAdditionalDetails from './WalletAdditionalDetails'; import type {WalletAdditionalQuestionDetails} from './WalletAdditionalDetails'; @@ -156,7 +155,6 @@ export type { TransactionViolations, User, UserLocation, - UserMetadata, UserWallet, ViolationName, WalletAdditionalDetails, From 41898c3d5b8eead48ede966ec251b9067a82e170 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 19:25:50 +0530 Subject: [PATCH 63/79] Revert "Merge pull request #40817 from Expensify/dsilva_changingGTMToThirdPartyScripts" This reverts commit 7ea2b6c4d794208bfcd23f825e4967ce9487e9e1, reversing changes made to 03588419f4ddd32b22b70a5e17ac845586a66a48. --- .github/workflows/typecheck.yml | 2 +- config/webpack/webpack.common.ts | 2 +- web/gtm.js | 11 +++ web/index.html | 6 +- web/thirdPartyScripts.js | 155 ------------------------------- 5 files changed, 16 insertions(+), 160 deletions(-) create mode 100644 web/gtm.js delete mode 100644 web/thirdPartyScripts.js diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 88d4d24a5723..f20939f9df0a 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -30,7 +30,7 @@ jobs: # - git diff is used to see the files that were added on this branch # - gh pr view is used to list files touched by this PR. Git diff may give false positives if the branch isn't up-to-date with main # - wc counts the words in the result of the intersection - count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) + count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'web/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) if [ "$count_new_js" -gt "0" ]; then echo "ERROR: Found new JavaScript files in the project; use TypeScript instead." exit 1 diff --git a/config/webpack/webpack.common.ts b/config/webpack/webpack.common.ts index 9d397b9557a3..7cafafca9973 100644 --- a/config/webpack/webpack.common.ts +++ b/config/webpack/webpack.common.ts @@ -98,7 +98,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment): {from: 'web/apple-touch-icon.png'}, {from: 'assets/images/expensify-app-icon.svg'}, {from: 'web/manifest.json'}, - {from: 'web/thirdPartyScripts.js'}, + {from: 'web/gtm.js'}, {from: 'assets/css', to: 'css'}, {from: 'assets/fonts/web', to: 'fonts'}, {from: 'assets/sounds', to: 'sounds'}, diff --git a/web/gtm.js b/web/gtm.js new file mode 100644 index 000000000000..ee96d01b9a67 --- /dev/null +++ b/web/gtm.js @@ -0,0 +1,11 @@ +/* eslint-disable no-param-reassign, prefer-template */ +(function (w, d, s, l, i) { + w[l] = w[l] || []; + w[l].push({'gtm.start': new Date().getTime(), event: 'gtm.js'}); + const f = d.getElementsByTagName(s)[0]; + const j = d.createElement(s); + const dl = l !== 'dataLayer' ? '&l=' + l : ''; + j.async = true; + j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; + f.parentNode.insertBefore(j, f); +})(window, document, 'script', 'dataLayer', 'GTM-N4M3FLJZ'); diff --git a/web/index.html b/web/index.html index be6396190d25..115803573bbd 100644 --- a/web/index.html +++ b/web/index.html @@ -122,9 +122,9 @@ <% if (htmlWebpackPlugin.options.isProduction) { %> - - - + + + <% } %> <% } %> diff --git a/web/thirdPartyScripts.js b/web/thirdPartyScripts.js deleted file mode 100644 index 15e77dbd490e..000000000000 --- a/web/thirdPartyScripts.js +++ /dev/null @@ -1,155 +0,0 @@ -/* eslint-disable */ -// Google Tag Manager -(function (w, d, s, l, i) { - w[l] = w[l] || []; - w[l].push({'gtm.start': new Date().getTime(), event: 'gtm.js'}); - const f = d.getElementsByTagName(s)[0]; - const j = d.createElement(s); - const dl = l !== 'dataLayer' ? '&l=' + l : ''; - j.async = true; - j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl; - f.parentNode.insertBefore(j, f); -})(window, document, 'script', 'dataLayer', 'GTM-N4M3FLJZ'); - -// FullStory -window['_fs_host'] = 'fullstory.com'; -window['_fs_script'] = 'edge.fullstory.com/s/fs.js'; -window['_fs_org'] = 'o-1WN56P-na1'; -window['_fs_namespace'] = 'FS'; -!(function (m, n, e, t, l, o, g, y) { - var s, - f, - a = (function (h) { - return !(h in m) || (m.console && m.console.log && m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].'), !1); - })(e); - function p(b) { - var h, - d = []; - function j() { - h && - (d.forEach(function (b) { - var d; - try { - d = b[h[0]] && b[h[0]](h[1]); - } catch (h) { - return void (b[3] && b[3](h)); - } - d && d.then ? d.then(b[2], b[3]) : b[2] && b[2](d); - }), - (d.length = 0)); - } - function r(b) { - return function (d) { - h || ((h = [b, d]), j()); - }; - } - return ( - b(r(0), r(1)), - { - then: function (b, h) { - return p(function (r, i) { - d.push([b, h, r, i]), j(); - }); - }, - } - ); - } - a && - ((g = m[e] = - (function () { - var b = function (b, d, j, r) { - function i(i, c) { - h(b, d, j, i, c, r); - } - r = r || 2; - var c, - u = /Async$/; - return u.test(b) ? ((b = b.replace(u, '')), 'function' == typeof Promise ? new Promise(i) : p(i)) : h(b, d, j, c, c, r); - }; - function h(h, d, j, r, i, c) { - return b._api ? b._api(h, d, j, r, i, c) : (b.q && b.q.push([h, d, j, r, i, c]), null); - } - return (b.q = []), b; - })()), - (y = function (b) { - function h(h) { - 'function' == typeof h[4] && h[4](new Error(b)); - } - var d = g.q; - if (d) { - for (var j = 0; j < d.length; j++) h(d[j]); - (d.length = 0), (d.push = h); - } - }), - (function () { - ((o = n.createElement(t)).async = !0), - (o.crossOrigin = 'anonymous'), - (o.src = 'https://' + l), - (o.onerror = function () { - y('Error loading ' + l); - }); - var b = n.getElementsByTagName(t)[0]; - b && b.parentNode ? b.parentNode.insertBefore(o, b) : n.head.appendChild(o); - })(), - (function () { - function b() {} - function h(b, h, d) { - g(b, h, d, 1); - } - function d(b, d, j) { - h('setProperties', {type: b, properties: d}, j); - } - function j(b, h) { - d('user', b, h); - } - function r(b, h, d) { - j( - { - uid: b, - }, - d, - ), - h && j(h, d); - } - (g.identify = r), - (g.setUserVars = j), - (g.identifyAccount = b), - (g.clearUserCookie = b), - (g.setVars = d), - (g.event = function (b, d, j) { - h( - 'trackEvent', - { - name: b, - properties: d, - }, - j, - ); - }), - (g.anonymize = function () { - r(!1); - }), - (g.shutdown = function () { - h('shutdown'); - }), - (g.restart = function () { - h('restart'); - }), - (g.log = function (b, d) { - h('log', {level: b, msg: d}); - }), - (g.consent = function (b) { - h('setIdentity', {consent: !arguments.length || b}); - }); - })(), - (s = 'fetch'), - (f = 'XMLHttpRequest'), - (g._w = {}), - (g._w[f] = m[f]), - (g._w[s] = m[s]), - m[s] && - (m[s] = function () { - return g._w[s].apply(this, arguments); - }), - (g._v = '2.0.0')); -})(window, document, window._fs_namespace, 'script', window._fs_script); From bcc705ed5f5c4bfcbd2503d3a54383e6291d4ca3 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 19:26:46 +0530 Subject: [PATCH 64/79] Revert "Merge pull request #40294 from LCOleksii/fullstory-integration" This reverts commit 1928c3ae8a36c12ff2b79104fe14a43446cfd809, reversing changes made to 9b839f4f18d724dba1ed17ed5967f7e033781428. --- android/app/build.gradle | 10 +-- android/build.gradle | 6 +- babel.config.js | 17 ----- ios/NewExpensify.xcodeproj/project.pbxproj | 4 - ios/Podfile.lock | 28 ------- jest/setup.ts | 2 - jest/setupMockFullstoryLib.ts | 24 ------ package-lock.json | 48 ------------ package.json | 2 - src/libs/Navigation/NavigationRoot.tsx | 3 - src/libs/actions/Session/index.ts | 6 -- src/libs/fullstory/index.native.ts | 59 -------------- src/libs/fullstory/index.ts | 89 ---------------------- src/libs/fullstory/types.ts | 10 --- 14 files changed, 2 insertions(+), 306 deletions(-) delete mode 100644 jest/setupMockFullstoryLib.ts delete mode 100644 src/libs/fullstory/index.native.ts delete mode 100644 src/libs/fullstory/index.ts delete mode 100644 src/libs/fullstory/types.ts diff --git a/android/app/build.gradle b/android/app/build.gradle index bb508ea9f4de..93b538b3d943 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -2,20 +2,12 @@ apply plugin: "com.android.application" apply plugin: "org.jetbrains.kotlin.android" apply plugin: "com.facebook.react" apply plugin: "com.google.firebase.firebase-perf" -apply plugin: "fullstory" apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" /** * This is the configuration block to customize your React Native Android app. * By default you don't need to apply any configuration, just uncomment the lines you need. */ - -/* Fullstory settings */ -fullstory { - org 'o-1WN56P-na1' - enabledVariants 'all' -} - react { /* Folders */ // The root of your project, i.e. where "package.json" lives. Default is '..' @@ -170,7 +162,7 @@ android { signingConfig null // buildTypes take precedence over productFlavors when it comes to the signing configuration, // thus we need to manually set the signing config, so that the e2e uses the debug config again. - // In other words, the signingConfig setting above will be ignored when we build the flavor in release mode. + // In other words, the signingConfig setting above will be ignored when we build the flavor in release mode. productFlavors.all { flavor -> // All release builds should be signed with the release config ... flavor.signingConfig signingConfigs.release diff --git a/android/build.gradle b/android/build.gradle index 7ecd482b38f0..10600480d8bb 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -20,7 +20,6 @@ buildscript { repositories { google() mavenCentral() - maven {url "https://maven.fullstory.com"} } dependencies { classpath("com.android.tools.build:gradle") @@ -28,9 +27,6 @@ buildscript { classpath("com.google.gms:google-services:4.3.4") classpath("com.google.firebase:firebase-crashlytics-gradle:2.7.1") classpath("com.google.firebase:perf-plugin:1.4.1") - // Fullstory integration - classpath ("com.fullstory:gradle-plugin-local:1.45.1") - // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") @@ -74,7 +70,7 @@ allprojects { // 'mapbox' is the fixed username for Mapbox's Maven repository. username = 'mapbox' - // The value for password is read from the 'MAPBOX_DOWNLOADS_TOKEN' gradle property. + // The value for password is read from the 'MAPBOX_DOWNLOADS_TOKEN' gradle property. // Run "npm run setup-mapbox-sdk" to set this property in «USER_HOME»/.gradle/gradle.properties // Example gradle.properties entry: diff --git a/babel.config.js b/babel.config.js index 0660cdb452fb..9f8b7a711d78 100644 --- a/babel.config.js +++ b/babel.config.js @@ -14,23 +14,6 @@ const defaultPlugins = [ // source code transformation as we do not use class property assignment. 'transform-class-properties', - /* Fullstory */ - [ - '@fullstory/react-native', - { - version: '1.4.0', - org: 'o-1WN56P-na1', - enabledVariants: 'all', - }, - ], - [ - '@fullstory/babel-plugin-annotate-react', - { - native: true, - setFSTagName: true, - }, - ], - // Keep it last 'react-native-reanimated/plugin', ]; diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index e7ce320f65d6..7f50db5da85a 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -681,7 +681,6 @@ "${PODS_ROOT}/Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests-frameworks.sh", "${BUILT_PRODUCTS_DIR}/MapboxMaps/MapboxMaps.framework", "${BUILT_PRODUCTS_DIR}/Turf/Turf.framework", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/FullStory/FullStory.framework/FullStory", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCommon/MapboxCommon.framework/MapboxCommon", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCoreMaps/MapboxCoreMaps.framework/MapboxCoreMaps", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxMobileEvents/MapboxMobileEvents.framework/MapboxMobileEvents", @@ -693,7 +692,6 @@ outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Turf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FullStory.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCoreMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMobileEvents.framework", @@ -737,7 +735,6 @@ "${PODS_ROOT}/Target Support Files/Pods-NewExpensify/Pods-NewExpensify-frameworks.sh", "${BUILT_PRODUCTS_DIR}/MapboxMaps/MapboxMaps.framework", "${BUILT_PRODUCTS_DIR}/Turf/Turf.framework", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/FullStory/FullStory.framework/FullStory", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCommon/MapboxCommon.framework/MapboxCommon", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxCoreMaps/MapboxCoreMaps.framework/MapboxCoreMaps", "${PODS_XCFRAMEWORKS_BUILD_DIR}/MapboxMobileEvents/MapboxMobileEvents.framework/MapboxMobileEvents", @@ -749,7 +746,6 @@ outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Turf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FullStory.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCommon.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxCoreMaps.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MapboxMobileEvents.framework", diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6ef495a65bd3..ed387a8d522f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -138,27 +138,6 @@ PODS: - GoogleUtilities/Environment (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - fmt (6.2.1) - - FullStory (1.43.1) - - fullstory_react-native (1.4.2): - - FullStory (~> 1.14) - - glog - - hermes-engine - - RCT-Folly (= 2022.05.16.00) - - RCTRequired - - RCTTypeSafety - - React-Codegen - - React-Core - - React-debug - - React-Fabric - - React-graphics - - React-ImageManager - - React-NativeModulesApple - - React-RCTFabric - - React-rendererdebug - - React-utils - - ReactCommon/turbomodule/bridging - - ReactCommon/turbomodule/core - - Yoga - glog (0.3.5) - GoogleAppMeasurement (8.8.0): - GoogleAppMeasurement/AdIdSupport (= 8.8.0) @@ -2197,7 +2176,6 @@ SPEC REPOS: - FirebasePerformance - FirebaseRemoteConfig - fmt - - FullStory - GoogleAppMeasurement - GoogleDataTransport - GoogleSignIn @@ -2246,10 +2224,6 @@ EXTERNAL SOURCES: :path: "../node_modules/expo-modules-core" FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" - fullstory_react-native: - :path: "../node_modules/@fullstory/react-native" - FBReactNativeSpec: - :path: "../node_modules/react-native/React/FBReactNativeSpec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: @@ -2465,8 +2439,6 @@ SPEC CHECKSUMS: FirebasePerformance: 0c01a7a496657d7cea86d40c0b1725259d164c6c FirebaseRemoteConfig: 2d6e2cfdb49af79535c8af8a80a4a5009038ec2b fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - FullStory: e035758fef275fb59c6471f61b179652aeca452b - fullstory_react-native: a56e2bb52753b69f01aab3ae876087db08488034 glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 GoogleAppMeasurement: 5ba1164e3c844ba84272555e916d0a6d3d977e91 GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a diff --git a/jest/setup.ts b/jest/setup.ts index 174e59a7e493..488e3e36a1d3 100644 --- a/jest/setup.ts +++ b/jest/setup.ts @@ -2,11 +2,9 @@ import '@shopify/flash-list/jestSetup'; import 'react-native-gesture-handler/jestSetup'; import mockStorage from 'react-native-onyx/dist/storage/__mocks__'; import 'setimmediate'; -import mockFSLibrary from './setupMockFullstoryLib'; import setupMockImages from './setupMockImages'; setupMockImages(); -mockFSLibrary(); // This mock is required as per setup instructions for react-navigation testing // https://reactnavigation.org/docs/testing/#mocking-native-modules diff --git a/jest/setupMockFullstoryLib.ts b/jest/setupMockFullstoryLib.ts deleted file mode 100644 index 9edfccab9441..000000000000 --- a/jest/setupMockFullstoryLib.ts +++ /dev/null @@ -1,24 +0,0 @@ -type FSPageInterface = { - start: jest.Mock; -}; - -export default function mockFSLibrary() { - jest.mock('@fullstory/react-native', () => { - class Fullstory { - consent = jest.fn(); - - anonymize = jest.fn(); - - identify = jest.fn(); - } - - return { - FSPage(): FSPageInterface { - return { - start: jest.fn(), - }; - }, - default: Fullstory, - }; - }); -} diff --git a/package-lock.json b/package-lock.json index 054b669e1926..aac685eddef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,6 @@ "@formatjs/intl-locale": "^3.3.0", "@formatjs/intl-numberformat": "^8.5.0", "@formatjs/intl-pluralrules": "^5.2.2", - "@fullstory/browser": "^2.0.3", - "@fullstory/react-native": "^1.4.0", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", "@kie/act-js": "^2.6.0", @@ -5590,52 +5588,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@fullstory/babel-plugin-annotate-react": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@fullstory/babel-plugin-annotate-react/-/babel-plugin-annotate-react-2.3.0.tgz", - "integrity": "sha512-gYLUL6Tu0exbvTIhK9nSCaztmqBlQAm07Fvtl/nKTc+lxwFkcX9vR8RrdTbyjJZKbPaA5EMlExQ6GeLCXkfm5g==" - }, - "node_modules/@fullstory/babel-plugin-react-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@fullstory/babel-plugin-react-native/-/babel-plugin-react-native-1.1.0.tgz", - "integrity": "sha512-BqfSUdyrrYrZM286GzdHd3qCdbitxUAIM0Z+HpoOTGWVTLDpkFNNaRw5juq8YhYbcPm6BAtK0RMGY7CvcMNarA==", - "dependencies": { - "@babel/parser": "^7.0.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@fullstory/browser": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@fullstory/browser/-/browser-2.0.3.tgz", - "integrity": "sha512-usjH8FB1O2LiSWoblsuKhFhlYDGpIPuyQVOx4JXtxm9QmQARdKZdNq1vPijxuDvOGjhwtVZa4JmhvByRRuDPnQ==", - "dependencies": { - "@fullstory/snippet": "2.0.3" - } - }, - "node_modules/@fullstory/react-native": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@fullstory/react-native/-/react-native-1.4.2.tgz", - "integrity": "sha512-Ig85ghn5UN+Tc1JWL/y4hY9vleeaVHL3f6qH9W4odDNP4XAv29+G82nIYQhBOQGoVnIQ4oQFQftir/dqAbidSw==", - "dependencies": { - "@fullstory/babel-plugin-annotate-react": "^2.2.0", - "@fullstory/babel-plugin-react-native": "^1.1.0" - }, - "peerDependencies": { - "expo": ">=47.0.0", - "react": "*", - "react-native": ">=0.61.0" - }, - "peerDependenciesMeta": { - "expo": { - "optional": true - } - } - }, - "node_modules/@fullstory/snippet": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@fullstory/snippet/-/snippet-2.0.3.tgz", - "integrity": "sha512-EaCuTQSLv5FvnjHLbTxErn3sS1+nLqf1p6sA/c4PV49stBtkUakA0eLhJJdaw0WLdXyEzZXf86lRNsjEzrgGPw==" - }, "node_modules/@gar/promisify": { "version": "1.1.3", "license": "MIT" diff --git a/package.json b/package.json index 9a9ed16f6234..26f0eaf39464 100644 --- a/package.json +++ b/package.json @@ -72,8 +72,6 @@ "@formatjs/intl-locale": "^3.3.0", "@formatjs/intl-numberformat": "^8.5.0", "@formatjs/intl-pluralrules": "^5.2.2", - "@fullstory/browser": "^2.0.3", - "@fullstory/react-native": "^1.4.0", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", "@kie/act-js": "^2.6.0", diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 5760959c1b02..506eae2bdfd2 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -6,7 +6,6 @@ import useActiveWorkspace from '@hooks/useActiveWorkspace'; import useCurrentReportID from '@hooks/useCurrentReportID'; import useTheme from '@hooks/useTheme'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import {FSPage} from '@libs/fullstory'; import Log from '@libs/Log'; import {getPathFromURL} from '@libs/Url'; import {updateLastVisitedPath} from '@userActions/App'; @@ -58,8 +57,6 @@ function parseAndLogRoute(state: NavigationState) { } Navigation.setIsNavigationReady(); - // Fullstory Page navigation tracking - new FSPage(focusedRoute?.name ?? '', {path: currentPath}).start(); } function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: NavigationRootProps) { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index cef66487a438..9fc1485cd6e5 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -23,7 +23,6 @@ import type SignInUserParams from '@libs/API/parameters/SignInUserParams'; import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as Authentication from '@libs/Authentication'; import * as ErrorUtils from '@libs/ErrorUtils'; -import Fullstory from '@libs/fullstory'; import HttpUtils from '@libs/HttpUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -65,11 +64,6 @@ Onyx.connect({ }, }); -Onyx.connect({ - key: ONYXKEYS.SESSION, - callback: Fullstory.consentAndIdentify, -}); - let stashedSession: Session = {}; Onyx.connect({ key: ONYXKEYS.STASHED_SESSION, diff --git a/src/libs/fullstory/index.native.ts b/src/libs/fullstory/index.native.ts deleted file mode 100644 index 548598bf60bc..000000000000 --- a/src/libs/fullstory/index.native.ts +++ /dev/null @@ -1,59 +0,0 @@ -import FullStory, {FSPage} from '@fullstory/react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import type Session from '@src/types/onyx/Session'; -import type {UserSession} from './types'; - -/** - * Fullstory React-Native lib adapter - * Proxy function calls to React-Native lib - * */ -const FS = { - /** - * Sets the identity as anonymous using the FullStory library. - */ - anonymize: () => FullStory.anonymize(), - - /** - * Sets the identity consent status using the FullStory library. - */ - consent: (c: boolean) => FullStory.consent(c), - - /** - * Initializes the FullStory session with the provided session information. - */ - consentAndIdentify: (value: OnyxEntry) => { - try { - const session: UserSession = { - email: value?.email, - accountID: value?.accountID, - }; - // set consent - FullStory.consent(true); - FS.fsIdentify(session); - } catch (e) { - // error handler - } - }, - - /** - * Sets the FullStory user identity based on the provided session information. - * If the session is null or the email is 'undefined', the user identity is anonymized. - * If the session contains an email, the user identity is defined with the email and account ID. - */ - fsIdentify: (session: UserSession) => { - if (!session || session.email === 'undefined') { - // anonymize FullStory user identity session - FullStory.anonymize(); - } else { - // define FullStory user identity - FullStory.identify(String(session.accountID), { - properties: { - accountID: session.accountID, - }, - }); - } - }, -}; - -export default FS; -export {FSPage}; diff --git a/src/libs/fullstory/index.ts b/src/libs/fullstory/index.ts deleted file mode 100644 index 0cb849983c80..000000000000 --- a/src/libs/fullstory/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -import {FullStory, init, isInitialized} from '@fullstory/browser'; -import type {OnyxEntry} from 'react-native-onyx'; -import type Session from '@src/types/onyx/Session'; -import type {NavigationProperties, UserSession} from './types'; - -// Placeholder Browser API does not support Manual Page definition -class FSPage { - private pageName; - - private properties; - - constructor(name: string, properties: NavigationProperties) { - this.pageName = name; - this.properties = properties; - } - - start() {} -} - -/** - * Web does not use Fullstory React-Native lib - * Proxy function calls to Browser Snippet instance - * */ -const FS = { - /** - * Executes a function when the FullStory library is ready, either by initialization or by observing the start event. - */ - onReady: () => - new Promise((resolve) => { - // Initialised via HEAD snippet - if (isInitialized()) { - init({orgId: ''}, resolve); - } else { - FullStory('observe', {type: 'start', callback: resolve}); - } - }), - - /** - * Sets the identity as anonymous using the FullStory library. - */ - anonymize: () => FullStory('setIdentity', {anonymous: true}), - - /** - * Sets the identity consent status using the FullStory library. - */ - consent: (c: boolean) => FullStory('setIdentity', {consent: c}), - - /** - * Initializes the FullStory session with the provided session information. - */ - consentAndIdentify: (value: OnyxEntry) => { - try { - FS.onReady().then(() => { - const session: UserSession = { - email: value?.email, - accountID: value?.accountID, - }; - // set consent - FS.consent(true); - FS.fsIdentify(session); - }); - } catch (e) { - // error handler - } - }, - - /** - * Sets the FullStory user identity based on the provided session information. - * If the session does not contain an email, the user identity is anonymized. - * If the session contains an email, the user identity is defined with the email and account ID. - */ - fsIdentify: (session: UserSession) => { - if (typeof session.email === 'undefined') { - // anonymize FullStory user identity session - FS.anonymize(); - } else { - // define FullStory user identity - FullStory('setIdentity', { - uid: String(session.accountID), - properties: { - accountID: session.accountID, - }, - }); - } - }, -}; - -export default FS; -export {FSPage}; diff --git a/src/libs/fullstory/types.ts b/src/libs/fullstory/types.ts deleted file mode 100644 index 386e35536d97..000000000000 --- a/src/libs/fullstory/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -type UserSession = { - email: string | undefined; - accountID: number | undefined; -}; - -type NavigationProperties = { - path: string; -}; - -export type {UserSession, NavigationProperties}; From bb6719ea34ff85cdbc57925a5bdb0f42f2232781 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 11:07:31 -0300 Subject: [PATCH 65/79] Remove ONYXKEYS.IOU (also need to remove some files that relate to IOU like src/pages/iou/propTypes/index.js) --- src/ONYXKEYS.ts | 4 --- src/libs/actions/IOU.ts | 5 --- src/pages/iou/propTypes/index.js | 54 -------------------------------- 3 files changed, 63 deletions(-) delete mode 100644 src/pages/iou/propTypes/index.js diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 45c2d152542d..5a765c93ca03 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -39,9 +39,6 @@ const ONYXKEYS = { CREDENTIALS: 'credentials', STASHED_CREDENTIALS: 'stashedCredentials', - // Contains loading data for the IOU feature (MoneyRequestModal, IOUDetail, & MoneyRequestPreview Components) - IOU: 'iou', - /** Keeps track if there is modal currently visible or not */ MODAL: 'modal', @@ -577,7 +574,6 @@ type OnyxValuesMapping = { [ONYXKEYS.CURRENT_DATE]: string; [ONYXKEYS.CREDENTIALS]: OnyxTypes.Credentials; [ONYXKEYS.STASHED_CREDENTIALS]: OnyxTypes.Credentials; - [ONYXKEYS.IOU]: OnyxTypes.IOU; [ONYXKEYS.MODAL]: OnyxTypes.Modal; [ONYXKEYS.NETWORK]: OnyxTypes.Network; [ONYXKEYS.NEW_GROUP_CHAT_DRAFT]: OnyxTypes.NewGroupChatDraft; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 1539e88b1328..5208720210e8 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -5825,10 +5825,6 @@ function setMoneyRequestParticipantsFromReport(transactionID: string, report: On return participants; } -function setMoneyRequestId(id: string) { - Onyx.merge(ONYXKEYS.IOU, {id}); -} - function setMoneyRequestTaxRate(transactionID: string, taxRate: TaxRatesOption) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {taxRate}); } @@ -6025,7 +6021,6 @@ export { setMoneyRequestCreated, setMoneyRequestCurrency, setMoneyRequestDescription, - setMoneyRequestId, setMoneyRequestMerchant, setMoneyRequestParticipants, setMoneyRequestParticipantsFromReport, diff --git a/src/pages/iou/propTypes/index.js b/src/pages/iou/propTypes/index.js deleted file mode 100644 index 46abafac23e4..000000000000 --- a/src/pages/iou/propTypes/index.js +++ /dev/null @@ -1,54 +0,0 @@ -import PropTypes from 'prop-types'; -import participantPropTypes from '@components/participantPropTypes'; -import CONST from '@src/CONST'; - -const iouPropTypes = PropTypes.shape({ - /** ID (iouType + reportID) of the expense */ - id: PropTypes.string, - - /** Amount of the expense */ - amount: PropTypes.number, - - /** Currency of the expense */ - currency: PropTypes.string, - - /** Description of the expense */ - comment: PropTypes.string, - - /** The merchant name */ - merchant: PropTypes.string, - - /** The category name */ - category: PropTypes.string, - - /** Whether the expense is billable */ - billable: PropTypes.bool, - - /** The tag */ - tag: PropTypes.string, - - /** Date that the expense was created */ - created: PropTypes.string, - - /** The path to an image of the receipt attached to the expense */ - receiptPath: PropTypes.string, - - /** List of the participants */ - participants: PropTypes.arrayOf(participantPropTypes), -}); - -const iouDefaultProps = { - id: '', - amount: 0, - currency: CONST.CURRENCY.USD, - comment: '', - merchant: '', - category: '', - tag: '', - billable: false, - created: '', - participants: [], - receiptPath: '', -}; - -export {iouPropTypes, iouDefaultProps}; From dca062c662f89889cbef864dfd40e45f8b427347 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Wed, 24 Apr 2024 16:18:33 +0200 Subject: [PATCH 66/79] Add missing icon to SearchFilters --- src/pages/Search/SearchFiltersNarrow.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/Search/SearchFiltersNarrow.tsx b/src/pages/Search/SearchFiltersNarrow.tsx index 6b353750f47d..530b7cd176db 100644 --- a/src/pages/Search/SearchFiltersNarrow.tsx +++ b/src/pages/Search/SearchFiltersNarrow.tsx @@ -33,6 +33,7 @@ function SearchFiltersNarrow({filterItems, activeItemLabel}: SearchFiltersNarrow const popoverMenuItems = filterItems.map((item) => ({ text: item.title, onSelected: singleExecution(() => Navigation.navigate(item.route)), + icon: item.icon, })); return ( From a3f56621d44bb73bd0cc8959a1dac8ffef80f37d Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 11:21:40 -0300 Subject: [PATCH 67/79] revert 'remove ONYXKEYS.IOU' --- src/ONYXKEYS.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 5a765c93ca03..45c2d152542d 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -39,6 +39,9 @@ const ONYXKEYS = { CREDENTIALS: 'credentials', STASHED_CREDENTIALS: 'stashedCredentials', + // Contains loading data for the IOU feature (MoneyRequestModal, IOUDetail, & MoneyRequestPreview Components) + IOU: 'iou', + /** Keeps track if there is modal currently visible or not */ MODAL: 'modal', @@ -574,6 +577,7 @@ type OnyxValuesMapping = { [ONYXKEYS.CURRENT_DATE]: string; [ONYXKEYS.CREDENTIALS]: OnyxTypes.Credentials; [ONYXKEYS.STASHED_CREDENTIALS]: OnyxTypes.Credentials; + [ONYXKEYS.IOU]: OnyxTypes.IOU; [ONYXKEYS.MODAL]: OnyxTypes.Modal; [ONYXKEYS.NETWORK]: OnyxTypes.Network; [ONYXKEYS.NEW_GROUP_CHAT_DRAFT]: OnyxTypes.NewGroupChatDraft; From 33558a04369c2ec9e94c1874b68bd20182be0c1e Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 11:24:21 -0300 Subject: [PATCH 68/79] cleanup missing 'SCREENS.MONEY_REQUEST.RECEIPT' --- src/libs/Navigation/types.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 2f17645a3451..f9541cb674a3 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -472,10 +472,6 @@ type MoneyRequestNavigatorParamList = { reportID: string; backTo: Routes; }; - [SCREENS.MONEY_REQUEST.RECEIPT]: { - iouType: string; - reportID: string; - }; [SCREENS.MONEY_REQUEST.CREATE]: { iouType: IOUType; reportID: string; From b0947ae70823116c5d9091d5ec349dd4752908a8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 24 Apr 2024 08:30:29 -0600 Subject: [PATCH 69/79] update missing translation --- src/pages/ChatFinderPage/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/ChatFinderPage/index.tsx b/src/pages/ChatFinderPage/index.tsx index ccac9bac21ed..a7516163c40b 100644 --- a/src/pages/ChatFinderPage/index.tsx +++ b/src/pages/ChatFinderPage/index.tsx @@ -168,8 +168,7 @@ function ChatFinderPage({betas, isSearchingForReports, navigation}: ChatFinderPa navigation={navigation} > From 83bb869d3353184c2efbc0c794b0dc4424369f18 Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Wed, 24 Apr 2024 16:36:06 +0200 Subject: [PATCH 70/79] fix: copy state in reanimated commit hook --- ...eact-native-reanimated+3.7.2+002+copy-state.patch | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 patches/react-native-reanimated+3.7.2+002+copy-state.patch diff --git a/patches/react-native-reanimated+3.7.2+002+copy-state.patch b/patches/react-native-reanimated+3.7.2+002+copy-state.patch new file mode 100644 index 000000000000..bd5899977ea9 --- /dev/null +++ b/patches/react-native-reanimated+3.7.2+002+copy-state.patch @@ -0,0 +1,12 @@ +diff --git a/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp b/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp +index f913ceb..3f58247 100644 +--- a/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp ++++ b/node_modules/react-native-reanimated/Common/cpp/Fabric/ShadowTreeCloner.cpp +@@ -51,6 +51,7 @@ ShadowNode::Unshared cloneShadowTreeWithNewProps( + newChildNode = parentNode.clone({ + ShadowNodeFragment::propsPlaceholder(), + std::make_shared(children), ++ parentNode.getState() + }); + } + From 7e7b5adffc42147a8dcbdf2474d58f498430ed71 Mon Sep 17 00:00:00 2001 From: Manan Jadhav Date: Wed, 24 Apr 2024 20:12:28 +0530 Subject: [PATCH 71/79] fix: remove web.js for lint errors --- .github/workflows/typecheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index f20939f9df0a..88d4d24a5723 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -30,7 +30,7 @@ jobs: # - git diff is used to see the files that were added on this branch # - gh pr view is used to list files touched by this PR. Git diff may give false positives if the branch isn't up-to-date with main # - wc counts the words in the result of the intersection - count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'web/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) + count_new_js=$(comm -1 -2 <(git diff --name-only --diff-filter=A origin/main HEAD -- 'src/*.js' '__mocks__/*.js' '.storybook/*.js' 'assets/*.js' 'config/*.js' 'desktop/*.js' 'jest/*.js' 'scripts/*.js' 'tests/*.js' 'workflow_tests/*.js' '.github/libs/*.js' '.github/scripts/*.js') <(gh pr view ${{ github.event.pull_request.number }} --json files | jq -r '.files | map(.path) | .[]') | wc -l) if [ "$count_new_js" -gt "0" ]; then echo "ERROR: Found new JavaScript files in the project; use TypeScript instead." exit 1 From 66d906e4cf96cc9b203284ffb0a600df5f4d2db4 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 13:47:59 -0300 Subject: [PATCH 72/79] remove 'resetMoneyRequestInfo' and remaining 'ONYXKEYS.IOU' --- src/ONYXKEYS.ts | 4 ---- src/libs/actions/IOU.ts | 38 +++++++------------------------------- 2 files changed, 7 insertions(+), 35 deletions(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index c17c911d18b3..d64e85aa9ea1 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -39,9 +39,6 @@ const ONYXKEYS = { CREDENTIALS: 'credentials', STASHED_CREDENTIALS: 'stashedCredentials', - // Contains loading data for the IOU feature (MoneyRequestModal, IOUDetail, & MoneyRequestPreview Components) - IOU: 'iou', - /** Keeps track if there is modal currently visible or not */ MODAL: 'modal', @@ -580,7 +577,6 @@ type OnyxValuesMapping = { [ONYXKEYS.CURRENT_DATE]: string; [ONYXKEYS.CREDENTIALS]: OnyxTypes.Credentials; [ONYXKEYS.STASHED_CREDENTIALS]: OnyxTypes.Credentials; - [ONYXKEYS.IOU]: OnyxTypes.IOU; [ONYXKEYS.MODAL]: OnyxTypes.Modal; [ONYXKEYS.NETWORK]: OnyxTypes.Network; [ONYXKEYS.NEW_GROUP_CHAT_DRAFT]: OnyxTypes.NewGroupChatDraft; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index dc12dfe238d3..c63a837cb671 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -411,29 +411,6 @@ function updateDistanceRequestRate(transactionID: string, rateID: string, policy Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {comment: {customUnit: {customUnitRateID: rateID}}}); } -/** Reset expense info from the store with its initial value */ -function resetMoneyRequestInfo(id = '') { - // Disabling this line since currentDate can be an empty string - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const created = currentDate || format(new Date(), CONST.DATE.FNS_FORMAT_STRING); - Onyx.merge(ONYXKEYS.IOU, { - id, - amount: 0, - currency: currentUserPersonalDetails.localCurrencyCode ?? CONST.CURRENCY.USD, - comment: '', - participants: [], - merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, - category: '', - tag: '', - created, - receiptPath: '', - receiptFilename: '', - transactionID: '', - billable: null, - isSplitRequest: false, - }); -} - /** Helper function to get the receipt error for expenses, or the generic error if there's no receipt */ function getReceiptError(receipt?: Receipt, filename?: string, isScanRequest = true, errorKey?: number): Errors | ErrorFields { return isEmptyObject(receipt) || !isScanRequest @@ -2899,7 +2876,7 @@ function requestMoney( // eslint-disable-next-line rulesdir/no-multiple-api-calls API.write(WRITE_COMMANDS.REQUEST_MONEY, parameters, onyxData); - resetMoneyRequestInfo(); + } } @@ -3068,7 +3045,7 @@ function trackExpense( }; API.write(WRITE_COMMANDS.TRACK_EXPENSE, parameters, onyxData); - resetMoneyRequestInfo(); + } } if (action === CONST.IOU.ACTION.SHARE) { @@ -3571,7 +3548,7 @@ function splitBill({ API.write(WRITE_COMMANDS.SPLIT_BILL, parameters, onyxData); - resetMoneyRequestInfo(); + Navigation.dismissModal(existingSplitChatReportID); Report.notifyNewAction(splitData.chatReportID, currentUserAccountID); } @@ -3630,7 +3607,7 @@ function splitBillAndOpenReport({ API.write(WRITE_COMMANDS.SPLIT_BILL_AND_OPEN_REPORT, parameters, onyxData); - resetMoneyRequestInfo(); + Navigation.dismissModal(splitData.chatReportID); Report.notifyNewAction(splitData.chatReportID, currentUserAccountID); } @@ -3930,7 +3907,7 @@ function startSplitBill({ API.write(WRITE_COMMANDS.START_SPLIT_BILL, parameters, {optimisticData, successData, failureData}); - resetMoneyRequestInfo(); + Navigation.dismissModalWithReport(splitChatReport); Report.notifyNewAction(splitChatReport.chatReportID ?? '', currentUserAccountID); } @@ -5274,7 +5251,7 @@ function sendMoneyElsewhere(report: OnyxEntry, amount: number, API.write(WRITE_COMMANDS.SEND_MONEY_ELSEWHERE, params, {optimisticData, successData, failureData}); - resetMoneyRequestInfo(); + Navigation.dismissModal(params.chatReportID); Report.notifyNewAction(params.chatReportID, managerID); } @@ -5288,7 +5265,7 @@ function sendMoneyWithWallet(report: OnyxEntry, amount: number API.write(WRITE_COMMANDS.SEND_MONEY_WITH_WALLET, params, {optimisticData, successData, failureData}); - resetMoneyRequestInfo(); + Navigation.dismissModal(params.chatReportID); Report.notifyNewAction(params.chatReportID, managerID); } @@ -6004,7 +5981,6 @@ export { putOnHold, replaceReceipt, requestMoney, - resetMoneyRequestInfo, savePreferredPaymentMethod, sendMoneyElsewhere, sendMoneyWithWallet, From b3c9cf606bdae910d6f3446fa08afb3dabcf261c Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 13:51:40 -0300 Subject: [PATCH 73/79] run prettier --- src/libs/actions/IOU.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index c63a837cb671..4a05bbca4b11 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -2876,7 +2876,6 @@ function requestMoney( // eslint-disable-next-line rulesdir/no-multiple-api-calls API.write(WRITE_COMMANDS.REQUEST_MONEY, parameters, onyxData); - } } @@ -3045,7 +3044,6 @@ function trackExpense( }; API.write(WRITE_COMMANDS.TRACK_EXPENSE, parameters, onyxData); - } } if (action === CONST.IOU.ACTION.SHARE) { @@ -3548,7 +3546,6 @@ function splitBill({ API.write(WRITE_COMMANDS.SPLIT_BILL, parameters, onyxData); - Navigation.dismissModal(existingSplitChatReportID); Report.notifyNewAction(splitData.chatReportID, currentUserAccountID); } @@ -3607,7 +3604,6 @@ function splitBillAndOpenReport({ API.write(WRITE_COMMANDS.SPLIT_BILL_AND_OPEN_REPORT, parameters, onyxData); - Navigation.dismissModal(splitData.chatReportID); Report.notifyNewAction(splitData.chatReportID, currentUserAccountID); } @@ -3907,7 +3903,6 @@ function startSplitBill({ API.write(WRITE_COMMANDS.START_SPLIT_BILL, parameters, {optimisticData, successData, failureData}); - Navigation.dismissModalWithReport(splitChatReport); Report.notifyNewAction(splitChatReport.chatReportID ?? '', currentUserAccountID); } @@ -5251,7 +5246,6 @@ function sendMoneyElsewhere(report: OnyxEntry, amount: number, API.write(WRITE_COMMANDS.SEND_MONEY_ELSEWHERE, params, {optimisticData, successData, failureData}); - Navigation.dismissModal(params.chatReportID); Report.notifyNewAction(params.chatReportID, managerID); } @@ -5265,7 +5259,6 @@ function sendMoneyWithWallet(report: OnyxEntry, amount: number API.write(WRITE_COMMANDS.SEND_MONEY_WITH_WALLET, params, {optimisticData, successData, failureData}); - Navigation.dismissModal(params.chatReportID); Report.notifyNewAction(params.chatReportID, managerID); } From 5b9f01b3488dd4649dc79d45ce74f81d5b15d0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ska=C5=82ka?= Date: Wed, 24 Apr 2024 19:01:47 +0200 Subject: [PATCH 74/79] Bump react-native-live-markdown package version --- ios/Podfile.lock | 11 +++++------ package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6ef495a65bd3..f7fc4c6e047e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1837,7 +1837,7 @@ PODS: - RNGoogleSignin (10.0.1): - GoogleSignIn (~> 7.0) - React-Core - - RNLiveMarkdown (0.1.62): + - RNLiveMarkdown (0.1.64): - glog - hermes-engine - RCT-Folly (= 2022.05.16.00) @@ -1855,9 +1855,9 @@ PODS: - React-utils - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNLiveMarkdown/common (= 0.1.62) + - RNLiveMarkdown/common (= 0.1.64) - Yoga - - RNLiveMarkdown/common (0.1.62): + - RNLiveMarkdown/common (0.1.64): - glog - hermes-engine - RCT-Folly (= 2022.05.16.00) @@ -2083,6 +2083,7 @@ DEPENDENCIES: - ExpoImageManipulator (from `../node_modules/expo-image-manipulator/ios`) - ExpoModulesCore (from `../node_modules/expo-modules-core`) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) + - "fullstory_react-native (from `../node_modules/@fullstory/react-native`)" - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - libevent (~> 2.1.12) @@ -2248,8 +2249,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/Libraries/FBLazyVector" fullstory_react-native: :path: "../node_modules/@fullstory/react-native" - FBReactNativeSpec: - :path: "../node_modules/react-native/React/FBReactNativeSpec" glog: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: @@ -2569,7 +2568,7 @@ SPEC CHECKSUMS: RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 1190c218cdaaf029ee1437076a3fbbc3297d89fb RNGoogleSignin: ccaa4a81582cf713eea562c5dd9dc1961a715fd0 - RNLiveMarkdown: 47dfb50244f9ba1caefbc0efc6404ba41bf6620a + RNLiveMarkdown: ddc8b2d827febd397c88137ffc7a6e102d511b8b RNLocalize: d4b8af4e442d4bcca54e68fc687a2129b4d71a81 rnmapbox-maps: 3e273e0e867a079ec33df9ee33bb0482434b897d RNPermissions: 8990fc2c10da3640938e6db1647cb6416095b729 diff --git a/package-lock.json b/package-lock.json index df0456ac1d78..4eae23f5e74e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@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.62", + "@expensify/react-native-live-markdown": "0.1.64", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-listformat": "^7.2.2", @@ -3570,9 +3570,9 @@ } }, "node_modules/@expensify/react-native-live-markdown": { - "version": "0.1.62", - "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.62.tgz", - "integrity": "sha512-o70/tFIGZJ1U8U8aqTQu1HAZed6nt5LYWk74mrceRxQHOqsKhZgn2q5EuEy8EMIcnCGKjwxuDyZJbuRexgHx/A==", + "version": "0.1.64", + "resolved": "https://registry.npmjs.org/@expensify/react-native-live-markdown/-/react-native-live-markdown-0.1.64.tgz", + "integrity": "sha512-X6NXYH420wC+BFNOuzJflpegwSKTiuzLvbDeehCpxrtS059Eyb2FbwkzrAVH7TGwDeghFgaQfY9rVkSCGUAbsw==", "engines": { "node": ">= 18.0.0" }, diff --git a/package.json b/package.json index 44a111e0e88c..c7106e3cd65a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@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.62", + "@expensify/react-native-live-markdown": "0.1.64", "@expo/metro-runtime": "~3.1.1", "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-listformat": "^7.2.2", From 5b1c240f69098f07fbbd7459235edcfc8f936111 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 24 Apr 2024 17:19:35 +0000 Subject: [PATCH 75/79] Update version to 1.4.65-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 2264396ff9bf..641587e4f343 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001046503 - versionName "1.4.65-3" + versionCode 1001046504 + versionName "1.4.65-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 829ed3987bbd..5c489c59d7f4 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.65.3 + 1.4.65.4 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 51a3b8f830e8..ad64ce2e648a 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.65.3 + 1.4.65.4 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 362a79f18a3b..4c634c675ebb 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.65 CFBundleVersion - 1.4.65.3 + 1.4.65.4 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 1bc27e186d9f..b792015b1ac4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.65-3", + "version": "1.4.65-4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.65-3", + "version": "1.4.65-4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index a7369c837c3b..1a8e0bd31852 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.65-3", + "version": "1.4.65-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 e8893584aa32d1b89f3995fe74682202c1d0cd57 Mon Sep 17 00:00:00 2001 From: Francois Laithier Date: Wed, 24 Apr 2024 10:24:48 -0700 Subject: [PATCH 76/79] Don't include `X-Chat-Attachment-Token` header for static video thumbnails --- src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx index 9bbd9fe5fc62..76efec0879a8 100644 --- a/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx +++ b/src/components/VideoPlayerPreview/VideoPlayerThumbnail.tsx @@ -34,7 +34,8 @@ function VideoPlayerThumbnail({thumbnailUrl, onPress, accessibilityLabel}: Video )} From 2b0b12ca324a47eabce6b1563985b196d7ebe210 Mon Sep 17 00:00:00 2001 From: brunovjk Date: Wed, 24 Apr 2024 14:25:46 -0300 Subject: [PATCH 77/79] remove unnecessary 'eslint/naming-convention' --- src/libs/actions/IOU.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 4a05bbca4b11..e1c57ba01892 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -327,7 +327,6 @@ function clearMoneyRequest(transactionID: string, skipConfirmation = false) { Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, null); } -// eslint-disable-next-line @typescript-eslint/naming-convention function startMoneyRequest(iouType: ValueOf, reportID: string, requestType?: IOURequestType, skipConfirmation = false) { clearMoneyRequest(CONST.IOU.OPTIMISTIC_TRANSACTION_ID, skipConfirmation); switch (requestType) { @@ -345,17 +344,14 @@ function startMoneyRequest(iouType: ValueOf, reportID: st } } -// eslint-disable-next-line @typescript-eslint/naming-convention function setMoneyRequestAmount(transactionID: string, amount: number, currency: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency}); } -// eslint-disable-next-line @typescript-eslint/naming-convention function setMoneyRequestCreated(transactionID: string, created: string, isDraft: boolean) { Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {created}); } -// eslint-disable-next-line @typescript-eslint/naming-convention function setMoneyRequestCurrency(transactionID: string, currency: string, isEditing = false) { const fieldToUpdate = isEditing ? 'modifiedCurrency' : 'currency'; Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {[fieldToUpdate]: currency}); @@ -381,12 +377,10 @@ function setMoneyRequestTag(transactionID: string, tag: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {tag}); } -// eslint-disable-next-line @typescript-eslint/naming-convention function setMoneyRequestBillable(transactionID: string, billable: boolean) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {billable}); } -// eslint-disable-next-line @typescript-eslint/naming-convention function setMoneyRequestParticipants(transactionID: string, participants: Participant[] = []) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {participants}); } From 0ac175af1d0ae1f9738c55f2e853f4554c46995d Mon Sep 17 00:00:00 2001 From: Francois Laithier Date: Wed, 24 Apr 2024 11:37:35 -0700 Subject: [PATCH 78/79] Use new thumbnails for guided setup videos --- src/CONST.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index f0139d82e614..1dbded05426a 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3640,7 +3640,7 @@ const CONST = { message: 'Here are some essential tasks to keep your business spend in shape for tax season.', video: { url: `${CLOUDFRONT_URL}/videos/intro-1280.mp4`, - thumbnailUrl: `${CLOUDFRONT_URL}/images/expensify__favicon.png`, + thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-track-business.jpg`, duration: 55, width: 1280, height: 960, @@ -3680,7 +3680,7 @@ const CONST = { message: 'Getting paid back is as easy as sending a message. Let’s go over the basics.', video: { url: `${CLOUDFRONT_URL}/videos/intro-1280.mp4`, - thumbnailUrl: `${CLOUDFRONT_URL}/images/expensify__favicon.png`, + thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-get-paid-back.jpg`, duration: 55, width: 1280, height: 960, @@ -3721,7 +3721,7 @@ const CONST = { message: 'Here are some important tasks to help get your team’s expenses under control.', video: { url: `${CLOUDFRONT_URL}/videos/intro-1280.mp4`, - thumbnailUrl: `${CLOUDFRONT_URL}/images/expensify__favicon.png`, + thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-manage-team.jpg`, duration: 55, width: 1280, height: 960, @@ -3804,7 +3804,7 @@ const CONST = { message: 'Here’s how to track your spend in a few clicks.', video: { url: `${CLOUDFRONT_URL}/videos/intro-1280.mp4`, - thumbnailUrl: `${CLOUDFRONT_URL}/images/expensify__favicon.png`, + thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-track-personal.jpg`, duration: 55, width: 1280, height: 960, @@ -3831,7 +3831,7 @@ const CONST = { message: 'Splitting bills with friends is as easy as sending a message. Here’s how.', video: { url: `${CLOUDFRONT_URL}/videos/intro-1280.mp4`, - thumbnailUrl: `${CLOUDFRONT_URL}/images/expensify__favicon.png`, + thumbnailUrl: `${CLOUDFRONT_URL}/images/guided-setup-chat-split-bills.jpg`, duration: 55, width: 1280, height: 960, From 0f389435213f87d89795cee00577b4a2ac7416f3 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Wed, 24 Apr 2024 19:31:42 +0000 Subject: [PATCH 79/79] Update version to 1.4.65-5 --- 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 641587e4f343..21b152277957 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001046504 - versionName "1.4.65-4" + versionCode 1001046505 + versionName "1.4.65-5" // 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 5c489c59d7f4..d3689bbe3127 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.65.4 + 1.4.65.5 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index ad64ce2e648a..8a559a1b4f51 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.65.4 + 1.4.65.5 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 4c634c675ebb..6beb52aed9d6 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 1.4.65 CFBundleVersion - 1.4.65.4 + 1.4.65.5 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index b792015b1ac4..ead9af5ab37b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.65-4", + "version": "1.4.65-5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.65-4", + "version": "1.4.65-5", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 1a8e0bd31852..e14aecc5d387 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.65-4", + "version": "1.4.65-5", "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.",