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
10 changed files with 125 additions and 33 deletions

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 {