Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new route for profile plan type #52117

Merged
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6a6e6b1
added new route for profile plan type
jayeshmangwani Nov 6, 2024
354e371
merge main and resolved conflicts
jayeshmangwani Nov 8, 2024
fe3d7ad
added plan type and pricing help for URL
jayeshmangwani Nov 8, 2024
aa22a9d
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 10, 2024
a5a0ba0
added selection list for ws plan type selection
jayeshmangwani Nov 11, 2024
6e5a07d
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 11, 2024
cc5de45
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 11, 2024
bfbe6d1
removed unused en.ts key
jayeshmangwani Nov 11, 2024
eb2b373
removed unused es.ts key
jayeshmangwani Nov 11, 2024
fc72d50
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 12, 2024
ca5a6c2
fixed footer button position when offline
jayeshmangwani Nov 12, 2024
60fc866
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 13, 2024
02ba6dc
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 14, 2024
5874d3b
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 14, 2024
a893592
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 14, 2024
3ecbd4a
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 15, 2024
219c274
added locked plan type UI to plan type page
jayeshmangwani Nov 15, 2024
8757f1e
made featureName optional and added a common features UI for the upgr…
jayeshmangwani Nov 18, 2024
6dab121
merge main , resolved conflicts
jayeshmangwani Nov 18, 2024
7b6ec22
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 19, 2024
17241c0
updated common upgrade intro UI styling same as other intro components
jayeshmangwani Nov 19, 2024
6f3909f
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 20, 2024
30da5cb
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 20, 2024
02049cf
fixed lint
jayeshmangwani Nov 20, 2024
580695e
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 20, 2024
49eb7b1
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 21, 2024
3382ec4
updated spanish copy for locked type subscriptions
jayeshmangwani Nov 21, 2024
1066d5d
update en and es translation for benefits learn more
jayeshmangwani Nov 21, 2024
1778c65
Merge branch 'main' into workspace_downgrade_plan_type_page
jayeshmangwani Nov 21, 2024
baf3180
merged main and resolved conflicts
jayeshmangwani Nov 25, 2024
c6f8a99
generic upgrade features moved to a new file and added pending action…
jayeshmangwani Nov 25, 2024
728afd4
merged main and resolved conflicts
jayeshmangwani Nov 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,7 @@ const CONST = {
CONFIGURE_REIMBURSEMENT_SETTINGS_HELP_URL: 'https://help.expensify.com/articles/expensify-classic/workspaces/Configure-Reimbursement-Settings',
COPILOT_HELP_URL: 'https://help.expensify.com/articles/expensify-classic/copilots-and-delegates/Assign-or-remove-a-Copilot',
DELAYED_SUBMISSION_HELP_URL: 'https://help.expensify.com/articles/expensify-classic/reports/Automatically-submit-employee-reports',
PLAN_TYPES_AND_PRICING_HELP_URL: 'https://help.expensify.com/articles/new-expensify/billing-and-subscriptions/Plan-types-and-pricing',
carlosmiceli marked this conversation as resolved.
Show resolved Hide resolved
// Use Environment.getEnvironmentURL to get the complete URL with port number
DEV_NEW_EXPENSIFY_URL: 'https://dev.new.expensify.com:',
NAVATTIC: {
Expand Down
10 changes: 7 additions & 3 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/profile/address',
getRoute: (policyID: string, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/profile/address` as const, backTo),
},
WORKSPACE_PROFILE_PLAN: {
route: 'settings/workspaces/:policyID/profile/plan',
getRoute: (policyID: string, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/profile/plan` as const, backTo),
},
WORKSPACE_ACCOUNTING: {
route: 'settings/workspaces/:policyID/accounting',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting` as const,
Expand Down Expand Up @@ -965,9 +969,9 @@ const ROUTES = {
getRoute: (policyID: string, categoryName: string) => `settings/workspaces/${policyID}/category/${encodeURIComponent(categoryName)}` as const,
},
WORKSPACE_UPGRADE: {
route: 'settings/workspaces/:policyID/upgrade/:featureName',
getRoute: (policyID: string, featureName: string, backTo?: string) =>
getUrlWithBackToParam(`settings/workspaces/${policyID}/upgrade/${encodeURIComponent(featureName)}` as const, backTo),
route: 'settings/workspaces/:policyID/upgrade/:featureName?',
getRoute: (policyID: string, featureName?: string, backTo?: string) =>
getUrlWithBackToParam(`settings/workspaces/${policyID}/upgrade/${encodeURIComponent(featureName ?? '')}` as const, backTo),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using the existing Upgrade page to display the upgrade workspace page when coming from the workspace plan page. Now, we can also navigate from pages that don't have a specific feature.

I've made featureName an optional parameter. If it's not provided, we'll show the common control plan features instead.

},
WORKSPACE_DOWNGRADE: {
route: 'settings/workspaces/:policyID/downgrade/',
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ const SCREENS = {
TAG_GL_CODE: 'Tag_GL_Code',
CURRENCY: 'Workspace_Profile_Currency',
ADDRESS: 'Workspace_Profile_Address',
PLAN: 'Workspace_Profile_Plan_Type',
WORKFLOWS: 'Workspace_Workflows',
WORKFLOWS_PAYER: 'Workspace_Workflows_Payer',
WORKFLOWS_APPROVALS_NEW: 'Workspace_Approvals_New',
Expand Down
32 changes: 32 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ import type {
WelcomeNoteParams,
WelcomeToRoomParams,
WeSentYouMagicSignInLinkParams,
WorkspaceLockedPlanTypeParams,
WorkspaceOwnerWillNeedToAddOrUpdatePaymentCardParams,
YourPlanPriceParams,
ZipCodeExampleFormatParams,
Expand Down Expand Up @@ -2524,6 +2525,7 @@ const translations = {
return 'Member';
}
},
planType: 'Plan type',
defaultCategory: 'Default category',
},
perDiem: {
Expand Down Expand Up @@ -4258,6 +4260,19 @@ const translations = {
moreDetails: 'for more details.',
gotIt: 'Got it, thanks',
},
commonFeatures: {
title: 'Upgrade Workspace to Control',
note: 'Get access to all our most advanced functionality, including:',
benefits: {
note: 'The Control plan starts at $9 per active member per month.',
learnMore: 'Learn more',
pricing: 'about our plans and pricing.',
benefit1: 'Advanced accounting connections (NetSuite, Sage Intacct and more)',
benefit2: 'Expense rules',
benefit3: 'Multiple approval workflows',
benefit4: 'Enhanced security controls',
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carlosmiceli Before merging, I wanted to let you know that these translations are not yet confirmed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, let's keep these comments open so we can go back to them to see what we have yet to change/merge.

},
restrictedAction: {
restricted: 'Restricted',
Expand Down Expand Up @@ -4361,6 +4376,23 @@ const translations = {
andEnableWorkflows: 'and enable workflows, then add approvals to unlock this feature.',
},
},
planTypePage: {
planTypes: {
team: {
label: 'Collect',
description: 'For teams looking to automate their processes.',
},
corporate: {
label: 'Control',
description: 'For organizations with advanced requirements.',
},
},
description: "Choose a plan that's right for you. For a detailed list of features and pricing, check out our",
subscriptionLink: 'plan types and pricing help page',
lockedPlanDescription: ({subscriptionUsersCount, annualSubscriptionEndDate}: WorkspaceLockedPlanTypeParams) =>
`You've committed to ${subscriptionUsersCount} active users on the Control plan until your annual subscription ends on ${annualSubscriptionEndDate}. You can switch to pay-per-use subscription and downgrade to the Collect plan starting ${annualSubscriptionEndDate} by disabling auto-renew in`,
subscriptions: 'Subscriptions',
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we resolve this conversation?

},
getAssistancePage: {
title: 'Get assistance',
Expand Down
32 changes: 32 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ import type {
WelcomeNoteParams,
WelcomeToRoomParams,
WeSentYouMagicSignInLinkParams,
WorkspaceLockedPlanTypeParams,
WorkspaceOwnerWillNeedToAddOrUpdatePaymentCardParams,
YourPlanPriceParams,
ZipCodeExampleFormatParams,
Expand Down Expand Up @@ -2548,6 +2549,7 @@ const translations = {
return 'Miembro';
}
},
planType: 'Tipo de plan',
defaultCategory: 'Categoría predeterminada',
},
perDiem: {
Expand Down Expand Up @@ -4231,6 +4233,23 @@ const translations = {
confirmText: 'Sí, exportar de nuevo',
cancelText: 'Cancelar',
},
planTypePage: {
planTypes: {
team: {
label: 'Collect',
description: 'Para equipos que buscan automatizar sus procesos.',
},
corporate: {
label: 'Recolectar',
description: 'Para organizaciones con requisitos avanzados.',
},
},
description: 'Elige el plan adecuado para ti. Para ver una lista detallada de funciones y precios, consulta nuestra',
subscriptionLink: 'página de ayuda sobre tipos de planes y precios',
lockedPlanDescription: ({subscriptionUsersCount, annualSubscriptionEndDate}: WorkspaceLockedPlanTypeParams) =>
`Tienes un compromiso anual de ${subscriptionUsersCount} miembros activos en el plan Control hasta el ${annualSubscriptionEndDate}. Puedes cambiar a una suscripción de pago por uso y desmejorar al plan Recopilar a partir del ${annualSubscriptionEndDate} desactivando la renovación automática en`,
subscriptions: 'Suscripciones',
},
upgrade: {
reportFields: {
title: 'Los campos',
Expand Down Expand Up @@ -4305,6 +4324,19 @@ const translations = {
moreDetails: 'para obtener más información.',
gotIt: 'Entendido, gracias.',
},
commonFeatures: {
title: 'Actualiza tu espacio de trabajo al plan Controlar',
note: 'Obtén acceso a todas nuestras funciones más avanzadas, incluyendo:',
benefits: {
note: 'El plan Controlar comienza en $9 por miembro activo al mes.',
learnMore: 'Obtén más información',
pricing: 'sobre nuestros planes y precios.',
benefit1: 'Conexiones contables avanzadas (NetSuite, Sage Intacct y más)',
benefit2: 'Reglas de gastos',
benefit3: 'Flujos de aprobación múltiples',
benefit4: 'Controles de seguridad mejorados',
},
},
},
restrictedAction: {
restricted: 'Restringido',
Expand Down
5 changes: 5 additions & 0 deletions src/languages/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,10 @@ type CurrencyCodeParams = {
currencyCode: string;
};

type WorkspaceLockedPlanTypeParams = {
subscriptionUsersCount: number;
annualSubscriptionEndDate: string;
};
type CompanyNameParams = {
companyName: string;
};
Expand Down Expand Up @@ -760,5 +764,6 @@ export type {
AssignCardParams,
ImportedTypesParams,
CurrencyCodeParams,
WorkspaceLockedPlanTypeParams,
CompanyNameParams,
};
2 changes: 1 addition & 1 deletion src/libs/API/parameters/UpgradeToCorporateParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
type UpgradeToCorporateParams = {
policyID: string;
featureName: string;
featureName?: string;
};

export default UpgradeToCorporateParams;
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.CURRENCY]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceProfileCurrencyPage').default,
[SCREENS.WORKSPACE.CATEGORY_SETTINGS]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/CategorySettingsPage').default,
[SCREENS.WORKSPACE.ADDRESS]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceProfileAddressPage').default,
[SCREENS.WORKSPACE.PLAN]: () => require<ReactComponentModule>('../../../../pages/workspace/WorkspaceProfilePlanTypePage').default,
[SCREENS.WORKSPACE.CATEGORIES_SETTINGS]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/WorkspaceCategoriesSettingsPage').default,
[SCREENS.WORKSPACE.CATEGORIES_IMPORT]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/ImportCategoriesPage').default,
[SCREENS.WORKSPACE.CATEGORIES_IMPORTED]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/ImportedCategoriesPage').default,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
[SCREENS.WORKSPACE.PROFILE]: [
SCREENS.WORKSPACE.NAME,
SCREENS.WORKSPACE.ADDRESS,
SCREENS.WORKSPACE.PLAN,
SCREENS.WORKSPACE.CURRENCY,
SCREENS.WORKSPACE.DESCRIPTION,
SCREENS.WORKSPACE.SHARE,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.ADDRESS]: {
path: ROUTES.WORKSPACE_PROFILE_ADDRESS.route,
},
[SCREENS.WORKSPACE.PLAN]: {
path: ROUTES.WORKSPACE_PROFILE_PLAN.route,
},
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_IMPORT]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT.route},
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CHART_OF_ACCOUNTS]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CHART_OF_ACCOUNTS.route},
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CLASSES]: {path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES.route},
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ type SettingsNavigatorParamList = {
};
[SCREENS.WORKSPACE.UPGRADE]: {
policyID: string;
featureName: string;
featureName?: string;
backTo?: Routes;
categoryId?: string;
};
Expand Down
12 changes: 12 additions & 0 deletions src/libs/PolicyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,17 @@ function getActivePolicy(): OnyxEntry<Policy> {
return getPolicy(activePolicyId);
}

function getUserFriendlyWorkspaceType(workspaceType: ValueOf<typeof CONST.POLICY.TYPE>) {
switch (workspaceType) {
case CONST.POLICY.TYPE.CORPORATE:
return Localize.translateLocal('workspace.type.control');
case CONST.POLICY.TYPE.TEAM:
return Localize.translateLocal('workspace.type.collect');
default:
return Localize.translateLocal('workspace.type.free');
}
}

function isPolicyAccessible(policy: OnyxEntry<Policy>): boolean {
return !isEmptyObject(policy) && (Object.keys(policy).length !== 1 || isEmptyObject(policy.errors)) && !!policy?.id;
}
Expand Down Expand Up @@ -1236,6 +1247,7 @@ export {
getNetSuiteImportCustomFieldLabel,
getAllPoliciesLength,
getActivePolicy,
getUserFriendlyWorkspaceType,
isPolicyAccessible,
areAllGroupPoliciesExpenseChatDisabled,
};
Expand Down
6 changes: 4 additions & 2 deletions src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1663,6 +1663,7 @@ function buildPolicyData(policyOwnerEmail = '', makeMeAdmin = false, policyName
outputCurrency: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
address: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
description: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
type: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
},
},
},
Expand Down Expand Up @@ -1735,6 +1736,7 @@ function buildPolicyData(policyOwnerEmail = '', makeMeAdmin = false, policyName
outputCurrency: null,
address: null,
description: null,
type: null,
},
},
},
Expand Down Expand Up @@ -3322,7 +3324,7 @@ function setForeignCurrencyDefault(policyID: string, taxCode: string) {
API.write(WRITE_COMMANDS.SET_POLICY_TAXES_FOREIGN_CURRENCY_DEFAULT, parameters, onyxData);
}

function upgradeToCorporate(policyID: string, featureName: string) {
function upgradeToCorporate(policyID: string, featureName?: string) {
const policy = getPolicy(policyID);
const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -3374,7 +3376,7 @@ function upgradeToCorporate(policyID: string, featureName: string) {
},
];

const parameters: UpgradeToCorporateParams = {policyID, featureName};
const parameters: UpgradeToCorporateParams = {policyID, ...(featureName ? {featureName} : {})};

API.write(WRITE_COMMANDS.UPGRADE_TO_CORPORATE, parameters, {optimisticData, successData, failureData});
}
Expand Down
17 changes: 17 additions & 0 deletions src/pages/workspace/WorkspaceProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
const onPressName = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE_NAME.getRoute(policy?.id ?? '-1')), [policy?.id]);
const onPressDescription = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE_DESCRIPTION.getRoute(policy?.id ?? '-1')), [policy?.id]);
const onPressShare = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE_SHARE.getRoute(policy?.id ?? '-1')), [policy?.id]);
const onPressPlanType = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_PROFILE_PLAN.getRoute(policy?.id ?? '-1')), [policy?.id]);

const policyName = policy?.name ?? '';
const policyDescription =
Expand Down Expand Up @@ -266,6 +267,22 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
</View>
</OfflineWithFeedback>
)}
{!readOnly && !!policy?.type && (
<OfflineWithFeedback pendingAction={policy?.pendingFields?.type}>
<View>
<MenuItemWithTopDescription
title={PolicyUtils.getUserFriendlyWorkspaceType(policy.type)}
description={translate('workspace.common.planType')}
shouldShowRightIcon={!readOnly}
disabled={readOnly}
wrapperStyle={styles.sectionMenuItemTopDescription}
onPress={onPressPlanType}
shouldGreyOutWhenDisabled={false}
shouldUseDefaultCursorWhenDisabled
/>
</View>
</OfflineWithFeedback>
)}
{!readOnly && (
<View style={[styles.flexRow, styles.mt6, styles.mnw120]}>
<Button
Expand Down
Loading
Loading