Treat suspended workspace as workspaces that need to be synced (#9669)

In this PR:
- migrate WorkspaceActivationStatus to twenty-shared (and update case to
make FE and BE consistent)
- introduce isWorkspaceActiveOrSuspended in twenty-shared
- refactor the code to use it (when we fetch data on the FE, we want to
keep SUSPENDED workspace working + when we sync workspaces we want it
too)
This commit is contained in:
Charles Bochet
2025-01-16 15:01:04 +01:00
committed by GitHub
parent 4a0b89d094
commit f545bd1c40
41 changed files with 200 additions and 167 deletions

View File

@ -1784,11 +1784,11 @@ export type WorkspaceBillingSubscriptionsArgs = {
};
export enum WorkspaceActivationStatus {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
OngoingCreation = 'ONGOING_CREATION',
PendingCreation = 'PENDING_CREATION',
Suspended = 'SUSPENDED'
ACTIVE = 'ACTIVE',
INACTIVE = 'INACTIVE',
ONGOING_CREATION = 'ONGOING_CREATION',
PENDING_CREATION = 'PENDING_CREATION',
SUSPENDED = 'SUSPENDED'
}
export type WorkspaceEdge = {

View File

@ -1556,11 +1556,11 @@ export type WorkspaceBillingSubscriptionsArgs = {
};
export enum WorkspaceActivationStatus {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
OngoingCreation = 'ONGOING_CREATION',
PendingCreation = 'PENDING_CREATION',
Suspended = 'SUSPENDED'
ACTIVE = 'ACTIVE',
INACTIVE = 'INACTIVE',
ONGOING_CREATION = 'ONGOING_CREATION',
PENDING_CREATION = 'PENDING_CREATION',
SUSPENDED = 'SUSPENDED'
}
export type WorkspaceEdge = {

View File

@ -85,6 +85,15 @@ const testCases = [
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.InviteTeam, res: undefined },
{ loc: AppPath.ResetPassword, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.Completed, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PlanRequired, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.Completed, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.WorkspaceActivation, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.ProfileCreation, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.SyncEmail, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.InviteTeam, res: undefined },
{ loc: AppPath.VerifyEmail, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.Completed, res: undefined },
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: false, onboardingStatus: OnboardingStatus.PlanRequired, res: AppPath.PlanRequired },
{ loc: AppPath.CreateWorkspace, isLoggedIn: true, isWorkspaceSuspended: true, onboardingStatus: OnboardingStatus.Completed, res: '/settings/billing' },
{ loc: AppPath.CreateWorkspace, isLoggedIn: false, isWorkspaceSuspended: false, onboardingStatus: undefined, res: AppPath.SignInUp },

View File

@ -1,7 +1,7 @@
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
import {
BillingPlanKey,
SubscriptionInterval,
BillingPlanKey,
SubscriptionInterval,
} from '~/generated-metadata/graphql';
export const BILLING_CHECKOUT_SESSION_DEFAULT_VALUE: BillingCheckoutSession = {

View File

@ -5,7 +5,7 @@ import { currentUserState } from '@/auth/states/currentUserState';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useLoadMockedObjectMetadataItems } from '@/object-metadata/hooks/useLoadMockedObjectMetadataItems';
import { useRefreshObjectMetadataItems } from '@/object-metadata/hooks/useRefreshObjectMetadataItem';
import { WorkspaceActivationStatus } from '~/generated/graphql';
import { isWorkspaceActiveOrSuspended } from 'twenty-shared';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const ObjectMetadataItemsLoadEffect = () => {
@ -18,7 +18,7 @@ export const ObjectMetadataItemsLoadEffect = () => {
useEffect(() => {
if (
isUndefinedOrNull(currentUser) ||
currentWorkspace?.activationStatus !== WorkspaceActivationStatus.Active
!isWorkspaceActiveOrSuspended(currentWorkspace)
) {
loadMockedObjectMetadataItems();
} else {
@ -26,7 +26,7 @@ export const ObjectMetadataItemsLoadEffect = () => {
}
}, [
currentUser,
currentWorkspace?.activationStatus,
currentWorkspace,
loadMockedObjectMetadataItems,
refreshObjectMetadataItems,
]);

View File

@ -16,7 +16,7 @@ const Wrapper = getJestMetadataAndApolloMocksWrapper({
featureFlags: [],
allowImpersonation: false,
subdomain: 'test',
activationStatus: WorkspaceActivationStatus.Active,
activationStatus: WorkspaceActivationStatus.ACTIVE,
hasValidEntrepriseKey: false,
metadataVersion: 1,
isPublicInviteLinkEnabled: false,

View File

@ -2,7 +2,7 @@ import { useRecoilValue } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
import { WorkspaceActivationStatus } from '~/generated/graphql';
import { isWorkspaceActiveOrSuspended } from 'twenty-shared';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { isDefined } from '~/utils/isDefined';
@ -20,7 +20,7 @@ export const useObjectNamePluralFromSingular = ({
}),
);
if (currentWorkspace?.activationStatus !== WorkspaceActivationStatus.Active) {
if (!isWorkspaceActiveOrSuspended(currentWorkspace)) {
objectMetadataItem =
generatedMockObjectMetadataItems.find(
(objectMetadataItem) =>

View File

@ -2,7 +2,7 @@ import { useRecoilValue } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
import { WorkspaceActivationStatus } from '~/generated/graphql';
import { isWorkspaceActiveOrSuspended } from 'twenty-shared';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
import { isDefined } from '~/utils/isDefined';
@ -20,7 +20,7 @@ export const useObjectNameSingularFromPlural = ({
}),
);
if (currentWorkspace?.activationStatus !== WorkspaceActivationStatus.Active) {
if (!isWorkspaceActiveOrSuspended(currentWorkspace)) {
objectMetadataItem =
generatedMockObjectMetadataItems.find(
(objectMetadataItem) =>

View File

@ -7,7 +7,7 @@ import { useFindManyRecordIndexTableParams } from '@/object-record/record-index/
import { useRecordTableRecordGqlFields } from '@/object-record/record-index/hooks/useRecordTableRecordGqlFields';
import { useRecordTable } from '@/object-record/record-table/hooks/useRecordTable';
import { SIGN_IN_BACKGROUND_MOCK_COMPANIES } from '@/sign-in-background-mock/constants/SignInBackgroundMockCompanies';
import { WorkspaceActivationStatus } from '~/generated/graphql';
import { isWorkspaceActiveOrSuspended } from 'twenty-shared';
export const useLazyLoadRecordIndexTable = (objectNameSingular: string) => {
const { objectMetadataItem } = useObjectMetadataItem({
@ -44,10 +44,9 @@ export const useLazyLoadRecordIndexTable = (objectNameSingular: string) => {
return {
findManyRecords,
records:
currentWorkspace?.activationStatus === WorkspaceActivationStatus.Active
? records
: SIGN_IN_BACKGROUND_MOCK_COMPANIES,
records: isWorkspaceActiveOrSuspended(currentWorkspace)
? records
: SIGN_IN_BACKGROUND_MOCK_COMPANIES,
totalCount: totalCount,
loading,
fetchMoreRecords,

View File

@ -16,7 +16,7 @@ import {
const currentWorkspace = {
id: '1',
currentBillingSubscription: { status: SubscriptionStatus.Incomplete },
activationStatus: WorkspaceActivationStatus.Active,
activationStatus: WorkspaceActivationStatus.ACTIVE,
allowImpersonation: true,
} as CurrentWorkspace;

View File

@ -6,6 +6,6 @@ import { WorkspaceActivationStatus } from '~/generated/graphql';
export const useIsWorkspaceActivationStatusSuspended = (): boolean => {
const currentWorkspace = useRecoilValue(currentWorkspaceState);
return (
currentWorkspace?.activationStatus === WorkspaceActivationStatus.Suspended
currentWorkspace?.activationStatus === WorkspaceActivationStatus.SUSPENDED
);
};

View File

@ -45,7 +45,7 @@ export const mockCurrentWorkspace: Workspace = {
logo: workspaceLogoUrl,
isPublicInviteLinkEnabled: true,
allowImpersonation: true,
activationStatus: WorkspaceActivationStatus.Active,
activationStatus: WorkspaceActivationStatus.ACTIVE,
hasValidEntrepriseKey: false,
isGoogleAuthEnabled: true,
isPasswordAuthEnabled: true,