From 20b38b29751c5a0c98297862053daddd99c32c36 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Mon, 20 Jan 2025 15:30:41 +0100 Subject: [PATCH 01/11] fix problem in WorkspaceInitialPage when adding new feature --- src/pages/workspace/WorkspaceInitialPage.tsx | 337 ++++++++++--------- 1 file changed, 185 insertions(+), 152 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 2a9b77551c0f..71876dfea817 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -68,6 +68,7 @@ type WorkspaceMenuItem = { | typeof SCREENS.WORKSPACE.RULES | typeof SCREENS.WORKSPACE.PER_DIEM; badgeText?: string; + highlighted?: boolean; }; type WorkspaceInitialPageProps = WithPolicyAndFullscreenLoadingProps & PlatformStackScreenProps; @@ -168,8 +169,185 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy, login); const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); const [featureStates, setFeatureStates] = useState(policyFeatureStates); + const [highlightedFeature, setHighlightedFeature] = useState(''); + + const workspaceMenuItems: WorkspaceMenuItem[] = useMemo(() => { + const protectedMenuItems: WorkspaceMenuItem[] = []; + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.distanceRates', + icon: Expensicons.Car, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_DISTANCE_RATES.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.DISTANCE_RATES, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.expensifyCard', + icon: Expensicons.ExpensifyCard, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.EXPENSIFY_CARD, + brickRoadIndicator: + !isEmptyObject(cardsList?.cardList?.errorFields ?? {}) || !isEmptyObject(cardSettings?.errors ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED]) { + const hasPolicyFeedsError = PolicyUtils.hasPolicyFeedsError(CardUtils.getCompanyFeeds(cardFeeds)); + + protectedMenuItems.push({ + translationKey: 'workspace.common.companyCards', + icon: Expensicons.CreditCard, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.COMPANY_CARDS, + brickRoadIndicator: hasPolicyFeedsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'common.perDiem', + icon: Expensicons.CalendarSolid, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.PER_DIEM, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.workflows', + icon: Expensicons.Workflows, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.WORKFLOWS, + brickRoadIndicator: !isEmptyObject(policy?.errorFields?.reimburser ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.rules', + icon: Expensicons.Feed, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_RULES.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.RULES, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED]) { + const currencyCode = policy?.outputCurrency ?? CONST.CURRENCY.USD; + + protectedMenuItems.push({ + translationKey: 'workspace.common.invoices', + icon: Expensicons.InvoiceGeneric, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_INVOICES.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.INVOICES, + badgeText: CurrencyUtils.convertToDisplayString(policy?.invoice?.bankAccount?.stripeConnectAccountBalance ?? 0, currencyCode), + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.categories', + icon: Expensicons.Folder, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_CATEGORIES.getRoute(policyID)))), + brickRoadIndicator: hasPolicyCategoryError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + routeName: SCREENS.WORKSPACE.CATEGORIES, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.tags', + icon: Expensicons.Tag, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_TAGS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.TAGS, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.taxes', + icon: Expensicons.Coins, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_TAXES.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.TAXES, + brickRoadIndicator: PolicyUtils.shouldShowTaxRateError(policy) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.reportFields', + icon: Expensicons.Pencil, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_REPORT_FIELDS.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.REPORT_FIELDS, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED, + }); + } + + if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED]) { + protectedMenuItems.push({ + translationKey: 'workspace.common.accounting', + icon: Expensicons.Sync, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING.getRoute(policyID)))), + brickRoadIndicator: hasSyncError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + routeName: SCREENS.WORKSPACE.ACCOUNTING.ROOT, + highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED, + }); + } - const protectedCollectPolicyMenuItems: WorkspaceMenuItem[] = []; + protectedMenuItems.push({ + translationKey: 'workspace.common.moreFeatures', + icon: Expensicons.Gear, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)))), + routeName: SCREENS.WORKSPACE.MORE_FEATURES, + }); + + const menuItems: WorkspaceMenuItem[] = [ + { + translationKey: 'workspace.common.profile', + icon: Expensicons.Building, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE.getRoute(policyID)))), + brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + routeName: SCREENS.WORKSPACE.PROFILE, + }, + { + translationKey: 'workspace.common.members', + icon: Expensicons.Users, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(policyID)))), + brickRoadIndicator: hasMembersError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + routeName: SCREENS.WORKSPACE.MEMBERS, + }, + ...(isPaidGroupPolicy && shouldShowProtectedItems ? protectedMenuItems : []), + ]; + + return menuItems; + }, [ + cardFeeds, + cardSettings?.errors, + cardsList?.cardList?.errorFields, + featureStates, + hasGeneralSettingsError, + hasMembersError, + hasPolicyCategoryError, + hasSyncError, + highlightedFeature, + isPaidGroupPolicy, + policy, + policyID, + shouldShowProtectedItems, + singleExecution, + waitForNavigate, + ]); // We only update feature states if they aren't pending. // These changes are made to synchronously change feature states along with AccessOrNotFoundWrapperComponent. @@ -181,6 +359,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac newFeatureStates[key] = prevPendingFields?.[key] !== policy?.pendingFields?.[key] || isOffline || !policy?.pendingFields?.[key] ? isFeatureEnabled : currentFeatureStates[key]; }); + + setHighlightedFeature(Object.keys(newFeatureStates).at(0) ?? ''); return { ...policyFeatureStates, ...newFeatureStates, @@ -192,154 +372,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac App.confirmReadyToOpenApp(); }, []); - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.distanceRates', - icon: Expensicons.Car, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_DISTANCE_RATES.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.DISTANCE_RATES, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.expensifyCard', - icon: Expensicons.ExpensifyCard, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.EXPENSIFY_CARD, - brickRoadIndicator: !isEmptyObject(cardsList?.cardList?.errorFields ?? {}) || !isEmptyObject(cardSettings?.errors ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED]) { - const hasPolicyFeedsError = PolicyUtils.hasPolicyFeedsError(CardUtils.getCompanyFeeds(cardFeeds)); - - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.companyCards', - icon: Expensicons.CreditCard, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.COMPANY_CARDS, - brickRoadIndicator: hasPolicyFeedsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'common.perDiem', - icon: Expensicons.CalendarSolid, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.PER_DIEM, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.workflows', - icon: Expensicons.Workflows, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.WORKFLOWS, - brickRoadIndicator: !isEmptyObject(policy?.errorFields?.reimburser ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.rules', - icon: Expensicons.Feed, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_RULES.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.RULES, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED]) { - const currencyCode = policy?.outputCurrency ?? CONST.CURRENCY.USD; - - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.invoices', - icon: Expensicons.InvoiceGeneric, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_INVOICES.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.INVOICES, - badgeText: CurrencyUtils.convertToDisplayString(policy?.invoice?.bankAccount?.stripeConnectAccountBalance ?? 0, currencyCode), - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.categories', - icon: Expensicons.Folder, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_CATEGORIES.getRoute(policyID)))), - brickRoadIndicator: hasPolicyCategoryError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - routeName: SCREENS.WORKSPACE.CATEGORIES, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.tags', - icon: Expensicons.Tag, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_TAGS.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.TAGS, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.taxes', - icon: Expensicons.Coins, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_TAXES.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.TAXES, - brickRoadIndicator: PolicyUtils.shouldShowTaxRateError(policy) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.reportFields', - icon: Expensicons.Pencil, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_REPORT_FIELDS.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.REPORT_FIELDS, - }); - } - - if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED]) { - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.accounting', - icon: Expensicons.Sync, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING.getRoute(policyID)))), - brickRoadIndicator: hasSyncError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - routeName: SCREENS.WORKSPACE.ACCOUNTING.ROOT, - }); - } - - protectedCollectPolicyMenuItems.push({ - translationKey: 'workspace.common.moreFeatures', - icon: Expensicons.Gear, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)))), - routeName: SCREENS.WORKSPACE.MORE_FEATURES, - }); - - const menuItems: WorkspaceMenuItem[] = [ - { - translationKey: 'workspace.common.profile', - icon: Expensicons.Building, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE.getRoute(policyID)))), - brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - routeName: SCREENS.WORKSPACE.PROFILE, - }, - { - translationKey: 'workspace.common.members', - icon: Expensicons.Users, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(policyID)))), - brickRoadIndicator: hasMembersError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - routeName: SCREENS.WORKSPACE.MEMBERS, - }, - ...(isPaidGroupPolicy && shouldShowProtectedItems ? protectedCollectPolicyMenuItems : []), - ]; - const prevPolicy = usePrevious(policy); - const prevProtectedMenuItems = usePrevious(protectedCollectPolicyMenuItems); - const enabledItem = protectedCollectPolicyMenuItems.find((curItem) => !prevProtectedMenuItems.some((prevItem) => curItem.routeName === prevItem.routeName)); - const shouldShowPolicy = useMemo(() => PolicyUtils.shouldShowPolicy(policy, isOffline, currentUserLogin), [policy, isOffline, currentUserLogin]); const prevShouldShowPolicy = useMemo(() => PolicyUtils.shouldShowPolicy(prevPolicy, isOffline, currentUserLogin), [prevPolicy, isOffline, currentUserLogin]); // We check shouldShowPolicy and prevShouldShowPolicy to prevent the NotFound view from showing right after we delete the workspace @@ -355,7 +388,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac // We are checking if the user can access the route. // If user can't access the route, we are dismissing any modals that are open when the NotFound view is shown - const canAccessRoute = activeRoute && (menuItems.some((item) => item.routeName === activeRoute) || activeRoute === SCREENS.WORKSPACE.INITIAL); + const canAccessRoute = activeRoute && (workspaceMenuItems.some((item) => item.routeName === activeRoute) || activeRoute === SCREENS.WORKSPACE.INITIAL); useEffect(() => { if (!shouldShowNotFoundPage && canAccessRoute) { @@ -422,9 +455,9 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac {/* Ideally we should use MenuList component for MenuItems with singleExecution/Navigation actions. - In this case where user can click on workspace avatar or menu items, we need to have a check for `isExecuting`. So, we are directly mapping menuItems. + In this case where user can click on workspace avatar or menu items, we need to have a check for `isExecuting`. So, we are directly mapping workspaceMenuItems. */} - {menuItems.map((item) => ( + {workspaceMenuItems.map((item) => ( Date: Mon, 20 Jan 2025 15:46:14 +0100 Subject: [PATCH 02/11] add accordion component --- src/components/Accordion/index.native.tsx | 81 +++++++++++++++++++ src/components/Accordion/index.tsx | 78 ++++++++++++++++++ src/libs/Navigation/linkTo/index.ts | 10 ++- .../workflows/ToggleSettingsOptionRow.tsx | 27 ++++++- 4 files changed, 191 insertions(+), 5 deletions(-) create mode 100644 src/components/Accordion/index.native.tsx create mode 100644 src/components/Accordion/index.tsx diff --git a/src/components/Accordion/index.native.tsx b/src/components/Accordion/index.native.tsx new file mode 100644 index 000000000000..0fcaa7294dd7 --- /dev/null +++ b/src/components/Accordion/index.native.tsx @@ -0,0 +1,81 @@ +import type {ReactNode} from 'react'; +import React from 'react'; +import type {StyleProp, ViewStyle} from 'react-native'; +import {View} from 'react-native'; +import type {SharedValue} from 'react-native-reanimated'; +import Animated, {Easing, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated'; +import useThemeStyles from '@hooks/useThemeStyles'; + +type AccordionProps = { + /** Giving information whether the component is open */ + isExpanded: SharedValue; + + /** Element that is inside Accordion */ + children: ReactNode; + + /** Duration of expansion animation */ + duration?: number; + + /** Additional external style */ + style?: StyleProp; + + /** Was toggle triggered */ + isToggleTriggered: SharedValue; +}; + +function Accordion({isExpanded, children, duration = 300, isToggleTriggered, style}: AccordionProps) { + const height = useSharedValue(0); + const styles = useThemeStyles(); + + const derivedHeight = useDerivedValue(() => { + if (!isToggleTriggered.get()) { + return isExpanded.get() ? height.get() : 0; + } + + return withTiming(height.get() * Number(isExpanded.get()), { + duration, + easing: Easing.inOut(Easing.quad), + }); + }); + + const derivedOpacity = useDerivedValue(() => { + if (!isToggleTriggered.get()) { + return isExpanded.get() ? 1 : 0; + } + + return withTiming(isExpanded.get() ? 1 : 0, { + duration, + easing: Easing.inOut(Easing.quad), + }); + }); + + const animatedStyle = useAnimatedStyle(() => { + if (!isToggleTriggered.get() && !isExpanded.get()) { + return { + height: 0, + opacity: 0, + }; + } + return { + height: !isToggleTriggered.get() ? height.get() : derivedHeight.get(), + opacity: derivedOpacity.get(), + }; + }); + + return ( + + { + height.set(e.nativeEvent.layout.height); + }} + style={[styles.pAbsolute, styles.l0, styles.r0, styles.t0]} + > + {children} + + + ); +} + +Accordion.displayName = 'Accordion'; + +export default Accordion; diff --git a/src/components/Accordion/index.tsx b/src/components/Accordion/index.tsx new file mode 100644 index 000000000000..9715f3902c03 --- /dev/null +++ b/src/components/Accordion/index.tsx @@ -0,0 +1,78 @@ +import type {ReactNode} from 'react'; +import React from 'react'; +import type {StyleProp, ViewStyle} from 'react-native'; +import {View} from 'react-native'; +import type {SharedValue} from 'react-native-reanimated'; +import Animated, {Easing, useAnimatedStyle, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated'; + +type AccordionProps = { + /** Giving information whether the component is open */ + isExpanded: SharedValue; + + /** Element that is inside Accordion */ + children: ReactNode; + + /** Duration of expansion animation */ + duration?: number; + + /** Additional external style */ + style?: StyleProp; + + /** Was toggle triggered */ + isToggleTriggered: SharedValue; +}; + +function Accordion({isExpanded, children, duration = 300, isToggleTriggered, style}: AccordionProps) { + const height = useSharedValue(0); + + const derivedHeight = useDerivedValue(() => { + if (!isToggleTriggered.get()) { + return isExpanded.get() ? height.get() : 0; + } + + return withTiming(height.get() * Number(isExpanded.get()), { + duration, + easing: Easing.inOut(Easing.quad), + }); + }); + + const derivedOpacity = useDerivedValue(() => { + if (!isToggleTriggered.get()) { + return isExpanded.get() ? 1 : 0; + } + + return withTiming(isExpanded.get() ? 1 : 0, { + duration, + easing: Easing.inOut(Easing.quad), + }); + }); + + const animatedStyle = useAnimatedStyle(() => { + if (!isToggleTriggered.get() && !isExpanded.get()) { + return { + height: 0, + opacity: 0, + }; + } + + return { + height: !isToggleTriggered.get() ? undefined : derivedHeight.get(), + opacity: derivedOpacity.get(), + }; + }); + + return ( + + { + height.set(e.nativeEvent.layout.height); + }} + > + {children} + + + ); +} +Accordion.displayName = 'Accordion'; + +export default Accordion; diff --git a/src/libs/Navigation/linkTo/index.ts b/src/libs/Navigation/linkTo/index.ts index 93ae33a6f77e..771c62c4ca70 100644 --- a/src/libs/Navigation/linkTo/index.ts +++ b/src/libs/Navigation/linkTo/index.ts @@ -183,7 +183,13 @@ export default function linkTo(navigation: NavigationContainerRef; + /** Used to apply styles to the Accordion */ + accordionStyle?: StyleProp; + /** Whether the option is enabled or not */ isActive: boolean; @@ -81,6 +86,7 @@ function ToggleSettingOptionRow({ customTitle, subtitle, subtitleStyle, + accordionStyle, switchAccessibilityLabel, shouldPlaceSubtitleBelowSwitch, shouldEscapeText = undefined, @@ -98,6 +104,12 @@ function ToggleSettingOptionRow({ showLockIcon = false, }: ToggleSettingOptionRowProps) { const styles = useThemeStyles(); + const isExpanded = useSharedValue(isActive); + const isToggleTriggered = useSharedValue(false); + + useEffect(() => { + isExpanded.set(isActive); + }, [isExpanded, isActive]); const subtitleHtml = useMemo(() => { if (!subtitle || !shouldParseSubtitle || typeof subtitle !== 'string') { @@ -171,14 +183,23 @@ function ToggleSettingOptionRow({ { + isToggleTriggered.set(true); + onToggle(isOn); + }} isOn={isActive} disabled={disabled} showLockIcon={showLockIcon} /> {shouldPlaceSubtitleBelowSwitch && subtitle && subTitleView} - {isActive && subMenuItems} + + {subMenuItems} + ); From 6ac60f38e0919405bc44d86882d7d5c11879ae4f Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Mon, 20 Jan 2025 18:03:33 +0100 Subject: [PATCH 03/11] fix imports --- src/pages/workspace/WorkspaceInitialPage.tsx | 132 ++++++++++++------- 1 file changed, 81 insertions(+), 51 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 71876dfea817..ed558472a9a9 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -7,7 +7,24 @@ import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView import ConfirmModal from '@components/ConfirmModal'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import HighlightableMenuItem from '@components/HighlightableMenuItem'; -import * as Expensicons from '@components/Icon/Expensicons'; +import { + Building, + CalendarSolid, + Car, + Coins, + CreditCard, + ExpensifyAppIcon, + ExpensifyCard, + Feed, + Folder, + Gear, + InvoiceGeneric, + Pencil, + Sync, + Tag, + Users, + Workflows, +} from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -21,17 +38,30 @@ import useSingleExecution from '@hooks/useSingleExecution'; import useThemeStyles from '@hooks/useThemeStyles'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; import {isConnectionInProgress} from '@libs/actions/connections'; -import * as CardUtils from '@libs/CardUtils'; -import * as CurrencyUtils from '@libs/CurrencyUtils'; +import {getCompanyFeeds} from '@libs/CardUtils'; +import {convertToDisplayString} from '@libs/CurrencyUtils'; import getTopmostRouteName from '@libs/Navigation/getTopmostRouteName'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; -import * as PolicyUtils from '@libs/PolicyUtils'; +import { + getWorkspaceAccountID, + goBackFromInvalidPolicy, + hasPolicyCategoriesError, + hasPolicyFeedsError, + isPaidGroupPolicy, + isPendingDeletePolicy, + isPolicyAdmin, + isPolicyFeatureEnabled, + shouldShowEmployeeListError, + shouldShowPolicy, + shouldShowSyncError, + shouldShowTaxRateError, +} from '@libs/PolicyUtils'; import {getDefaultWorkspaceAvatar, getIcons, getPolicyExpenseChat, getReportName, getReportOfflinePendingActionAndErrors} from '@libs/ReportUtils'; import type {FullScreenNavigatorParamList} from '@navigation/types'; -import * as App from '@userActions/App'; -import * as Policy from '@userActions/Policy/Policy'; -import * as ReimbursementAccount from '@userActions/ReimbursementAccount'; +import {confirmReadyToOpenApp} from '@userActions/App'; +import {clearErrors, openPolicyInitialPage, removeWorkspace, updateGeneralSettings} from '@userActions/Policy/Policy'; +import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -77,17 +107,17 @@ type PolicyFeatureStates = Record; function dismissError(policyID: string, pendingAction: PendingAction | undefined) { if (!policyID || pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { - PolicyUtils.goBackFromInvalidPolicy(); - Policy.removeWorkspace(policyID); + goBackFromInvalidPolicy(); + removeWorkspace(policyID); } else { - Policy.clearErrors(policyID); + clearErrors(policyID); } } function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: WorkspaceInitialPageProps) { const styles = useThemeStyles(); const policy = policyDraft?.id ? policyDraft : policyProp; - const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policy?.id); + const workspaceAccountID = getWorkspaceAccountID(policy?.id); const [isCurrencyModalOpen, setIsCurrencyModalOpen] = useState(false); const hasPolicyCreationError = !!(policy?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && !isEmptyObject(policy.errors)); const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); @@ -98,7 +128,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route.params?.policyID}`); const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const {login, accountID} = useCurrentUserPersonalDetails(); - const hasSyncError = PolicyUtils.shouldShowSyncError(policy, isConnectionInProgress(connectionSyncProgress, policy)); + const hasSyncError = shouldShowSyncError(policy, isConnectionInProgress(connectionSyncProgress, policy)); const waitForNavigate = useWaitForNavigation(); const {singleExecution, isExecuting} = useSingleExecution(); const activeRoute = useNavigationState(getTopmostRouteName); @@ -132,7 +162,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (policyDraft?.id) { return; } - Policy.openPolicyInitialPage(route.params.policyID); + openPolicyInitialPage(route.params.policyID); }, [policyDraft?.id, route.params.policyID]); useNetwork({onReconnect: fetchPolicyData}); @@ -154,22 +184,22 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac /** Call update workspace currency and hide the modal */ const confirmCurrencyChangeAndHideModal = useCallback(() => { - Policy.updateGeneralSettings(policyID, policyName, CONST.CURRENCY.USD); + updateGeneralSettings(policyID, policyName, CONST.CURRENCY.USD); setIsCurrencyModalOpen(false); - ReimbursementAccount.navigateToBankAccountRoute(policyID); + navigateToBankAccountRoute(policyID); }, [policyID, policyName]); - const hasMembersError = PolicyUtils.shouldShowEmployeeListError(policy); - const hasPolicyCategoryError = PolicyUtils.hasPolicyCategoriesError(policyCategories); + const hasMembersError = shouldShowEmployeeListError(policy); + const hasPolicyCategoryError = hasPolicyCategoriesError(policyCategories); const hasGeneralSettingsError = !isEmptyObject(policy?.errorFields?.name ?? {}) || !isEmptyObject(policy?.errorFields?.avatarURL ?? {}) || !isEmptyObject(policy?.errorFields?.ouputCurrency ?? {}) || !isEmptyObject(policy?.errorFields?.address ?? {}); - const shouldShowProtectedItems = PolicyUtils.isPolicyAdmin(policy, login); - const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); + const shouldShowProtectedItems = isPolicyAdmin(policy, login); + const isPaidGroupPolicyValue = isPaidGroupPolicy(policy); const [featureStates, setFeatureStates] = useState(policyFeatureStates); - const [highlightedFeature, setHighlightedFeature] = useState(''); + const [highlightedFeature, setHighlightedFeature] = useState(undefined); const workspaceMenuItems: WorkspaceMenuItem[] = useMemo(() => { const protectedMenuItems: WorkspaceMenuItem[] = []; @@ -177,7 +207,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.distanceRates', - icon: Expensicons.Car, + icon: Car, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_DISTANCE_RATES.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.DISTANCE_RATES, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_DISTANCE_RATES_ENABLED, @@ -187,7 +217,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.expensifyCard', - icon: Expensicons.ExpensifyCard, + icon: ExpensifyCard, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.EXPENSIFY_CARD, brickRoadIndicator: @@ -197,14 +227,14 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac } if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED]) { - const hasPolicyFeedsError = PolicyUtils.hasPolicyFeedsError(CardUtils.getCompanyFeeds(cardFeeds)); + const hasPolicyFeedsErrorValue = hasPolicyFeedsError(getCompanyFeeds(cardFeeds)); protectedMenuItems.push({ translationKey: 'workspace.common.companyCards', - icon: Expensicons.CreditCard, + icon: CreditCard, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.COMPANY_CARDS, - brickRoadIndicator: hasPolicyFeedsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + brickRoadIndicator: hasPolicyFeedsErrorValue ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED, }); } @@ -212,7 +242,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_PER_DIEM_RATES_ENABLED]) { protectedMenuItems.push({ translationKey: 'common.perDiem', - icon: Expensicons.CalendarSolid, + icon: CalendarSolid, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PER_DIEM.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.PER_DIEM, }); @@ -221,7 +251,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_WORKFLOWS_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.workflows', - icon: Expensicons.Workflows, + icon: Workflows, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.WORKFLOWS, brickRoadIndicator: !isEmptyObject(policy?.errorFields?.reimburser ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, @@ -232,7 +262,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.rules', - icon: Expensicons.Feed, + icon: Feed, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_RULES.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.RULES, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_RULES_ENABLED, @@ -244,10 +274,10 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac protectedMenuItems.push({ translationKey: 'workspace.common.invoices', - icon: Expensicons.InvoiceGeneric, + icon: InvoiceGeneric, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_INVOICES.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.INVOICES, - badgeText: CurrencyUtils.convertToDisplayString(policy?.invoice?.bankAccount?.stripeConnectAccountBalance ?? 0, currencyCode), + badgeText: convertToDisplayString(policy?.invoice?.bankAccount?.stripeConnectAccountBalance ?? 0, currencyCode), highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_INVOICES_ENABLED, }); } @@ -255,7 +285,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CATEGORIES_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.categories', - icon: Expensicons.Folder, + icon: Folder, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_CATEGORIES.getRoute(policyID)))), brickRoadIndicator: hasPolicyCategoryError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.CATEGORIES, @@ -266,7 +296,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.tags', - icon: Expensicons.Tag, + icon: Tag, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_TAGS.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.TAGS, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_TAGS_ENABLED, @@ -276,10 +306,10 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.taxes', - icon: Expensicons.Coins, + icon: Coins, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_TAXES.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.TAXES, - brickRoadIndicator: PolicyUtils.shouldShowTaxRateError(policy) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + brickRoadIndicator: shouldShowTaxRateError(policy) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED, }); } @@ -287,7 +317,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.reportFields', - icon: Expensicons.Pencil, + icon: Pencil, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_REPORT_FIELDS.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.REPORT_FIELDS, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_REPORT_FIELDS_ENABLED, @@ -297,7 +327,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED]) { protectedMenuItems.push({ translationKey: 'workspace.common.accounting', - icon: Expensicons.Sync, + icon: Sync, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING.getRoute(policyID)))), brickRoadIndicator: hasSyncError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.ACCOUNTING.ROOT, @@ -307,7 +337,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac protectedMenuItems.push({ translationKey: 'workspace.common.moreFeatures', - icon: Expensicons.Gear, + icon: Gear, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.MORE_FEATURES, }); @@ -315,19 +345,19 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const menuItems: WorkspaceMenuItem[] = [ { translationKey: 'workspace.common.profile', - icon: Expensicons.Building, + icon: Building, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE.getRoute(policyID)))), brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.PROFILE, }, { translationKey: 'workspace.common.members', - icon: Expensicons.Users, + icon: Users, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(policyID)))), brickRoadIndicator: hasMembersError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, routeName: SCREENS.WORKSPACE.MEMBERS, }, - ...(isPaidGroupPolicy && shouldShowProtectedItems ? protectedMenuItems : []), + ...(isPaidGroupPolicyValue && shouldShowProtectedItems ? protectedMenuItems : []), ]; return menuItems; @@ -341,7 +371,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac hasPolicyCategoryError, hasSyncError, highlightedFeature, - isPaidGroupPolicy, + isPaidGroupPolicyValue, policy, policyID, shouldShowProtectedItems, @@ -355,12 +385,12 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac setFeatureStates((currentFeatureStates) => { const newFeatureStates = {} as PolicyFeatureStates; (Object.keys(policy?.pendingFields ?? {}) as PolicyFeatureName[]).forEach((key) => { - const isFeatureEnabled = PolicyUtils.isPolicyFeatureEnabled(policy, key); + const isFeatureEnabled = isPolicyFeatureEnabled(policy, key); newFeatureStates[key] = prevPendingFields?.[key] !== policy?.pendingFields?.[key] || isOffline || !policy?.pendingFields?.[key] ? isFeatureEnabled : currentFeatureStates[key]; }); - setHighlightedFeature(Object.keys(newFeatureStates).at(0) ?? ''); + setHighlightedFeature(Object.keys(newFeatureStates).at(0)); return { ...policyFeatureStates, ...newFeatureStates, @@ -369,21 +399,21 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac }, [policy, isOffline, policyFeatureStates, prevPendingFields]); useEffect(() => { - App.confirmReadyToOpenApp(); + confirmReadyToOpenApp(); }, []); const prevPolicy = usePrevious(policy); - const shouldShowPolicy = useMemo(() => PolicyUtils.shouldShowPolicy(policy, isOffline, currentUserLogin), [policy, isOffline, currentUserLogin]); - const prevShouldShowPolicy = useMemo(() => PolicyUtils.shouldShowPolicy(prevPolicy, isOffline, currentUserLogin), [prevPolicy, isOffline, currentUserLogin]); + const actualShouldShowPolicy = useMemo(() => shouldShowPolicy(policy, isOffline, currentUserLogin), [policy, isOffline, currentUserLogin]); + const prevShouldShowPolicy = useMemo(() => shouldShowPolicy(prevPolicy, isOffline, currentUserLogin), [prevPolicy, isOffline, currentUserLogin]); // We check shouldShowPolicy and prevShouldShowPolicy to prevent the NotFound view from showing right after we delete the workspace // eslint-disable-next-line rulesdir/no-negated-variables - const shouldShowNotFoundPage = isEmptyObject(policy) || (!shouldShowPolicy && !prevShouldShowPolicy); + const shouldShowNotFoundPage = isEmptyObject(policy) || (!actualShouldShowPolicy && !prevShouldShowPolicy); useEffect(() => { - if (isEmptyObject(prevPolicy) || PolicyUtils.isPendingDeletePolicy(prevPolicy) || !PolicyUtils.isPendingDeletePolicy(policy)) { + if (isEmptyObject(prevPolicy) || isPendingDeletePolicy(prevPolicy) || !isPendingDeletePolicy(policy)) { return; } - PolicyUtils.goBackFromInvalidPolicy(); + goBackFromInvalidPolicy(); }, [policy, prevPolicy]); // We are checking if the user can access the route. @@ -406,7 +436,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const policyAvatar = useMemo(() => { if (!policy) { - return {source: Expensicons.ExpensifyAppIcon, name: CONST.WORKSPACE_SWITCHER.NAME, type: CONST.ICON_TYPE_AVATAR}; + return {source: ExpensifyAppIcon, name: CONST.WORKSPACE_SWITCHER.NAME, type: CONST.ICON_TYPE_AVATAR}; } const avatar = policy?.avatarURL ? policy.avatarURL : getDefaultWorkspaceAvatar(policy?.name); @@ -427,7 +457,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac onBackButtonPress={Navigation.dismissModal} onLinkPress={Navigation.resetToHome} shouldShow={shouldShowNotFoundPage} - subtitleKey={shouldShowPolicy ? 'workspace.common.notAuthorized' : undefined} + subtitleKey={actualShouldShowPolicy ? 'workspace.common.notAuthorized' : undefined} > Date: Fri, 24 Jan 2025 13:46:45 +0100 Subject: [PATCH 04/11] fix entering animation bug --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 9e5e03acd1b0..3b38e83268d9 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1065,7 +1065,7 @@ function removePendingFieldsFromCustomUnit(customUnit: CustomUnit): CustomUnit { function navigateWhenEnableFeature(policyID: string) { setTimeout(() => { - Navigation.navigate(ROUTES.WORKSPACE_INITIAL.getRoute(policyID)); + Navigation.goBack(ROUTES.WORKSPACE_INITIAL.getRoute(policyID)); }, CONST.WORKSPACE_ENABLE_FEATURE_REDIRECT_DELAY); } From 88998d18ced456409d7999e28a799a9642745639 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Fri, 24 Jan 2025 14:32:09 +0100 Subject: [PATCH 05/11] rename function --- src/libs/PolicyUtils.ts | 7 ++++ src/libs/actions/Policy/Category.ts | 10 +++-- src/libs/actions/Policy/DistanceRate.ts | 4 +- src/libs/actions/Policy/PerDiem.ts | 10 +++-- src/libs/actions/Policy/Policy.ts | 42 +++++++++++++------ .../workspace/WorkspaceMoreFeaturesPage.tsx | 14 +++---- 6 files changed, 59 insertions(+), 28 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 3b38e83268d9..c0d533fdafca 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1064,6 +1064,12 @@ function removePendingFieldsFromCustomUnit(customUnit: CustomUnit): CustomUnit { } function navigateWhenEnableFeature(policyID: string) { + setTimeout(() => { + Navigation.navigate(ROUTES.WORKSPACE_INITIAL.getRoute(policyID)); + }, CONST.WORKSPACE_ENABLE_FEATURE_REDIRECT_DELAY); +} + +function goBackWhenEnableFeature(policyID: string) { setTimeout(() => { Navigation.goBack(ROUTES.WORKSPACE_INITIAL.getRoute(policyID)); }, CONST.WORKSPACE_ENABLE_FEATURE_REDIRECT_DELAY); @@ -1298,6 +1304,7 @@ export { sortWorkspacesBySelected, removePendingFieldsFromCustomUnit, navigateWhenEnableFeature, + goBackWhenEnableFeature, getIntegrationLastSuccessfulDate, getCurrentConnectionName, getCustomersOrJobsLabelNetSuite, diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 1b3267f59163..673f85ae7b20 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -27,7 +27,7 @@ import {translateLocal} from '@libs/Localize'; import Log from '@libs/Log'; import enhanceParameters from '@libs/Network/enhanceParameters'; import {hasEnabledOptions} from '@libs/OptionsListUtils'; -import {getPolicy, navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {getPolicy, goBackWhenEnableFeature, navigateWhenEnableFeature} from '@libs/PolicyUtils'; import {getAllPolicyReports} from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -958,7 +958,7 @@ function deleteWorkspaceCategories(policyID: string, categoryNamesToDelete: stri API.write(WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES, parameters, onyxData); } -function enablePolicyCategories(policyID: string, enabled: boolean, shouldNavigate = true) { +function enablePolicyCategories(policyID: string, enabled: boolean, shouldNavigate = true, useGoBack = false) { const onyxUpdatesToDisableCategories: OnyxUpdate[] = []; if (!enabled) { onyxUpdatesToDisableCategories.push( @@ -1030,7 +1030,11 @@ function enablePolicyCategories(policyID: string, enabled: boolean, shouldNaviga API.write(WRITE_COMMANDS.ENABLE_POLICY_CATEGORIES, parameters, onyxData); if (enabled && getIsNarrowLayout() && shouldNavigate) { - navigateWhenEnableFeature(policyID); + if (useGoBack) { + goBackWhenEnableFeature(policyID); + } else { + navigateWhenEnableFeature(policyID); + } } } diff --git a/src/libs/actions/Policy/DistanceRate.ts b/src/libs/actions/Policy/DistanceRate.ts index 2a4cf0cde1a7..a56cc3d576e9 100644 --- a/src/libs/actions/Policy/DistanceRate.ts +++ b/src/libs/actions/Policy/DistanceRate.ts @@ -13,7 +13,7 @@ import type { import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; import getIsNarrowLayout from '@libs/getIsNarrowLayout'; -import {getDistanceRateCustomUnit, navigateWhenEnableFeature, removePendingFieldsFromCustomUnit} from '@libs/PolicyUtils'; +import {getDistanceRateCustomUnit, goBackWhenEnableFeature, removePendingFieldsFromCustomUnit} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -166,7 +166,7 @@ function enablePolicyDistanceRates(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_DISTANCE_RATES, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - navigateWhenEnableFeature(policyID); + goBackWhenEnableFeature(policyID); } } diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index c7a09e0365fe..bf893504943e 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -10,7 +10,7 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import {translateLocal} from '@libs/Localize'; import enhanceParameters from '@libs/Network/enhanceParameters'; import * as NumberUtils from '@libs/NumberUtils'; -import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature, navigateWhenEnableFeature} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -70,7 +70,7 @@ function generateCustomUnitID(): string { return NumberUtils.generateHexadecimalValue(13); } -function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string, disableRedirect?: boolean) { +function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string, disableRedirect?: boolean, useGoBack = false) { const doesCustomUnitExists = !!customUnitID; const finalCustomUnitID = doesCustomUnitExists ? customUnitID : generateCustomUnitID(); const optimisticCustomUnit = { @@ -124,7 +124,11 @@ function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string API.write(WRITE_COMMANDS.TOGGLE_POLICY_PER_DIEM, parameters, onyxData); if (enabled && getIsNarrowLayout() && !disableRedirect) { - navigateWhenEnableFeature(policyID); + if (useGoBack) { + goBackWhenEnableFeature(policyID); + } else { + navigateWhenEnableFeature(policyID); + } } } diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index c926b5552d11..e79d71db1dea 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -73,7 +73,7 @@ import * as NumberUtils from '@libs/NumberUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; -import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature, navigateWhenEnableFeature} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import {getAllReportTransactions} from '@libs/TransactionUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; @@ -2784,7 +2784,7 @@ function enablePolicyConnections(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_CONNECTIONS, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - navigateWhenEnableFeature(policyID); + goBackWhenEnableFeature(policyID); } } @@ -2841,11 +2841,11 @@ function enableExpensifyCard(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_EXPENSIFY_CARDS, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - navigateWhenEnableFeature(policyID); + goBackWhenEnableFeature(policyID); } } -function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect = false) { +function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect = false, useGoBack = false) { const authToken = NetworkStore.getAuthToken(); const onyxData: OnyxData = { @@ -2891,11 +2891,15 @@ function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect API.write(WRITE_COMMANDS.ENABLE_POLICY_COMPANY_CARDS, parameters, onyxData); if (enabled && getIsNarrowLayout() && !disableRedirect) { - navigateWhenEnableFeature(policyID); + if (useGoBack) { + goBackWhenEnableFeature(policyID); + } else { + navigateWhenEnableFeature(policyID); + } } } -function enablePolicyReportFields(policyID: string, enabled: boolean, disableRedirect = false) { +function enablePolicyReportFields(policyID: string, enabled: boolean, disableRedirect = false, useGoBack = false) { const onyxData: OnyxData = { optimisticData: [ { @@ -2939,11 +2943,15 @@ function enablePolicyReportFields(policyID: string, enabled: boolean, disableRed API.write(WRITE_COMMANDS.ENABLE_POLICY_REPORT_FIELDS, parameters, onyxData); if (enabled && getIsNarrowLayout() && !disableRedirect) { - navigateWhenEnableFeature(policyID); + if (useGoBack) { + goBackWhenEnableFeature(policyID); + } else { + navigateWhenEnableFeature(policyID); + } } } -function enablePolicyTaxes(policyID: string, enabled: boolean) { +function enablePolicyTaxes(policyID: string, enabled: boolean, useGoBack = false) { const defaultTaxRates: TaxRatesWithDefault = CONST.DEFAULT_TAX; const taxRatesData: OnyxData = { optimisticData: [ @@ -3053,7 +3061,11 @@ function enablePolicyTaxes(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_TAXES, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - navigateWhenEnableFeature(policyID); + if (useGoBack) { + goBackWhenEnableFeature(policyID); + } else { + navigateWhenEnableFeature(policyID); + } } } @@ -3144,7 +3156,7 @@ function enablePolicyWorkflows(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_WORKFLOWS, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - navigateWhenEnableFeature(policyID); + goBackWhenEnableFeature(policyID); } } @@ -3154,7 +3166,7 @@ const DISABLED_MAX_EXPENSE_VALUES: Pick { setIsDisableCompanyCardsWarningModalOpen(true); @@ -175,7 +175,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.perDiem.alias, ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID))); return; } - enablePerDiem(policyID, isEnabled, perDiemCustomUnit?.customUnitID); + enablePerDiem(policyID, isEnabled, perDiemCustomUnit?.customUnitID, undefined, true); }, }); } @@ -209,7 +209,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.rules.alias, ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID))); return; } - enablePolicyRules(policyID, isEnabled); + enablePolicyRules(policyID, isEnabled, false, true); }, }, ]; @@ -243,7 +243,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - enablePolicyCategories(policyID, isEnabled); + enablePolicyCategories(policyID, isEnabled, true, true); }, }, { @@ -273,7 +273,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - enablePolicyTaxes(policyID, isEnabled); + enablePolicyTaxes(policyID, isEnabled, true); }, }, { @@ -296,7 +296,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro return; } - enablePolicyReportFields(policyID, true); + enablePolicyReportFields(policyID, true, false, true); return; } setIsReportFieldsWarningModalOpen(true); @@ -507,7 +507,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro return; } setIsReportFieldsWarningModalOpen(false); - enablePolicyReportFields(policyID, false); + enablePolicyReportFields(policyID, false, false, true); }} onCancel={() => setIsReportFieldsWarningModalOpen(false)} prompt={translate('workspace.reportFields.disableReportFieldsConfirmation')} From aa3e3b7b04f3b6760337cf5f3af4d331ffbe2d48 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Fri, 24 Jan 2025 16:10:38 +0100 Subject: [PATCH 06/11] rename function --- src/libs/actions/Policy/Category.ts | 4 ++-- src/libs/actions/Policy/PerDiem.ts | 4 ++-- src/libs/actions/Policy/Policy.ts | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 673f85ae7b20..5934e2780838 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -958,7 +958,7 @@ function deleteWorkspaceCategories(policyID: string, categoryNamesToDelete: stri API.write(WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES, parameters, onyxData); } -function enablePolicyCategories(policyID: string, enabled: boolean, shouldNavigate = true, useGoBack = false) { +function enablePolicyCategories(policyID: string, enabled: boolean, shouldNavigate = true, shouldGoBack = false) { const onyxUpdatesToDisableCategories: OnyxUpdate[] = []; if (!enabled) { onyxUpdatesToDisableCategories.push( @@ -1030,7 +1030,7 @@ function enablePolicyCategories(policyID: string, enabled: boolean, shouldNaviga API.write(WRITE_COMMANDS.ENABLE_POLICY_CATEGORIES, parameters, onyxData); if (enabled && getIsNarrowLayout() && shouldNavigate) { - if (useGoBack) { + if (shouldGoBack) { goBackWhenEnableFeature(policyID); } else { navigateWhenEnableFeature(policyID); diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index bf893504943e..467deae5250f 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -70,7 +70,7 @@ function generateCustomUnitID(): string { return NumberUtils.generateHexadecimalValue(13); } -function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string, disableRedirect?: boolean, useGoBack = false) { +function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string, disableRedirect?: boolean, shouldGoBack = false) { const doesCustomUnitExists = !!customUnitID; const finalCustomUnitID = doesCustomUnitExists ? customUnitID : generateCustomUnitID(); const optimisticCustomUnit = { @@ -124,7 +124,7 @@ function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string API.write(WRITE_COMMANDS.TOGGLE_POLICY_PER_DIEM, parameters, onyxData); if (enabled && getIsNarrowLayout() && !disableRedirect) { - if (useGoBack) { + if (shouldGoBack) { goBackWhenEnableFeature(policyID); } else { navigateWhenEnableFeature(policyID); diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index d8796a686b31..d073ae713d36 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2853,7 +2853,7 @@ function enableExpensifyCard(policyID: string, enabled: boolean) { } } -function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect = false, useGoBack = false) { +function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect = false, shouldGoBack = false) { const authToken = NetworkStore.getAuthToken(); const onyxData: OnyxData = { @@ -2899,7 +2899,7 @@ function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect API.write(WRITE_COMMANDS.ENABLE_POLICY_COMPANY_CARDS, parameters, onyxData); if (enabled && getIsNarrowLayout() && !disableRedirect) { - if (useGoBack) { + if (shouldGoBack) { goBackWhenEnableFeature(policyID); } else { navigateWhenEnableFeature(policyID); @@ -2907,7 +2907,7 @@ function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect } } -function enablePolicyReportFields(policyID: string, enabled: boolean, disableRedirect = false, useGoBack = false) { +function enablePolicyReportFields(policyID: string, enabled: boolean, disableRedirect = false, shouldGoBack = false) { const onyxData: OnyxData = { optimisticData: [ { @@ -2951,7 +2951,7 @@ function enablePolicyReportFields(policyID: string, enabled: boolean, disableRed API.write(WRITE_COMMANDS.ENABLE_POLICY_REPORT_FIELDS, parameters, onyxData); if (enabled && getIsNarrowLayout() && !disableRedirect) { - if (useGoBack) { + if (shouldGoBack) { goBackWhenEnableFeature(policyID); } else { navigateWhenEnableFeature(policyID); @@ -2959,7 +2959,7 @@ function enablePolicyReportFields(policyID: string, enabled: boolean, disableRed } } -function enablePolicyTaxes(policyID: string, enabled: boolean, useGoBack = false) { +function enablePolicyTaxes(policyID: string, enabled: boolean, shouldGoBack = false) { const defaultTaxRates: TaxRatesWithDefault = CONST.DEFAULT_TAX; const taxRatesData: OnyxData = { optimisticData: [ @@ -3069,7 +3069,7 @@ function enablePolicyTaxes(policyID: string, enabled: boolean, useGoBack = false API.write(WRITE_COMMANDS.ENABLE_POLICY_TAXES, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - if (useGoBack) { + if (shouldGoBack) { goBackWhenEnableFeature(policyID); } else { navigateWhenEnableFeature(policyID); @@ -3174,7 +3174,7 @@ const DISABLED_MAX_EXPENSE_VALUES: Pick Date: Fri, 24 Jan 2025 17:23:19 +0100 Subject: [PATCH 07/11] better naming for function parameters --- src/libs/actions/Policy/Category.ts | 12 ++---- src/libs/actions/Policy/PerDiem.ts | 10 ++--- src/libs/actions/Policy/Policy.ts | 40 ++++++------------- .../workspace/WorkspaceMoreFeaturesPage.tsx | 14 +++---- .../upgrade/WorkspaceUpgradePage.tsx | 8 ++-- 5 files changed, 30 insertions(+), 54 deletions(-) diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 5934e2780838..375eb0970bf5 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -27,7 +27,7 @@ import {translateLocal} from '@libs/Localize'; import Log from '@libs/Log'; import enhanceParameters from '@libs/Network/enhanceParameters'; import {hasEnabledOptions} from '@libs/OptionsListUtils'; -import {getPolicy, goBackWhenEnableFeature, navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {getPolicy, goBackWhenEnableFeature} from '@libs/PolicyUtils'; import {getAllPolicyReports} from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -958,7 +958,7 @@ function deleteWorkspaceCategories(policyID: string, categoryNamesToDelete: stri API.write(WRITE_COMMANDS.DELETE_WORKSPACE_CATEGORIES, parameters, onyxData); } -function enablePolicyCategories(policyID: string, enabled: boolean, shouldNavigate = true, shouldGoBack = false) { +function enablePolicyCategories(policyID: string, enabled: boolean, shouldGoBack = true) { const onyxUpdatesToDisableCategories: OnyxUpdate[] = []; if (!enabled) { onyxUpdatesToDisableCategories.push( @@ -1029,12 +1029,8 @@ function enablePolicyCategories(policyID: string, enabled: boolean, shouldNaviga API.write(WRITE_COMMANDS.ENABLE_POLICY_CATEGORIES, parameters, onyxData); - if (enabled && getIsNarrowLayout() && shouldNavigate) { - if (shouldGoBack) { - goBackWhenEnableFeature(policyID); - } else { - navigateWhenEnableFeature(policyID); - } + if (enabled && getIsNarrowLayout() && shouldGoBack) { + goBackWhenEnableFeature(policyID); } } diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index 467deae5250f..29edeabb3f04 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -70,7 +70,7 @@ function generateCustomUnitID(): string { return NumberUtils.generateHexadecimalValue(13); } -function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string, disableRedirect?: boolean, shouldGoBack = false) { +function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string, shouldGoBack?: boolean) { const doesCustomUnitExists = !!customUnitID; const finalCustomUnitID = doesCustomUnitExists ? customUnitID : generateCustomUnitID(); const optimisticCustomUnit = { @@ -123,12 +123,8 @@ function enablePerDiem(policyID: string, enabled: boolean, customUnitID?: string API.write(WRITE_COMMANDS.TOGGLE_POLICY_PER_DIEM, parameters, onyxData); - if (enabled && getIsNarrowLayout() && !disableRedirect) { - if (shouldGoBack) { - goBackWhenEnableFeature(policyID); - } else { - navigateWhenEnableFeature(policyID); - } + if (enabled && getIsNarrowLayout() && shouldGoBack) { + goBackWhenEnableFeature(policyID); } } diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index d073ae713d36..ff31c5660f57 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -73,7 +73,7 @@ import * as NumberUtils from '@libs/NumberUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PhoneNumber from '@libs/PhoneNumber'; import * as PolicyUtils from '@libs/PolicyUtils'; -import {goBackWhenEnableFeature, navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import type {PolicySelector} from '@pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover'; import * as PaymentMethods from '@userActions/PaymentMethods'; @@ -2853,7 +2853,7 @@ function enableExpensifyCard(policyID: string, enabled: boolean) { } } -function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect = false, shouldGoBack = false) { +function enableCompanyCards(policyID: string, enabled: boolean, shouldGoBack = true) { const authToken = NetworkStore.getAuthToken(); const onyxData: OnyxData = { @@ -2898,16 +2898,12 @@ function enableCompanyCards(policyID: string, enabled: boolean, disableRedirect API.write(WRITE_COMMANDS.ENABLE_POLICY_COMPANY_CARDS, parameters, onyxData); - if (enabled && getIsNarrowLayout() && !disableRedirect) { - if (shouldGoBack) { - goBackWhenEnableFeature(policyID); - } else { - navigateWhenEnableFeature(policyID); - } + if (enabled && getIsNarrowLayout() && shouldGoBack) { + goBackWhenEnableFeature(policyID); } } -function enablePolicyReportFields(policyID: string, enabled: boolean, disableRedirect = false, shouldGoBack = false) { +function enablePolicyReportFields(policyID: string, enabled: boolean, shouldGoBack = true) { const onyxData: OnyxData = { optimisticData: [ { @@ -2950,16 +2946,12 @@ function enablePolicyReportFields(policyID: string, enabled: boolean, disableRed API.write(WRITE_COMMANDS.ENABLE_POLICY_REPORT_FIELDS, parameters, onyxData); - if (enabled && getIsNarrowLayout() && !disableRedirect) { - if (shouldGoBack) { - goBackWhenEnableFeature(policyID); - } else { - navigateWhenEnableFeature(policyID); - } + if (enabled && getIsNarrowLayout() && shouldGoBack) { + goBackWhenEnableFeature(policyID); } } -function enablePolicyTaxes(policyID: string, enabled: boolean, shouldGoBack = false) { +function enablePolicyTaxes(policyID: string, enabled: boolean) { const defaultTaxRates: TaxRatesWithDefault = CONST.DEFAULT_TAX; const taxRatesData: OnyxData = { optimisticData: [ @@ -3069,11 +3061,7 @@ function enablePolicyTaxes(policyID: string, enabled: boolean, shouldGoBack = fa API.write(WRITE_COMMANDS.ENABLE_POLICY_TAXES, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - if (shouldGoBack) { - goBackWhenEnableFeature(policyID); - } else { - navigateWhenEnableFeature(policyID); - } + goBackWhenEnableFeature(policyID); } } @@ -3174,7 +3162,7 @@ const DISABLED_MAX_EXPENSE_VALUES: Pick { setIsDisableCompanyCardsWarningModalOpen(true); @@ -175,7 +175,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.perDiem.alias, ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID))); return; } - enablePerDiem(policyID, isEnabled, perDiemCustomUnit?.customUnitID, undefined, true); + enablePerDiem(policyID, isEnabled, perDiemCustomUnit?.customUnitID, true); }, }); } @@ -209,7 +209,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.rules.alias, ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID))); return; } - enablePolicyRules(policyID, isEnabled, false, true); + enablePolicyRules(policyID, isEnabled); }, }, ]; @@ -243,7 +243,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - enablePolicyCategories(policyID, isEnabled, true, true); + enablePolicyCategories(policyID, isEnabled, true); }, }, { @@ -273,7 +273,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - enablePolicyTaxes(policyID, isEnabled, true); + enablePolicyTaxes(policyID, isEnabled); }, }, { @@ -296,7 +296,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro return; } - enablePolicyReportFields(policyID, true, false, true); + enablePolicyReportFields(policyID, true, true); return; } setIsReportFieldsWarningModalOpen(true); @@ -507,7 +507,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro return; } setIsReportFieldsWarningModalOpen(false); - enablePolicyReportFields(policyID, false, false, true); + enablePolicyReportFields(policyID, false, true); }} onCancel={() => setIsReportFieldsWarningModalOpen(false)} prompt={translate('workspace.reportFields.disableReportFieldsConfirmation')} diff --git a/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx b/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx index e31ef3232ba4..1d9063a9ceba 100644 --- a/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx +++ b/src/pages/workspace/upgrade/WorkspaceUpgradePage.tsx @@ -128,18 +128,18 @@ function WorkspaceUpgradePage({route}: WorkspaceUpgradePageProps) { break; } default: { - Policy.enablePolicyReportFields(policyID, true, true); + Policy.enablePolicyReportFields(policyID, true, false); } } break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.rules.id: - Policy.enablePolicyRules(policyID, true, true); + Policy.enablePolicyRules(policyID, true, false); break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.companyCards.id: - Policy.enableCompanyCards(policyID, true, true); + Policy.enableCompanyCards(policyID, true, false); break; case CONST.UPGRADE_FEATURE_INTRO_MAPPING.perDiem.id: - PerDiem.enablePerDiem(policyID, true, perDiemCustomUnit?.customUnitID, true); + PerDiem.enablePerDiem(policyID, true, perDiemCustomUnit?.customUnitID, false); break; default: } From e84be2af46fa62252b81e94d14eed8f7ce2ef45a Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Fri, 24 Jan 2025 17:39:35 +0100 Subject: [PATCH 08/11] fix import --- src/libs/actions/Policy/PerDiem.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index 29edeabb3f04..0afb011805ed 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -10,7 +10,7 @@ import getIsNarrowLayout from '@libs/getIsNarrowLayout'; import {translateLocal} from '@libs/Localize'; import enhanceParameters from '@libs/Network/enhanceParameters'; import * as NumberUtils from '@libs/NumberUtils'; -import {goBackWhenEnableFeature, navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; From 2f73c2f0d16814b49332e00546e62266bcbcdb68 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Tue, 28 Jan 2025 10:24:55 +0100 Subject: [PATCH 09/11] remove unused function --- src/libs/PolicyUtils.ts | 7 ------- src/libs/actions/Policy/Tag.ts | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index c0d533fdafca..7314c901b55a 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1063,12 +1063,6 @@ function removePendingFieldsFromCustomUnit(customUnit: CustomUnit): CustomUnit { return cleanedCustomUnit; } -function navigateWhenEnableFeature(policyID: string) { - setTimeout(() => { - Navigation.navigate(ROUTES.WORKSPACE_INITIAL.getRoute(policyID)); - }, CONST.WORKSPACE_ENABLE_FEATURE_REDIRECT_DELAY); -} - function goBackWhenEnableFeature(policyID: string) { setTimeout(() => { Navigation.goBack(ROUTES.WORKSPACE_INITIAL.getRoute(policyID)); @@ -1303,7 +1297,6 @@ export { getDistanceRateCustomUnitRate, sortWorkspacesBySelected, removePendingFieldsFromCustomUnit, - navigateWhenEnableFeature, goBackWhenEnableFeature, getIntegrationLastSuccessfulDate, getCurrentConnectionName, diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 9186e1478b36..c22a5922d0dd 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -22,7 +22,7 @@ import Log from '@libs/Log'; import enhanceParameters from '@libs/Network/enhanceParameters'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import {navigateWhenEnableFeature} from '@libs/PolicyUtils'; +import {goBackWhenEnableFeature} from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import {getTagArrayFromName} from '@libs/TransactionUtils'; import type {PolicyTagList} from '@pages/workspace/tags/types'; @@ -692,7 +692,7 @@ function enablePolicyTags(policyID: string, enabled: boolean) { API.write(WRITE_COMMANDS.ENABLE_POLICY_TAGS, parameters, onyxData); if (enabled && getIsNarrowLayout()) { - navigateWhenEnableFeature(policyID); + goBackWhenEnableFeature(policyID); } } From 44a9e2c0c884da4ceb70941ee6379e816d315efb Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Tue, 28 Jan 2025 13:05:35 +0100 Subject: [PATCH 10/11] resolve conflicts --- src/pages/workspace/WorkspaceInitialPage.tsx | 96 ++++++++++++++------ 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index ae7bf260ad42..84a7107fc5e7 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -120,7 +120,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const policy = policyDraft?.id ? policyDraft : policyProp; const workspaceAccountID = getWorkspaceAccountID(policy?.id); const [isCurrencyModalOpen, setIsCurrencyModalOpen] = useState(false); - const hasPolicyCreationError = !!(policy?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && !isEmptyObject(policy.errors)); + const hasPolicyCreationError = policy?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && !isEmptyObject(policy.errors); const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`); @@ -199,6 +199,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac !isEmptyObject(policy?.errorFields?.address ?? {}); const shouldShowProtectedItems = isPolicyAdmin(policy, login); const [featureStates, setFeatureStates] = useState(policyFeatureStates); + const [highlightedFeature, setHighlightedFeature] = useState(undefined); const workspaceMenuItems: WorkspaceMenuItem[] = useMemo(() => { @@ -220,21 +221,19 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac icon: ExpensifyCard, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_EXPENSIFY_CARD.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.EXPENSIFY_CARD, - brickRoadIndicator: - !isEmptyObject(cardsList?.cardList?.errorFields ?? {}) || !isEmptyObject(cardSettings?.errors ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_EXPENSIFY_CARDS_ENABLED, }); } if (featureStates?.[CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED]) { - const hasPolicyFeedsErrorValue = hasPolicyFeedsError(getCompanyFeeds(cardFeeds)); + const hasBrokenFeedConnection = checkIfFeedConnectionIsBroken(flatAllCardsList(allFeedsCards, workspaceAccountID)); protectedMenuItems.push({ translationKey: 'workspace.common.companyCards', icon: CreditCard, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_COMPANY_CARDS.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.COMPANY_CARDS, - brickRoadIndicator: hasPolicyFeedsErrorValue ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + brickRoadIndicator: hasBrokenFeedConnection ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, highlighted: highlightedFeature === CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED, }); } @@ -342,34 +341,71 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac routeName: SCREENS.WORKSPACE.MORE_FEATURES, }); - const menuItems: WorkspaceMenuItem[] = [ - { - translationKey: 'workspace.common.profile', - icon: Expensicons.Building, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE.getRoute(policyID)))), - brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - routeName: SCREENS.WORKSPACE.PROFILE, - }, - { - translationKey: 'workspace.common.members', - icon: Expensicons.Users, - action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(policyID)))), - brickRoadIndicator: hasMembersError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - routeName: SCREENS.WORKSPACE.MEMBERS, - }, - ...(isPaidGroupPolicy(policy) && shouldShowProtectedItems ? protectedCollectPolicyMenuItems : []), - ]; + const menuItems: WorkspaceMenuItem[] = [ + { + translationKey: 'workspace.common.profile', + icon: Building, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE.getRoute(policyID)))), + brickRoadIndicator: hasGeneralSettingsError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + routeName: SCREENS.WORKSPACE.PROFILE, + }, + { + translationKey: 'workspace.common.members', + icon: Users, + action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(policyID)))), + brickRoadIndicator: hasMembersError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + routeName: SCREENS.WORKSPACE.MEMBERS, + }, + ...(isPaidGroupPolicy(policy) && shouldShowProtectedItems ? protectedMenuItems : []), + ]; + + return menuItems; + }, [ + cardSettings?.errors, + cardsList?.cardList?.errorFields, + featureStates, + hasGeneralSettingsError, + hasMembersError, + hasPolicyCategoryError, + hasSyncError, + highlightedFeature, + policy, + policyID, + shouldShowProtectedItems, + singleExecution, + waitForNavigate, + ]); + + // We only update feature states if they aren't pending. + // These changes are made to synchronously change feature states along with AccessOrNotFoundWrapperComponent. + useEffect(() => { + setFeatureStates((currentFeatureStates) => { + const newFeatureStates = {} as PolicyFeatureStates; + (Object.keys(policy?.pendingFields ?? {}) as PolicyFeatureName[]).forEach((key) => { + const isFeatureEnabled = isPolicyFeatureEnabled(policy, key); + newFeatureStates[key] = + prevPendingFields?.[key] !== policy?.pendingFields?.[key] || isOffline || !policy?.pendingFields?.[key] ? isFeatureEnabled : currentFeatureStates[key]; + }); + + setHighlightedFeature(Object.keys(newFeatureStates).at(0)); + return { + ...policyFeatureStates, + ...newFeatureStates, + }; + }); + }, [policy, isOffline, policyFeatureStates, prevPendingFields]); + + useEffect(() => { + confirmReadyToOpenApp(); + }, []); const prevPolicy = usePrevious(policy); - const prevProtectedMenuItems = usePrevious(protectedCollectPolicyMenuItems); - const enabledItem = protectedCollectPolicyMenuItems.find((curItem) => !prevProtectedMenuItems.some((prevItem) => curItem.routeName === prevItem.routeName)); - const shouldShowPolicy = useMemo(() => checkIfShouldShowPolicy(policy, false, currentUserLogin), [policy, currentUserLogin]); - const prevShouldShowPolicy = useMemo(() => checkIfShouldShowPolicy(prevPolicy, false, currentUserLogin), [prevPolicy, currentUserLogin]); - const actualShouldShowPolicy = useMemo(() => shouldShowPolicy(policy, isOffline, currentUserLogin), [policy, isOffline, currentUserLogin]); + const shouldShowPolicy = useMemo(() => checkIfShouldShowPolicy(policy, isOffline, currentUserLogin), [policy, isOffline, currentUserLogin]); + const prevShouldShowPolicy = useMemo(() => checkIfShouldShowPolicy(prevPolicy, isOffline, currentUserLogin), [prevPolicy, isOffline, currentUserLogin]); // We check shouldShowPolicy and prevShouldShowPolicy to prevent the NotFound view from showing right after we delete the workspace // eslint-disable-next-line rulesdir/no-negated-variables - const shouldShowNotFoundPage = isEmptyObject(policy) || (!actualShouldShowPolicy && !prevShouldShowPolicy); + const shouldShowNotFoundPage = isEmptyObject(policy) || (!shouldShowPolicy && !prevShouldShowPolicy); useEffect(() => { if (isEmptyObject(prevPolicy) || isPendingDeletePolicy(prevPolicy) || !isPendingDeletePolicy(policy)) { @@ -419,7 +455,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac onBackButtonPress={Navigation.dismissModal} onLinkPress={Navigation.resetToHome} shouldShow={shouldShowNotFoundPage} - subtitleKey={actualShouldShowPolicy ? 'workspace.common.notAuthorized' : undefined} + subtitleKey={shouldShowPolicy ? 'workspace.common.notAuthorized' : undefined} > {/* Ideally we should use MenuList component for MenuItems with singleExecution/Navigation actions. - In this case where user can click on workspace avatar or menu items, we need to have a check for `isExecuting`. So, we are directly mapping workspaceMenuItems. + In this case where user can click on workspace avatar or menu items, we need to have a check for `isExecuting`. So, we are directly mapping menuItems. */} {workspaceMenuItems.map((item) => ( Date: Tue, 28 Jan 2025 13:20:10 +0100 Subject: [PATCH 11/11] fix linter --- src/pages/workspace/WorkspaceInitialPage.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 84a7107fc5e7..58309cffe930 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -122,8 +122,6 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const [isCurrencyModalOpen, setIsCurrencyModalOpen] = useState(false); const hasPolicyCreationError = policy?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && !isEmptyObject(policy.errors); const [allFeedsCards] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}`); - const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); - const [cardsList] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`); const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policy?.id}`); const [currentUserLogin] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email}); const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route.params?.policyID}`); @@ -361,8 +359,6 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac return menuItems; }, [ - cardSettings?.errors, - cardsList?.cardList?.errorFields, featureStates, hasGeneralSettingsError, hasMembersError, @@ -374,6 +370,8 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac shouldShowProtectedItems, singleExecution, waitForNavigate, + allFeedsCards, + workspaceAccountID, ]); // We only update feature states if they aren't pending.