Skip to content

Commit

Permalink
Merge pull request #55556 from parasharrajat/parasharrajat/MoreFeatur…
Browse files Browse the repository at this point in the history
…esView

Change design of WorkspaceMoreFeaturePage sections.
  • Loading branch information
carlosmiceli authored Jan 22, 2025
2 parents f8f54cf + a90e931 commit 9018751
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 48 deletions.
133 changes: 85 additions & 48 deletions src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -103,7 +116,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
DistanceRate.enablePolicyDistanceRates(policyID, isEnabled);
enablePolicyDistanceRates(policyID, isEnabled);
},
},
{
Expand All @@ -117,7 +130,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
Policy.enableExpensifyCard(policyID, isEnabled);
enableExpensifyCard(policyID, isEnabled);
},
disabledAction: () => {
setIsDisableExpensifyCardWarningModalOpen(true);
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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);
},
});
}
Expand All @@ -178,7 +191,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
Policy.enablePolicyWorkflows(policyID, isEnabled);
enablePolicyWorkflows(policyID, isEnabled);
},
},
{
Expand All @@ -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);
},
},
];
Expand All @@ -212,7 +225,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
Policy.enablePolicyInvoicing(policyID, isEnabled);
enablePolicyInvoicing(policyID, isEnabled);
},
},
];
Expand All @@ -230,7 +243,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
Category.enablePolicyCategories(policyID, isEnabled);
enablePolicyCategories(policyID, isEnabled);
},
},
{
Expand All @@ -245,7 +258,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
Tag.enablePolicyTags(policyID, isEnabled);
enablePolicyTags(policyID, isEnabled);
},
},
{
Expand All @@ -260,7 +273,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
if (!policyID) {
return;
}
Policy.enablePolicyTaxes(policyID, isEnabled);
enablePolicyTaxes(policyID, isEnabled);
},
},
{
Expand All @@ -283,7 +296,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
return;
}

Policy.enablePolicyReportFields(policyID, true);
enablePolicyReportFields(policyID, true);
return;
}
setIsReportFieldsWarningModalOpen(true);
Expand All @@ -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);
},
},
];
Expand All @@ -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',
Expand All @@ -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) => (
<View
key={item.titleTranslationKey}
style={styles.mt7}
style={[styles.workspaceSectionMoreFeaturesItem, shouldUseNarrowLayout && styles.flexBasis100, shouldUseNarrowLayout && stylesutils.getMinimumWidth(0)]}
>
<ToggleSettingOptionRow
icon={item.icon}
Expand All @@ -372,31 +385,57 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
/>
</View>
),
[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 (
<View
key="section-filler-col"
aria-hidden
accessibilityElementsHidden
style={[
styles.workspaceSectionMoreFeaturesItem,
shouldUseNarrowLayout && stylesutils.getMinimumWidth(0),
styles.p0,
styles.mt0,
styles.visibilityHidden,
styles.bgTransparent,
]}
/>
);
},
[styles, stylesutils, shouldUseNarrowLayout],
);

const renderSection = useCallback(
(section: SectionObject) => (
<View
key={section.titleTranslationKey}
style={[styles.mt3, shouldUseNarrowLayout ? styles.workspaceSectionMobile : styles.workspaceSection]}
style={[styles.mt3, shouldUseNarrowLayout ? styles.workspaceSectionMobile : {}]}
>
<Section
containerStyles={shouldUseNarrowLayout ? styles.p5 : styles.p8}
title={translate(section.titleTranslationKey)}
titleStyles={styles.textStrong}
subtitle={translate(section.subtitleTranslationKey)}
containerStyles={[styles.ph1, styles.pv0, styles.bgTransparent, styles.noBorderRadius]}
childrenStyles={[styles.flexRow, styles.flexWrap, styles.columnGap3]}
renderTitle={() => <Text style={styles.mutedNormalTextLabel}>{translate(section.titleTranslationKey)}</Text>}
subtitleMuted
>
{section.items.map(renderItem)}
{sectionRowFillerItem(section)}
</Section>
</View>
),
[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});
Expand Down Expand Up @@ -426,9 +465,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
/>

<ScrollView contentContainerStyle={safeAreaPaddingBottomStyle}>
<Text style={[styles.ph5, styles.mb4, styles.mt3, styles.textSupporting, shouldUseNarrowLayout ? styles.workspaceSectionMobile : styles.workspaceSection]}>
{translate('workspace.moreFeatures.subtitle')}
</Text>
<Text style={[styles.ph5, styles.mb5, styles.mt3, styles.textSupporting, styles.workspaceSectionMobile]}>{translate('workspace.moreFeatures.subtitle')}</Text>
{sections.map(renderSection)}
</ScrollView>

Expand Down Expand Up @@ -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')}
Expand All @@ -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')}
Expand All @@ -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')}
Expand Down
13 changes: 13 additions & 0 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
4 changes: 4 additions & 0 deletions src/styles/utils/flex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ export default {
flexBasis: 'auto',
},

flexBasis100: {
flexBasis: '100%',
},

flexBasis0: {
flexBasis: 0,
},
Expand Down
4 changes: 4 additions & 0 deletions src/styles/utils/spacing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,10 @@ export default {
rowGap: 16,
},

columnGap3: {
columnGap: 12,
},

minHeight5: {
minHeight: 20,
},
Expand Down

0 comments on commit 9018751

Please sign in to comment.