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:
martmull
2024-03-12 18:10:27 +01:00
committed by GitHub
parent 4476f5215b
commit 62d414ee66
23 changed files with 292 additions and 247 deletions

View File

@ -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',
);
});
});

View File

@ -11,6 +11,7 @@ export type CurrentWorkspace = Pick<
| 'featureFlags'
| 'subscriptionStatus'
| 'activationStatus'
| 'currentBillingSubscription'
>;
export const currentWorkspaceState = createState<CurrentWorkspace | null>({

View File

@ -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;
};

View File

@ -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}

View File

@ -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]);

View File

@ -35,6 +35,9 @@ export const GET_CURRENT_USER = gql`
value
workspaceId
}
currentBillingSubscription {
status
}
}
workspaces {
workspace {

View File

@ -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';