Skip to content

Commit ce3be45

Browse files
martmullWeiko
authored andcommitted
5509 remove flash on intermediate verify step when sign in with sso (#5526)
- remove flash on /verify - remove flash on signInUp - remove useless redirections and hooks - Remove DefaultHomePage component - Move redirections to /objects/companies in PageChangeEffect - add useShowAuthModal hooks and tests - add usePageChangeEffectNaviteLocation hooks and tests - fix refresh token expired produces blank screen
1 parent ea174a6 commit ce3be45

26 files changed

+976
-418
lines changed

packages/twenty-front/src/App.tsx

+1-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import { Invite } from '~/pages/auth/Invite';
4343
import { PasswordReset } from '~/pages/auth/PasswordReset';
4444
import { PaymentSuccess } from '~/pages/auth/PaymentSuccess';
4545
import { SignInUp } from '~/pages/auth/SignInUp';
46-
import { DefaultHomePage } from '~/pages/DefaultHomePage';
4746
import { ImpersonateEffect } from '~/pages/impersonate/ImpersonateEffect';
4847
import { NotFound } from '~/pages/not-found/NotFound';
4948
import { RecordIndexPage } from '~/pages/object-record/RecordIndexPage';
@@ -139,10 +138,7 @@ const createRouter = (isBillingEnabled?: boolean) =>
139138
path={AppPath.PlanRequiredSuccess}
140139
element={<PaymentSuccess />}
141140
/>
142-
<Route
143-
path={indexAppPath.getIndexAppPath()}
144-
element={<DefaultHomePage />}
145-
/>
141+
<Route path={indexAppPath.getIndexAppPath()} element={<></>} />
146142
<Route path={AppPath.TasksPage} element={<Tasks />} />
147143
<Route path={AppPath.Impersonate} element={<ImpersonateEffect />} />
148144
<Route path={AppPath.RecordIndexPage} element={<RecordIndexPage />} />

packages/twenty-front/src/effect-components/PageChangeEffect.tsx

+8-81
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,41 @@ import { IconCheckbox } from 'twenty-ui';
55

66
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
77
import { useEventTracker } from '@/analytics/hooks/useEventTracker';
8-
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
9-
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
108
import { useRequestFreshCaptchaToken } from '@/captcha/hooks/useRequestFreshCaptchaToken';
119
import { isCaptchaScriptLoadedState } from '@/captcha/states/isCaptchaScriptLoadedState';
12-
import { isSignUpDisabledState } from '@/client-config/states/isSignUpDisabledState';
1310
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
1411
import { CommandType } from '@/command-menu/types/Command';
1512
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
1613
import { AppBasePath } from '@/types/AppBasePath';
1714
import { AppPath } from '@/types/AppPath';
1815
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
1916
import { SettingsPath } from '@/types/SettingsPath';
20-
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
2117
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
22-
import { useGetWorkspaceFromInviteHashLazyQuery } from '~/generated/graphql';
2318
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
19+
import { usePageChangeEffectNavigateLocation } from '~/hooks/usePageChangeEffectNavigateLocation';
2420
import { isDefined } from '~/utils/isDefined';
2521

2622
// TODO: break down into smaller functions and / or hooks
23+
// - moved usePageChangeEffectNavigateLocation into dedicated hook
2724
export const PageChangeEffect = () => {
2825
const navigate = useNavigate();
2926
const isMatchingLocation = useIsMatchingLocation();
30-
const { enqueueSnackBar } = useSnackBar();
3127

3228
const [previousLocation, setPreviousLocation] = useState('');
3329

34-
const onboardingStatus = useOnboardingStatus();
35-
3630
const setHotkeyScope = useSetHotkeyScope();
3731

3832
const location = useLocation();
3933

34+
const pageChangeEffectNavigateLocation =
35+
usePageChangeEffectNavigateLocation();
36+
4037
const eventTracker = useEventTracker();
4138

42-
const [workspaceFromInviteHashQuery] =
43-
useGetWorkspaceFromInviteHashLazyQuery();
4439
const { addToCommandMenu, setToInitialCommandMenu } = useCommandMenu();
4540

4641
const openCreateActivity = useOpenCreateActivityDrawer();
4742

48-
const isSignUpDisabled = useRecoilValue(isSignUpDisabledState);
49-
5043
useEffect(() => {
5144
if (!previousLocation || previousLocation !== location.pathname) {
5245
setPreviousLocation(location.pathname);
@@ -56,76 +49,10 @@ export const PageChangeEffect = () => {
5649
}, [location, previousLocation]);
5750

5851
useEffect(() => {
59-
const isMatchingOngoingUserCreationRoute =
60-
isMatchingLocation(AppPath.SignInUp) ||
61-
isMatchingLocation(AppPath.Invite) ||
62-
isMatchingLocation(AppPath.Verify);
63-
64-
const isMatchingOnboardingRoute =
65-
isMatchingOngoingUserCreationRoute ||
66-
isMatchingLocation(AppPath.CreateWorkspace) ||
67-
isMatchingLocation(AppPath.CreateProfile) ||
68-
isMatchingLocation(AppPath.PlanRequired) ||
69-
isMatchingLocation(AppPath.PlanRequiredSuccess);
70-
71-
if (
72-
onboardingStatus === OnboardingStatus.OngoingUserCreation &&
73-
!isMatchingOngoingUserCreationRoute &&
74-
!isMatchingLocation(AppPath.ResetPassword)
75-
) {
76-
navigate(AppPath.SignInUp);
77-
} else if (
78-
isDefined(onboardingStatus) &&
79-
onboardingStatus === OnboardingStatus.Incomplete &&
80-
!isMatchingLocation(AppPath.PlanRequired)
81-
) {
82-
navigate(AppPath.PlanRequired);
83-
} else if (
84-
isDefined(onboardingStatus) &&
85-
[OnboardingStatus.Unpaid, OnboardingStatus.Canceled].includes(
86-
onboardingStatus,
87-
) &&
88-
!(
89-
isMatchingLocation(AppPath.SettingsCatchAll) ||
90-
isMatchingLocation(AppPath.PlanRequired)
91-
)
92-
) {
93-
navigate(
94-
`${AppPath.SettingsCatchAll.replace('/*', '')}/${SettingsPath.Billing}`,
95-
);
96-
} else if (
97-
onboardingStatus === OnboardingStatus.OngoingWorkspaceActivation &&
98-
!isMatchingLocation(AppPath.CreateWorkspace) &&
99-
!isMatchingLocation(AppPath.PlanRequiredSuccess)
100-
) {
101-
navigate(AppPath.CreateWorkspace);
102-
} else if (
103-
onboardingStatus === OnboardingStatus.OngoingProfileCreation &&
104-
!isMatchingLocation(AppPath.CreateProfile)
105-
) {
106-
navigate(AppPath.CreateProfile);
107-
} else if (
108-
onboardingStatus === OnboardingStatus.Completed &&
109-
isMatchingOnboardingRoute &&
110-
!isMatchingLocation(AppPath.Invite)
111-
) {
112-
navigate(AppPath.Index);
113-
} else if (
114-
onboardingStatus === OnboardingStatus.CompletedWithoutSubscription &&
115-
isMatchingOnboardingRoute &&
116-
!isMatchingLocation(AppPath.PlanRequired)
117-
) {
118-
navigate(AppPath.Index);
52+
if (isDefined(pageChangeEffectNavigateLocation)) {
53+
navigate(pageChangeEffectNavigateLocation);
11954
}
120-
}, [
121-
enqueueSnackBar,
122-
isMatchingLocation,
123-
isSignUpDisabled,
124-
location.pathname,
125-
navigate,
126-
onboardingStatus,
127-
workspaceFromInviteHashQuery,
128-
]);
55+
}, [navigate, pageChangeEffectNavigateLocation]);
12956

13057
useEffect(() => {
13158
switch (true) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { renderHook } from '@testing-library/react';
2+
import { RecoilRoot, useSetRecoilState } from 'recoil';
3+
4+
import { currentUserState } from '@/auth/states/currentUserState';
5+
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
6+
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
7+
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
8+
import { AppPath } from '@/types/AppPath';
9+
import { useDefaultHomePagePath } from '~/hooks/useDefaultHomePagePath';
10+
import { mockedUsersData } from '~/testing/mock-data/users';
11+
12+
const objectMetadataItem = getObjectMetadataItemsMock()[0];
13+
jest.mock('@/object-metadata/hooks/useObjectMetadataItem');
14+
jest.mocked(useObjectMetadataItem).mockReturnValue({
15+
objectMetadataItem,
16+
});
17+
18+
jest.mock('@/prefetch/hooks/usePrefetchedData');
19+
const setupMockPrefetchedData = (viewId?: string) => {
20+
jest.mocked(usePrefetchedData).mockReturnValue({
21+
isDataPrefetched: true,
22+
records: viewId
23+
? [
24+
{
25+
id: viewId,
26+
__typename: 'object',
27+
objectMetadataId: objectMetadataItem.id,
28+
},
29+
]
30+
: [],
31+
});
32+
};
33+
34+
const renderHooks = (withCurrentUser: boolean) => {
35+
const { result } = renderHook(
36+
() => {
37+
const setCurrentUser = useSetRecoilState(currentUserState);
38+
if (withCurrentUser) {
39+
setCurrentUser(mockedUsersData[0]);
40+
}
41+
return useDefaultHomePagePath();
42+
},
43+
{
44+
wrapper: RecoilRoot,
45+
},
46+
);
47+
return { result };
48+
};
49+
describe('useDefaultHomePagePath', () => {
50+
it('should return proper path when no currentUser', () => {
51+
setupMockPrefetchedData();
52+
const { result } = renderHooks(false);
53+
expect(result.current.defaultHomePagePath).toEqual(AppPath.SignInUp);
54+
});
55+
it('should return proper path when no currentUser and existing view', () => {
56+
setupMockPrefetchedData('viewId');
57+
const { result } = renderHooks(false);
58+
expect(result.current.defaultHomePagePath).toEqual(AppPath.SignInUp);
59+
});
60+
it('should return proper path when currentUser is defined', () => {
61+
setupMockPrefetchedData();
62+
const { result } = renderHooks(true);
63+
expect(result.current.defaultHomePagePath).toEqual('/objects/companies');
64+
});
65+
it('should return proper path when currentUser is defined and view exists', () => {
66+
setupMockPrefetchedData('viewId');
67+
const { result } = renderHooks(true);
68+
expect(result.current.defaultHomePagePath).toEqual(
69+
'/objects/companies?view=viewId',
70+
);
71+
});
72+
});

0 commit comments

Comments
 (0)