diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index 6c6e70b8cc28..c9836a31f7b8 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -14,19 +14,31 @@ import useNetwork from '@hooks/useNetwork'; import usePermissions from '@hooks/usePermissions'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyledSafeAreaInsets from '@hooks/useStyledSafeAreaInsets'; +import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as CardUtils from '@libs/CardUtils'; -import * as ErrorUtils from '@libs/ErrorUtils'; +import {getCompanyFeeds} from '@libs/CardUtils'; +import {getLatestErrorField} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {FullScreenNavigatorParamList} from '@libs/Navigation/types'; import {getPerDiemCustomUnit, isControlPolicy} from '@libs/PolicyUtils'; -import * as Category from '@userActions/Policy/Category'; -import * as DistanceRate from '@userActions/Policy/DistanceRate'; -import * as PerDiem from '@userActions/Policy/PerDiem'; -import * as Policy from '@userActions/Policy/Policy'; -import * as Tag from '@userActions/Policy/Tag'; -import * as Report from '@userActions/Report'; +import {enablePolicyCategories} from '@userActions/Policy/Category'; +import {enablePolicyDistanceRates} from '@userActions/Policy/DistanceRate'; +import {enablePerDiem} from '@userActions/Policy/PerDiem'; +import { + clearPolicyErrorField, + enableCompanyCards, + enableExpensifyCard, + enablePolicyConnections, + enablePolicyInvoicing, + enablePolicyReportFields, + enablePolicyRules, + enablePolicyTaxes, + enablePolicyWorkflows, + openPolicyMoreFeaturesPage, +} from '@userActions/Policy/Policy'; +import {enablePolicyTags} from '@userActions/Policy/Tag'; +import {navigateToConciergeChat} from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -63,6 +75,7 @@ type SectionObject = { function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPageProps) { const styles = useThemeStyles(); + const stylesutils = useStyleUtils(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const {safeAreaPaddingBottomStyle} = useStyledSafeAreaInsets(); const {translate} = useLocalize(); @@ -103,7 +116,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - DistanceRate.enablePolicyDistanceRates(policyID, isEnabled); + enablePolicyDistanceRates(policyID, isEnabled); }, }, { @@ -117,7 +130,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Policy.enableExpensifyCard(policyID, isEnabled); + enableExpensifyCard(policyID, isEnabled); }, disabledAction: () => { setIsDisableExpensifyCardWarningModalOpen(true); @@ -131,7 +144,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro subtitleTranslationKey: 'workspace.moreFeatures.companyCards.subtitle', isActive: policy?.areCompanyCardsEnabled ?? false, pendingAction: policy?.pendingFields?.areCompanyCardsEnabled, - disabled: !isEmptyObject(CardUtils.getCompanyFeeds(cardFeeds)), + disabled: !isEmptyObject(getCompanyFeeds(cardFeeds)), action: (isEnabled: boolean) => { if (!policyID) { return; @@ -140,7 +153,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.companyCards.alias, ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID))); return; } - Policy.enableCompanyCards(policyID, isEnabled); + enableCompanyCards(policyID, isEnabled); }, disabledAction: () => { setIsDisableCompanyCardsWarningModalOpen(true); @@ -162,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; } - PerDiem.enablePerDiem(policyID, isEnabled, perDiemCustomUnit?.customUnitID); + enablePerDiem(policyID, isEnabled, perDiemCustomUnit?.customUnitID); }, }); } @@ -178,7 +191,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Policy.enablePolicyWorkflows(policyID, isEnabled); + enablePolicyWorkflows(policyID, isEnabled); }, }, { @@ -196,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; } - Policy.enablePolicyRules(policyID, isEnabled); + enablePolicyRules(policyID, isEnabled); }, }, ]; @@ -212,7 +225,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Policy.enablePolicyInvoicing(policyID, isEnabled); + enablePolicyInvoicing(policyID, isEnabled); }, }, ]; @@ -230,7 +243,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Category.enablePolicyCategories(policyID, isEnabled); + enablePolicyCategories(policyID, isEnabled); }, }, { @@ -245,7 +258,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Tag.enablePolicyTags(policyID, isEnabled); + enablePolicyTags(policyID, isEnabled); }, }, { @@ -260,7 +273,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Policy.enablePolicyTaxes(policyID, isEnabled); + enablePolicyTaxes(policyID, isEnabled); }, }, { @@ -283,7 +296,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro return; } - Policy.enablePolicyReportFields(policyID, true); + enablePolicyReportFields(policyID, true); return; } setIsReportFieldsWarningModalOpen(true); @@ -308,15 +321,15 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro if (!policyID) { return; } - Policy.enablePolicyConnections(policyID, isEnabled); + enablePolicyConnections(policyID, isEnabled); }, disabled: hasAccountingConnection, - errors: ErrorUtils.getLatestErrorField(policy ?? {}, CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED), + errors: getLatestErrorField(policy ?? {}, CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED), onCloseError: () => { if (!policyID) { return; } - Policy.clearPolicyErrorField(policyID, CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED); + clearPolicyErrorField(policyID, CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED); }, }, ]; @@ -327,6 +340,16 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro subtitleTranslationKey: 'workspace.moreFeatures.spendSection.subtitle', items: spendItems, }, + { + titleTranslationKey: 'workspace.moreFeatures.integrateSection.title', + subtitleTranslationKey: 'workspace.moreFeatures.integrateSection.subtitle', + items: integrateItems, + }, + { + titleTranslationKey: 'workspace.moreFeatures.organizeSection.title', + subtitleTranslationKey: 'workspace.moreFeatures.organizeSection.subtitle', + items: organizeItems, + }, { titleTranslationKey: 'workspace.moreFeatures.manageSection.title', subtitleTranslationKey: 'workspace.moreFeatures.manageSection.subtitle', @@ -337,23 +360,13 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro subtitleTranslationKey: 'workspace.moreFeatures.earnSection.subtitle', items: earnItems, }, - { - titleTranslationKey: 'workspace.moreFeatures.organizeSection.title', - subtitleTranslationKey: 'workspace.moreFeatures.organizeSection.subtitle', - items: organizeItems, - }, - { - titleTranslationKey: 'workspace.moreFeatures.integrateSection.title', - subtitleTranslationKey: 'workspace.moreFeatures.integrateSection.subtitle', - items: integrateItems, - }, ]; const renderItem = useCallback( (item: Item) => ( ), - [styles, translate], + [styles, stylesutils, shouldUseNarrowLayout, translate], + ); + + /** Used to fill row space in the Section items when there are odd number of items to create equal margins for last odd item. */ + const sectionRowFillerItem = useCallback( + (section: SectionObject) => { + if (section.items.length % 2 === 0) { + return null; + } + + return ( + + ); + }, + [styles, stylesutils, shouldUseNarrowLayout], ); const renderSection = useCallback( (section: SectionObject) => (
{translate(section.titleTranslationKey)}} subtitleMuted > {section.items.map(renderItem)} + {sectionRowFillerItem(section)}
), - [shouldUseNarrowLayout, styles, renderItem, translate], + [shouldUseNarrowLayout, styles, renderItem, translate, sectionRowFillerItem], ); const fetchFeatures = useCallback(() => { - Policy.openPolicyMoreFeaturesPage(route.params.policyID); + openPolicyMoreFeaturesPage(route.params.policyID); }, [route.params.policyID]); useNetwork({onReconnect: fetchFeatures}); @@ -426,9 +465,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro /> - - {translate('workspace.moreFeatures.subtitle')} - + {translate('workspace.moreFeatures.subtitle')} {sections.map(renderSection)} @@ -470,7 +507,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro return; } setIsReportFieldsWarningModalOpen(false); - Policy.enablePolicyReportFields(policyID, false); + enablePolicyReportFields(policyID, false); }} onCancel={() => setIsReportFieldsWarningModalOpen(false)} prompt={translate('workspace.reportFields.disableReportFieldsConfirmation')} @@ -483,7 +520,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro isVisible={isDisableExpensifyCardWarningModalOpen} onConfirm={() => { setIsDisableExpensifyCardWarningModalOpen(false); - Report.navigateToConciergeChat(true); + navigateToConciergeChat(true); }} onCancel={() => setIsDisableExpensifyCardWarningModalOpen(false)} prompt={translate('workspace.moreFeatures.expensifyCard.disableCardPrompt')} @@ -495,7 +532,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro isVisible={isDisableCompanyCardsWarningModalOpen} onConfirm={() => { setIsDisableCompanyCardsWarningModalOpen(false); - Report.navigateToConciergeChat(true); + navigateToConciergeChat(true); }} onCancel={() => setIsDisableCompanyCardsWarningModalOpen(false)} prompt={translate('workspace.moreFeatures.companyCards.disableCardPrompt')} diff --git a/src/styles/index.ts b/src/styles/index.ts index dbae34f440af..85aae20a18a2 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4918,6 +4918,19 @@ const styles = (theme: ThemeColors) => alignSelf: 'center', }, + workspaceSectionMoreFeaturesItem: { + backgroundColor: theme.cardBG, + borderRadius: variables.componentBorderRadiusNormal, + paddingHorizontal: 16, + paddingVertical: 20, + minWidth: 350, + flexGrow: 1, + flexShrink: 1, + // Choosing a lowest value just above the threshold for the items to adjust width against the various screens. Only 2 items are shown 35 * 2 = 70 thus third item of 35% width can't fit forcing a two column layout. + flexBasis: '35%', + marginTop: 12, + }, + aspectRatioLottie: (animation: DotLottieAnimation) => ({aspectRatio: animation.w / animation.h}), receiptDropHeaderGap: { diff --git a/src/styles/utils/flex.ts b/src/styles/utils/flex.ts index 4db09f138535..f5df6eef8739 100644 --- a/src/styles/utils/flex.ts +++ b/src/styles/utils/flex.ts @@ -137,6 +137,10 @@ export default { flexBasis: 'auto', }, + flexBasis100: { + flexBasis: '100%', + }, + flexBasis0: { flexBasis: 0, }, diff --git a/src/styles/utils/spacing.ts b/src/styles/utils/spacing.ts index fd0a3a3cabc7..894542fcae0c 100644 --- a/src/styles/utils/spacing.ts +++ b/src/styles/utils/spacing.ts @@ -717,6 +717,10 @@ export default { rowGap: 16, }, + columnGap3: { + columnGap: 12, + }, + minHeight5: { minHeight: 20, },