Improve use set next onboarding state (#6076)

querying workspaceMembers may be slow leads to wrong
setNextOnboardingStatus value. So we added a resolved field in workspace
to get workspaceMemberCount directly
This commit is contained in:
martmull 2024-06-30 21:00:20 +02:00 committed by GitHub
parent 411fddd8d7
commit cce9bf5730
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 125 additions and 33 deletions

View File

@ -984,6 +984,8 @@ export type CalendarChannel = {
connectedAccount?: Maybe<ConnectedAccount>;
/** Connected Account id foreign key */
connectedAccountId?: Maybe<Scalars['UUID']>;
/** Automatically create records for people you participated with in an event. */
contactAutoCreationPolicy?: Maybe<CalendarChannelContactAutoCreationPolicyEnum>;
/** Creation date */
createdAt?: Maybe<Scalars['DateTime']>;
/** Handle */
@ -1030,10 +1032,31 @@ export type CalendarChannelConnection = {
totalCount?: Maybe<Scalars['Int']>;
};
/** Automatically create records for people you participated with in an event. */
export enum CalendarChannelContactAutoCreationPolicyEnum {
/** As Organizer */
AsOrganizer = 'AS_ORGANIZER',
/** As Participant */
AsParticipant = 'AS_PARTICIPANT',
/** As Participant and Organizer */
AsParticipantAndOrganizer = 'AS_PARTICIPANT_AND_ORGANIZER',
/** None */
None = 'NONE'
}
export type CalendarChannelContactAutoCreationPolicyEnumFilter = {
eq?: InputMaybe<CalendarChannelContactAutoCreationPolicyEnum>;
in?: InputMaybe<Array<InputMaybe<CalendarChannelContactAutoCreationPolicyEnum>>>;
is?: InputMaybe<FilterIs>;
neq?: InputMaybe<CalendarChannelContactAutoCreationPolicyEnum>;
};
/** Calendar Channels */
export type CalendarChannelCreateInput = {
/** Connected Account id foreign key */
connectedAccountId: Scalars['UUID'];
/** Automatically create records for people you participated with in an event. */
contactAutoCreationPolicy?: InputMaybe<CalendarChannelContactAutoCreationPolicyEnum>;
/** Creation date */
createdAt?: InputMaybe<Scalars['DateTime']>;
/** Handle */
@ -1172,6 +1195,8 @@ export type CalendarChannelFilterInput = {
and?: InputMaybe<Array<InputMaybe<CalendarChannelFilterInput>>>;
/** Connected Account id foreign key */
connectedAccountId?: InputMaybe<IdFilter>;
/** Automatically create records for people you participated with in an event. */
contactAutoCreationPolicy?: InputMaybe<CalendarChannelContactAutoCreationPolicyEnumFilter>;
/** Creation date */
createdAt?: InputMaybe<DateFilter>;
/** Handle */
@ -1204,6 +1229,8 @@ export type CalendarChannelFilterInput = {
export type CalendarChannelOrderByInput = {
/** Connected Account id foreign key */
connectedAccountId?: InputMaybe<OrderByDirection>;
/** Automatically create records for people you participated with in an event. */
contactAutoCreationPolicy?: InputMaybe<OrderByDirection>;
/** Creation date */
createdAt?: InputMaybe<OrderByDirection>;
/** Handle */
@ -1278,6 +1305,8 @@ export type CalendarChannelSyncStatusEnumFilter = {
export type CalendarChannelUpdateInput = {
/** Connected Account id foreign key */
connectedAccountId?: InputMaybe<Scalars['UUID']>;
/** Automatically create records for people you participated with in an event. */
contactAutoCreationPolicy?: InputMaybe<CalendarChannelContactAutoCreationPolicyEnum>;
/** Creation date */
createdAt?: InputMaybe<Scalars['DateTime']>;
/** Handle */
@ -2697,8 +2726,14 @@ export type MessageChannel = {
connectedAccount?: Maybe<ConnectedAccount>;
/** Connected Account id foreign key */
connectedAccountId?: Maybe<Scalars['UUID']>;
/** Automatically create People records when receiving or sending emails */
contactAutoCreationPolicy?: Maybe<MessageChannelContactAutoCreationPolicyEnum>;
/** Creation date */
createdAt?: Maybe<Scalars['DateTime']>;
/** Exclude group emails */
excludeGroupEmails?: Maybe<Scalars['Boolean']>;
/** Exclude non professional emails */
excludeNonProfessionalEmails?: Maybe<Scalars['Boolean']>;
/** Handle */
handle?: Maybe<Scalars['String']>;
/** Id */
@ -2749,12 +2784,35 @@ export type MessageChannelConnection = {
totalCount?: Maybe<Scalars['Int']>;
};
/** Automatically create People records when receiving or sending emails */
export enum MessageChannelContactAutoCreationPolicyEnum {
/** None */
None = 'NONE',
/** Sent */
Sent = 'SENT',
/** Sent and Received */
SentAndReceived = 'SENT_AND_RECEIVED'
}
export type MessageChannelContactAutoCreationPolicyEnumFilter = {
eq?: InputMaybe<MessageChannelContactAutoCreationPolicyEnum>;
in?: InputMaybe<Array<InputMaybe<MessageChannelContactAutoCreationPolicyEnum>>>;
is?: InputMaybe<FilterIs>;
neq?: InputMaybe<MessageChannelContactAutoCreationPolicyEnum>;
};
/** Message Channels */
export type MessageChannelCreateInput = {
/** Connected Account id foreign key */
connectedAccountId: Scalars['UUID'];
/** Automatically create People records when receiving or sending emails */
contactAutoCreationPolicy?: InputMaybe<MessageChannelContactAutoCreationPolicyEnum>;
/** Creation date */
createdAt?: InputMaybe<Scalars['DateTime']>;
/** Exclude group emails */
excludeGroupEmails?: InputMaybe<Scalars['Boolean']>;
/** Exclude non professional emails */
excludeNonProfessionalEmails?: InputMaybe<Scalars['Boolean']>;
/** Handle */
handle?: InputMaybe<Scalars['String']>;
/** Id */
@ -2794,8 +2852,14 @@ export type MessageChannelFilterInput = {
and?: InputMaybe<Array<InputMaybe<MessageChannelFilterInput>>>;
/** Connected Account id foreign key */
connectedAccountId?: InputMaybe<IdFilter>;
/** Automatically create People records when receiving or sending emails */
contactAutoCreationPolicy?: InputMaybe<MessageChannelContactAutoCreationPolicyEnumFilter>;
/** Creation date */
createdAt?: InputMaybe<DateFilter>;
/** Exclude group emails */
excludeGroupEmails?: InputMaybe<BooleanFilter>;
/** Exclude non professional emails */
excludeNonProfessionalEmails?: InputMaybe<BooleanFilter>;
/** Handle */
handle?: InputMaybe<StringFilter>;
/** Id */
@ -2953,8 +3017,14 @@ export type MessageChannelMessageAssociationUpdateInput = {
export type MessageChannelOrderByInput = {
/** Connected Account id foreign key */
connectedAccountId?: InputMaybe<OrderByDirection>;
/** Automatically create People records when receiving or sending emails */
contactAutoCreationPolicy?: InputMaybe<OrderByDirection>;
/** Creation date */
createdAt?: InputMaybe<OrderByDirection>;
/** Exclude group emails */
excludeGroupEmails?: InputMaybe<OrderByDirection>;
/** Exclude non professional emails */
excludeNonProfessionalEmails?: InputMaybe<OrderByDirection>;
/** Handle */
handle?: InputMaybe<OrderByDirection>;
/** Id */
@ -3052,8 +3122,14 @@ export type MessageChannelTypeEnumFilter = {
export type MessageChannelUpdateInput = {
/** Connected Account id foreign key */
connectedAccountId?: InputMaybe<Scalars['UUID']>;
/** Automatically create People records when receiving or sending emails */
contactAutoCreationPolicy?: InputMaybe<MessageChannelContactAutoCreationPolicyEnum>;
/** Creation date */
createdAt?: InputMaybe<Scalars['DateTime']>;
/** Exclude group emails */
excludeGroupEmails?: InputMaybe<Scalars['Boolean']>;
/** Exclude non professional emails */
excludeNonProfessionalEmails?: InputMaybe<Scalars['Boolean']>;
/** Handle */
handle?: InputMaybe<Scalars['String']>;
/** Id */
@ -7389,6 +7465,7 @@ export type Workspace = {
inviteHash?: Maybe<Scalars['String']>;
logo?: Maybe<Scalars['String']>;
updatedAt: Scalars['DateTime'];
workspaceMembersCount?: Maybe<Scalars['Float']>;
};

View File

@ -1203,6 +1203,7 @@ export type Workspace = {
inviteHash?: Maybe<Scalars['String']['output']>;
logo?: Maybe<Scalars['String']['output']>;
updatedAt: Scalars['DateTime']['output'];
workspaceMembersCount?: Maybe<Scalars['Float']['output']>;
};

View File

@ -919,6 +919,7 @@ export type Workspace = {
inviteHash?: Maybe<Scalars['String']>;
logo?: Maybe<Scalars['String']>;
updatedAt: Scalars['DateTime'];
workspaceMembersCount?: Maybe<Scalars['Float']>;
};
@ -1177,7 +1178,7 @@ export type ImpersonateMutationVariables = Exact<{
}>;
export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type RenewTokenMutationVariables = Exact<{
appToken: Scalars['String'];
@ -1209,7 +1210,7 @@ export type VerifyMutationVariables = Exact<{
}>;
export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } };
export type CheckUserExistsQueryVariables = Exact<{
email: Scalars['String'];
@ -1263,7 +1264,7 @@ export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]
export type SkipSyncEmailOnboardingStepMutation = { __typename?: 'Mutation', skipSyncEmailOnboardingStep: { __typename?: 'OnboardingStepSuccess', success: boolean } };
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
@ -1280,7 +1281,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> } };
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> } };
export type AddUserToWorkspaceMutationVariables = Exact<{
inviteHash: Scalars['String'];
@ -1455,6 +1456,7 @@ export const UserQueryFragmentFragmentDoc = gql`
status
interval
}
workspaceMembersCount
}
workspaces {
workspace {

View File

@ -12,6 +12,7 @@ export type CurrentWorkspace = Pick<
| 'featureFlags'
| 'activationStatus'
| 'currentBillingSubscription'
| 'workspaceMembersCount'
| 'currentCacheVersion'
>;

View File

@ -11,20 +11,10 @@ import {
mockedUserData,
} from '~/testing/mock-data/users';
jest.mock('@/object-record/hooks/useFindManyRecords', () => ({
useFindManyRecords: jest.fn(),
}));
const setupMockWorkspaceMembers = (withManyWorkspaceMembers = false) => {
jest
.requireMock('@/object-record/hooks/useFindManyRecords')
.useFindManyRecords.mockReturnValue({
records: withManyWorkspaceMembers ? [{}, {}] : [{}],
});
};
const renderHooks = (
onboardingStatus: OnboardingStatus,
withCurrentBillingSubscription: boolean,
withOneWorkspaceMember = true,
) => {
const { result } = renderHook(
() => {
@ -49,6 +39,7 @@ const renderHooks = (
currentBillingSubscription: withCurrentBillingSubscription
? { id: v4(), status: SubscriptionStatus.Active }
: undefined,
workspaceMembersCount: withOneWorkspaceMember ? 1 : 2,
});
});
act(() => {
@ -59,29 +50,38 @@ const renderHooks = (
describe('useSetNextOnboardingStatus', () => {
it('should set next onboarding status for ProfileCreation', () => {
setupMockWorkspaceMembers();
const nextOnboardingStatus = renderHooks(
OnboardingStatus.ProfileCreation,
false,
true,
);
expect(nextOnboardingStatus).toEqual(OnboardingStatus.SyncEmail);
});
it('should set next onboarding status for SyncEmail', () => {
setupMockWorkspaceMembers();
const nextOnboardingStatus = renderHooks(OnboardingStatus.SyncEmail, false);
const nextOnboardingStatus = renderHooks(
OnboardingStatus.SyncEmail,
false,
true,
);
expect(nextOnboardingStatus).toEqual(OnboardingStatus.InviteTeam);
});
it('should skip invite when workspaceMembers exist', () => {
setupMockWorkspaceMembers(true);
const nextOnboardingStatus = renderHooks(OnboardingStatus.SyncEmail, true);
it('should skip invite when more than 1 workspaceMember exist', () => {
const nextOnboardingStatus = renderHooks(
OnboardingStatus.SyncEmail,
true,
false,
);
expect(nextOnboardingStatus).toEqual(OnboardingStatus.Completed);
});
it('should set next onboarding status for Completed', () => {
setupMockWorkspaceMembers();
const nextOnboardingStatus = renderHooks(OnboardingStatus.InviteTeam, true);
const nextOnboardingStatus = renderHooks(
OnboardingStatus.InviteTeam,
true,
true,
);
expect(nextOnboardingStatus).toEqual(OnboardingStatus.Completed);
});
});

View File

@ -1,22 +1,23 @@
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { CurrentUser, currentUserState } from '@/auth/states/currentUserState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import {
CurrentWorkspace,
currentWorkspaceState,
} from '@/auth/states/currentWorkspaceState';
import { OnboardingStatus } from '~/generated/graphql';
import { isDefined } from '~/utils/isDefined';
const getNextOnboardingStatus = (
currentUser: CurrentUser | null,
workspaceMembers: WorkspaceMember[],
currentWorkspace: CurrentWorkspace | null,
) => {
if (currentUser?.onboardingStatus === OnboardingStatus.ProfileCreation) {
return OnboardingStatus.SyncEmail;
}
if (
currentUser?.onboardingStatus === OnboardingStatus.SyncEmail &&
workspaceMembers.length === 1
currentWorkspace?.workspaceMembersCount === 1
) {
return OnboardingStatus.InviteTeam;
}
@ -24,17 +25,15 @@ const getNextOnboardingStatus = (
};
export const useSetNextOnboardingStatus = () => {
const { records: workspaceMembers } = useFindManyRecords<WorkspaceMember>({
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
});
const currentUser = useRecoilValue(currentUserState);
const currentWorkspace = useRecoilValue(currentWorkspaceState);
return useRecoilCallback(
({ set }) =>
() => {
const nextOnboardingStatus = getNextOnboardingStatus(
currentUser,
workspaceMembers,
currentWorkspace,
);
set(currentUserState, (current) => {
if (isDefined(current)) {
@ -46,6 +45,6 @@ export const useSetNextOnboardingStatus = () => {
return current;
});
},
[workspaceMembers, currentUser],
[currentWorkspace, currentUser],
);
};

View File

@ -39,6 +39,7 @@ export const USER_QUERY_FRAGMENT = gql`
status
interval
}
workspaceMembersCount
}
workspaces {
workspace {

View File

@ -66,6 +66,7 @@ export const mockDefaultWorkspace: Workspace = {
interval: SubscriptionInterval.Month,
status: SubscriptionStatus.Active,
},
workspaceMembersCount: 1,
};
export const mockedWorkspaceMemberData: WorkspaceMember = {

View File

@ -87,6 +87,9 @@ export class Workspace {
@Field({ nullable: true })
currentBillingSubscription: BillingSubscription;
@Field({ nullable: true })
workspaceMembersCount: number;
@Field()
activationStatus: 'active' | 'inactive';

View File

@ -27,6 +27,7 @@ import { DemoEnvGuard } from 'src/engine/guards/demo.env.guard';
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
import { SendInviteLink } from 'src/engine/core-modules/workspace/dtos/send-invite-link.entity';
import { SendInviteLinkInput } from 'src/engine/core-modules/workspace/dtos/send-invite-link.input';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
import { Workspace } from './workspace.entity';
@ -38,6 +39,7 @@ export class WorkspaceResolver {
constructor(
private readonly workspaceService: WorkspaceService,
private readonly workspaceCacheVersionService: WorkspaceCacheVersionService,
private readonly userWorkspaceService: UserWorkspaceService,
private readonly fileUploadService: FileUploadService,
private readonly billingService: BillingService,
) {}
@ -125,6 +127,11 @@ export class WorkspaceResolver {
});
}
@ResolveField(() => Number)
async workspaceMembersCount(): Promise<number | undefined> {
return await this.userWorkspaceService.getWorkspaceMemberCount();
}
@Mutation(() => SendInviteLink)
async sendInviteLink(
@Args() sendInviteLinkInput: SendInviteLinkInput,