40 remove self billing feature flag (#4379)
* Define quantity at checkout * Remove billing submenu when not isBillingEnabled * Remove feature flag * Log warning when missing subscription active workspace add or remove member * Display subscribe cta for free usage of twenty * Authorize all settings when subscription canceled or unpaid * Display subscribe cta for workspace with canceled subscription * Replace OneToOne by OneToMany * Add a currentBillingSubscriptionField * Handle multiple subscriptions by workspace * Fix redirection * Fix test * Fix billingState
This commit is contained in:
@ -21,6 +21,9 @@ const currentWorkspace = {
|
||||
activationStatus: 'active',
|
||||
id: '1',
|
||||
allowImpersonation: true,
|
||||
currentBillingSubscription: {
|
||||
status: 'trialing',
|
||||
},
|
||||
};
|
||||
const currentWorkspaceMember = {
|
||||
id: '1',
|
||||
@ -240,4 +243,35 @@ describe('useOnboardingStatus', () => {
|
||||
|
||||
expect(result.current.onboardingStatus).toBe('unpaid');
|
||||
});
|
||||
|
||||
it('should return "completed_without_subscription"', async () => {
|
||||
const { result } = renderHooks();
|
||||
const {
|
||||
setTokenPair,
|
||||
setBilling,
|
||||
setCurrentWorkspace,
|
||||
setCurrentWorkspaceMember,
|
||||
} = result.current;
|
||||
|
||||
act(() => {
|
||||
setTokenPair(tokenPair);
|
||||
setBilling(billing);
|
||||
setCurrentWorkspace({
|
||||
...currentWorkspace,
|
||||
subscriptionStatus: 'trialing',
|
||||
currentBillingSubscription: null,
|
||||
});
|
||||
setCurrentWorkspaceMember({
|
||||
...currentWorkspaceMember,
|
||||
name: {
|
||||
firstName: 'John',
|
||||
lastName: 'Doe',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
expect(result.current.onboardingStatus).toBe(
|
||||
'completed_without_subscription',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,6 +11,7 @@ export type CurrentWorkspace = Pick<
|
||||
| 'featureFlags'
|
||||
| 'subscriptionStatus'
|
||||
| 'activationStatus'
|
||||
| 'currentBillingSubscription'
|
||||
>;
|
||||
|
||||
export const currentWorkspaceState = createState<CurrentWorkspace | null>({
|
||||
|
||||
@ -10,6 +10,7 @@ export enum OnboardingStatus {
|
||||
OngoingWorkspaceActivation = 'ongoing_workspace_activation',
|
||||
OngoingProfileCreation = 'ongoing_profile_creation',
|
||||
Completed = 'completed',
|
||||
CompletedWithoutSubscription = 'completed_without_subscription',
|
||||
}
|
||||
|
||||
export const getOnboardingStatus = ({
|
||||
@ -75,5 +76,12 @@ export const getOnboardingStatus = ({
|
||||
return OnboardingStatus.Unpaid;
|
||||
}
|
||||
|
||||
if (
|
||||
isBillingEnabled === true &&
|
||||
!currentWorkspace.currentBillingSubscription
|
||||
) {
|
||||
return OnboardingStatus.CompletedWithoutSubscription;
|
||||
}
|
||||
|
||||
return OnboardingStatus.Completed;
|
||||
};
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { billingState } from '@/client-config/states/billingState.ts';
|
||||
import { SettingsNavigationDrawerItem } from '@/settings/components/SettingsNavigationDrawerItem';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
@ -35,7 +37,7 @@ export const SettingsNavigationDrawerItems = () => {
|
||||
}, [signOut, navigate]);
|
||||
|
||||
const isCalendarEnabled = useIsFeatureEnabled('IS_CALENDAR_ENABLED');
|
||||
const isSelfBillingEnabled = useIsFeatureEnabled('IS_SELF_BILLING_ENABLED');
|
||||
const billing = useRecoilValue(billingState());
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -88,12 +90,13 @@ export const SettingsNavigationDrawerItems = () => {
|
||||
path={SettingsPath.WorkspaceMembersPage}
|
||||
Icon={IconUsers}
|
||||
/>
|
||||
<SettingsNavigationDrawerItem
|
||||
label="Billing"
|
||||
path={SettingsPath.Billing}
|
||||
Icon={IconCurrencyDollar}
|
||||
soon={!isSelfBillingEnabled}
|
||||
/>
|
||||
{billing?.isBillingEnabled && (
|
||||
<SettingsNavigationDrawerItem
|
||||
label="Billing"
|
||||
path={SettingsPath.Billing}
|
||||
Icon={IconCurrencyDollar}
|
||||
/>
|
||||
)}
|
||||
<SettingsNavigationDrawerItem
|
||||
label="Data model"
|
||||
path={SettingsPath.Objects}
|
||||
|
||||
@ -83,7 +83,10 @@ export const DefaultLayout = ({ children }: DefaultLayoutProps) => {
|
||||
OnboardingStatus.OngoingProfileCreation,
|
||||
OnboardingStatus.OngoingWorkspaceActivation,
|
||||
].includes(onboardingStatus)) ||
|
||||
isMatchingLocation(AppPath.ResetPassword)
|
||||
isMatchingLocation(AppPath.ResetPassword) ||
|
||||
(isMatchingLocation(AppPath.PlanRequired) &&
|
||||
(OnboardingStatus.CompletedWithoutSubscription ||
|
||||
OnboardingStatus.Canceled))
|
||||
);
|
||||
}, [isMatchingLocation, onboardingStatus]);
|
||||
|
||||
|
||||
@ -35,6 +35,9 @@ export const GET_CURRENT_USER = gql`
|
||||
value
|
||||
workspaceId
|
||||
}
|
||||
currentBillingSubscription {
|
||||
status
|
||||
}
|
||||
}
|
||||
workspaces {
|
||||
workspace {
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
export type FeatureFlagKey =
|
||||
| 'IS_BLOCKLIST_ENABLED'
|
||||
| 'IS_CALENDAR_ENABLED'
|
||||
| 'IS_QUICK_ACTIONS_ENABLED'
|
||||
| 'IS_SELF_BILLING_ENABLED';
|
||||
| 'IS_QUICK_ACTIONS_ENABLED';
|
||||
|
||||
Reference in New Issue
Block a user