Skip to content

Commit

Permalink
Merge pull request Expensify#45131 from allroundexperts/feat-43908
Browse files Browse the repository at this point in the history
feat: add upgrade screen to more features
  • Loading branch information
yuwenmemon authored Jul 17, 2024
2 parents da6c35b + 03863a6 commit c82183b
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 47 deletions.
57 changes: 44 additions & 13 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5308,24 +5308,55 @@ const CONST = {
},

EXCLUDE_FROM_LAST_VISITED_PATH: [SCREENS.NOT_FOUND, SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN] as string[],

EMPTY_STATE_MEDIA: {
ANIMATION: 'animation',
ILLUSTRATION: 'illustration',
VIDEO: 'video',
},

UPGRADE_FEATURE_INTRO_MAPPING: [
{
id: 'reportFields',
alias: 'report-fields',
name: 'Report Fields',
title: 'workspace.upgrade.reportFields.title',
description: 'workspace.upgrade.reportFields.description',
icon: 'Pencil',
},
],

get UPGRADE_FEATURE_INTRO_MAPPING() {
return {
reportFields: {
id: 'reportFields' as const,
alias: 'report-fields',
name: 'Report Fields',
title: 'workspace.upgrade.reportFields.title' as const,
description: 'workspace.upgrade.reportFields.description' as const,
icon: 'Pencil',
},
[this.POLICY.CONNECTIONS.NAME.NETSUITE]: {
id: this.POLICY.CONNECTIONS.NAME.NETSUITE,
alias: 'netsuite',
name: this.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.netsuite,
title: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.NETSUITE}.title` as const,
description: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.NETSUITE}.description` as const,
icon: 'NetSuiteSquare',
},
[this.POLICY.CONNECTIONS.NAME.SAGE_INTACCT]: {
id: this.POLICY.CONNECTIONS.NAME.SAGE_INTACCT,
alias: 'sage-intacct',
name: this.POLICY.CONNECTIONS.NAME_USER_FRIENDLY.intacct,
title: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.SAGE_INTACCT}.title` as const,
description: `workspace.upgrade.${this.POLICY.CONNECTIONS.NAME.SAGE_INTACCT}.description` as const,
icon: 'IntacctSquare',
},
glCodes: {
id: 'glCodes' as const,
alias: 'gl-codes',
name: 'GL codes',
title: 'workspace.upgrade.glCodes.title' as const,
description: 'workspace.upgrade.glCodes.description' as const,
icon: 'Tag',
},
glAndPayrollCodes: {
id: 'glAndPayrollCodes' as const,
alias: 'gl-and-payroll-codes',
name: 'GL & Payroll codes',
title: 'workspace.upgrade.glAndPayrollCodes.title' as const,
description: 'workspace.upgrade.glAndPayrollCodes.description' as const,
icon: 'FolderOpen',
},
};
},
REPORT_FIELD_TYPES: {
TEXT: 'text',
DATE: 'date',
Expand Down
3 changes: 2 additions & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,8 @@ const ROUTES = {
},
WORKSPACE_UPGRADE: {
route: 'settings/workspaces/:policyID/upgrade/:featureName',
getRoute: (policyID: string, featureName: string) => `settings/workspaces/${policyID}/upgrade/${encodeURIComponent(featureName)}` as const,
getRoute: (policyID: string, featureName: string, backTo?: string) =>
getUrlWithBackToParam(`settings/workspaces/${policyID}/upgrade/${encodeURIComponent(featureName)}` as const, backTo),
},
WORKSPACE_CATEGORIES_SETTINGS: {
route: 'settings/workspaces/:policyID/categories/settings',
Expand Down
9 changes: 9 additions & 0 deletions src/components/ConnectToNetSuiteButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useRef, useState} from 'react';
import type {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import AccountingConnectionConfirmationModal from '@components/AccountingConnectionConfirmationModal';
import Button from '@components/Button';
import * as Expensicons from '@components/Icon/Expensicons';
Expand All @@ -11,15 +12,18 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import {removePolicyConnection} from '@libs/actions/connections';
import {getAdminPoliciesConnectedToNetSuite} from '@libs/actions/Policy/Policy';
import Navigation from '@libs/Navigation/Navigation';
import {isControlPolicy} from '@libs/PolicyUtils';
import type {AnchorPosition} from '@styles/index';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {ConnectToNetSuiteButtonProps} from './types';

function ConnectToNetSuiteButton({policyID, shouldDisconnectIntegrationBeforeConnecting, integrationToDisconnect}: ConnectToNetSuiteButtonProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isOffline} = useNetwork();
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);

const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false);

Expand Down Expand Up @@ -51,6 +55,11 @@ function ConnectToNetSuiteButton({policyID, shouldDisconnectIntegrationBeforeCon
<>
<Button
onPress={() => {
if (!isControlPolicy(policy)) {
Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.netsuite.alias));
return;
}

if (shouldDisconnectIntegrationBeforeConnecting && integrationToDisconnect) {
setIsDisconnectModalOpen(true);
return;
Expand Down
10 changes: 10 additions & 0 deletions src/components/ConnectToSageIntacctButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useRef, useState} from 'react';
import type {View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import AccountingConnectionConfirmationModal from '@components/AccountingConnectionConfirmationModal';
import Button from '@components/Button';
import * as Expensicons from '@components/Icon/Expensicons';
Expand All @@ -11,8 +12,10 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import {removePolicyConnection} from '@libs/actions/connections';
import {getAdminPoliciesConnectedToSageIntacct} from '@libs/actions/Policy/Policy';
import Navigation from '@libs/Navigation/Navigation';
import {isControlPolicy} from '@libs/PolicyUtils';
import type {AnchorPosition} from '@styles/index';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {PolicyConnectionName} from '@src/types/onyx/Policy';

Expand All @@ -27,6 +30,8 @@ function ConnectToSageIntacctButton({policyID, shouldDisconnectIntegrationBefore
const {translate} = useLocalize();
const {isOffline} = useNetwork();

const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);

const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false);

const hasPoliciesConnectedToSageIntacct = !!getAdminPoliciesConnectedToSageIntacct().length;
Expand Down Expand Up @@ -57,6 +62,11 @@ function ConnectToSageIntacctButton({policyID, shouldDisconnectIntegrationBefore
<>
<Button
onPress={() => {
if (!isControlPolicy(policy)) {
Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.intacct.alias));
return;
}

if (shouldDisconnectIntegrationBeforeConnecting && integrationToDisconnect) {
setIsDisconnectModalOpen(true);
return;
Expand Down
30 changes: 25 additions & 5 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3348,11 +3348,31 @@ export default {
reportFields: {
title: 'Report fields',
description: `Report fields let you specify header-level details, distinct from tags that pertain to expenses on individual line items. These details can encompass specific project names, business trip information, locations, and more.`,
pricing: {
onlyAvailableOnPlan: 'Report fields are only available on the Control plan, starting at ',
amount: '$9 ',
perActiveMember: 'per active member per month.',
},
onlyAvailableOnPlan: 'Report fields are only available on the Control plan, starting at ',
},
[CONST.POLICY.CONNECTIONS.NAME.NETSUITE]: {
title: 'NetSuite',
description: `Enjoy automated syncing and reduce manual entries with the Expensify + NetSuite integration. Gain in-depth, realtime financial insights with native and custom segment support, including project and customer mapping.`,
onlyAvailableOnPlan: 'Our NetSuite integration is only available on the Control plan, starting at ',
},
[CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT]: {
title: 'Sage Intacct',
description: `Enjoy automated syncing and reduce manual entries with the Expensify + Sage Intacct integration. Gain in-depth, real-time financial insights with user-defined dimensions, as well as expense coding by department, class, location, customer, and project (job).`,
onlyAvailableOnPlan: 'Our Sage Intacct integration is only available on the Control plan, starting at ',
},
glCodes: {
title: 'GL codes',
description: `Add GL codes to your categories and tags for easy export of expenses to your accounting and payroll systems.`,
onlyAvailableOnPlan: 'GL codes are only available on the Control plan, starting at ',
},
glAndPayrollCodes: {
title: 'GL & Payroll codes',
description: `Add GL & Payroll codes to your categories for easy export of expenses to your accounting and payroll systems.`,
onlyAvailableOnPlan: 'GL & Payroll codes are only available on the Control plan, starting at ',
},
pricing: {
amount: '$9 ',
perActiveMember: 'per active member per month.',
},
note: {
upgradeWorkspace: 'Upgrade your workspace to access this feature, or',
Expand Down
30 changes: 25 additions & 5 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3402,17 +3402,37 @@ export default {
reportFields: {
title: 'Los campos',
description: `Los campos de informe permiten especificar detalles a nivel de cabecera, distintos de las etiquetas que pertenecen a los gastos en partidas individuales. Estos detalles pueden incluir nombres de proyectos específicos, información sobre viajes de negocios, ubicaciones, etc.`,
pricing: {
onlyAvailableOnPlan: 'Los campos de informe sólo están disponibles en el plan Control, a partir de ',
amount: '$9 ',
perActiveMember: 'por miembro activo al mes.',
},
onlyAvailableOnPlan: 'Los campos de informe sólo están disponibles en el plan Control, a partir de ',
},
[CONST.POLICY.CONNECTIONS.NAME.NETSUITE]: {
title: 'NetSuite',
description: `Disfruta de la sincronización automática y reduce las entradas manuales con la integración Expensify + NetSuite. Obtén información financiera en profundidad y en tiempo real con la compatibilidad nativa y personalizada con segmentos, incluida la asignación de proyectos y clientes.`,
onlyAvailableOnPlan: 'Nuestra integración NetSuite sólo está disponible en el plan Control, a partir de ',
},
[CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT]: {
title: 'Sage Intacct',
description: `Disfruta de una sincronización automatizada y reduce las entradas manuales con la integración Expensify + Sage Intacct. Obtén información financiera en profundidad y en tiempo real con dimensiones definidas por el usuario, así como codificación de gastos por departamento, clase, ubicación, cliente y proyecto (trabajo).`,
onlyAvailableOnPlan: 'Nuestra integración Sage Intacct sólo está disponible en el plan Control, a partir de ',
},
glCodes: {
title: 'Códigos de libro mayor',
description: `Añada códigos de libro mayor a sus categorías para exportar fácilmente los gastos a sus sistemas de contabilidad y nómina.`,
onlyAvailableOnPlan: 'Los códigos de libro mayor solo están disponibles en el plan Control, a partir de ',
},
glAndPayrollCodes: {
title: 'Códigos de libro mayor y nómina',
description: `Añada códigos de libro mayor y nómina a sus categorías para exportar fácilmente los gastos a sus sistemas de contabilidad y nómina.`,
onlyAvailableOnPlan: 'Los códigos de libro mayor y nómina solo están disponibles en el plan Control, a partir de ',
},
note: {
upgradeWorkspace: 'Mejore su espacio de trabajo para acceder a esta función, o',
learnMore: 'más información',
aboutOurPlans: 'sobre nuestros planes y precios.',
},
pricing: {
amount: '$9 ',
perActiveMember: 'por miembro activo al mes.',
},
upgradeToUnlock: 'Desbloquear esta función',
completed: {
headline: 'Has mejorado tu espacio de trabajo.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,7 @@ import type {FullScreenName} from '@libs/Navigation/types';
import SCREENS from '@src/SCREENS';

const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
[SCREENS.WORKSPACE.PROFILE]: [
SCREENS.WORKSPACE.NAME,
SCREENS.WORKSPACE.ADDRESS,
SCREENS.WORKSPACE.CURRENCY,
SCREENS.WORKSPACE.DESCRIPTION,
SCREENS.WORKSPACE.SHARE,
SCREENS.WORKSPACE.UPGRADE,
],
[SCREENS.WORKSPACE.PROFILE]: [SCREENS.WORKSPACE.NAME, SCREENS.WORKSPACE.ADDRESS, SCREENS.WORKSPACE.CURRENCY, SCREENS.WORKSPACE.DESCRIPTION, SCREENS.WORKSPACE.SHARE],
[SCREENS.WORKSPACE.REIMBURSE]: [SCREENS.WORKSPACE.RATE_AND_UNIT, SCREENS.WORKSPACE.RATE_AND_UNIT_RATE, SCREENS.WORKSPACE.RATE_AND_UNIT_UNIT],
[SCREENS.WORKSPACE.MEMBERS]: [
SCREENS.WORKSPACE.INVITE,
Expand Down
8 changes: 8 additions & 0 deletions src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import type {FullScreenNavigatorParamList} from '@libs/Navigation/types';
import {isControlPolicy} from '@libs/PolicyUtils';
import * as Category from '@userActions/Policy/Category';
import * as DistanceRate from '@userActions/Policy/DistanceRate';
import * as Policy from '@userActions/Policy/Policy';
Expand Down Expand Up @@ -204,6 +205,13 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
return;
}
if (isEnabled) {
if (!isControlPolicy(policy)) {
Navigation.navigate(
ROUTES.WORKSPACE_UPGRADE.getRoute(policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.reportFields.alias, ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)),
);
return;
}

Policy.enablePolicyReportFields(policyID, true);
return;
}
Expand Down
16 changes: 14 additions & 2 deletions src/pages/workspace/categories/CategorySettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,27 @@ function CategorySettingsPage({route, policyCategories, navigation}: CategorySet
<MenuItemWithTopDescription
title={policyCategory['GL Code']}
description={translate(`workspace.categories.glCode`)}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_GL_CODE.getRoute(route.params.policyID, policyCategory.name))}
onPress={() => {
if (!isControlPolicy(policy)) {
Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(route.params.policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.glAndPayrollCodes.alias));
return;
}
Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_GL_CODE.getRoute(route.params.policyID, policyCategory.name));
}}
shouldShowRightIcon
/>
</OfflineWithFeedback>
<OfflineWithFeedback pendingAction={policyCategory.pendingFields?.['Payroll Code']}>
<MenuItemWithTopDescription
title={policyCategory['Payroll Code']}
description={translate(`workspace.categories.payrollCode`)}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_PAYROLL_CODE.getRoute(route.params.policyID, policyCategory.name))}
onPress={() => {
if (!isControlPolicy(policy)) {
Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(route.params.policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.glAndPayrollCodes.alias));
return;
}
Navigation.navigate(ROUTES.WORKSPACE_CATEGORY_PAYROLL_CODE.getRoute(route.params.policyID, policyCategory.name));
}}
shouldShowRightIcon
disabled={shouldDisablePayrollCode}
/>
Expand Down
4 changes: 4 additions & 0 deletions src/pages/workspace/tags/TagSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ function TagSettingsPage({route, policyTags, navigation}: TagSettingsPageProps)
};

const navigateToEditGlCode = () => {
if (!PolicyUtils.isControlPolicy(policy)) {
Navigation.navigate(ROUTES.WORKSPACE_UPGRADE.getRoute(route.params.policyID, CONST.UPGRADE_FEATURE_INTRO_MAPPING.glCodes.alias));
return;
}
Navigation.navigate(ROUTES.WORKSPACE_TAG_GL_CODE.getRoute(route.params.policyID, route.params.orderWeight, currentPolicyTag.name));
};

Expand Down
Loading

0 comments on commit c82183b

Please sign in to comment.