Conversation
|
Self-review notes:
|
@ansmonjol Thank you, I addressed these points |
|
| <Typography variant="headline"> | ||
| {translate('text_664c90c9b2b6c2012aa50bcd', { | ||
| orgnisationName: data?.invite?.organization.name, | ||
| {!error && |
There was a problem hiding this comment.
During onLogOut -> refetchInvite() the card renders empty apart from the logo: mode is still defined (data survives logOut - client.stop() cancels the cache watch before resetPersistedCache, so the hook keeps its last result), which blocks the skeleton, and loading is true, which blocks the content. The notifyOnNetworkStatusChange comment on line 146 assumes the opposite of what happens.
The three branches here are gated by three independent expressions that are neither exhaustive nor mutually exclusive. Would a single render helper be safer?
const isResolving = !!loading || (isAuthenticated && (!!currentUserLoading || !currentUser))
const renderContent = () => {
if (isResolving) return skeletons
if (!!error || !invite || !mode) return notFoundContent
return inviteContent
}should log out and refetch the invitation does not catch this because logOut is mocked, so data is never in the intermediate state.
The same helper would also cover isAuthenticated === true with currentUser never resolving (a non-auth failure of getCurrentUserInfos, which useCurrentUser swallows since it does not expose error): today mode stays undefined and the skeleton never goes away.
|
|
||
| {errorAlert} | ||
|
|
||
| {mode === 'join' && !joinLoginMethodNotAuthorized && ( |
There was a problem hiding this comment.
joinOrganization can also fail with InviteEmailMistmatch and EmailAlreadyUsed (both handled in errorTranslation above), but only LoginMethodNotAuthorized swaps the "Accept invitation" button for "Log out". On the other two the user keeps a button that can only fail again, with no way out of the page and no way into the org.
Since all three are terminal for this session, could we widen the flag rather than special-casing one code?
const JOIN_BLOCKING_ERROR_CODES = [
'LoginMethodNotAuthorized',
'InviteEmailMistmatch',
'EmailAlreadyUsed',
] as const
const isJoinBlocked = JOIN_BLOCKING_ERROR_CODES.some((code) =>
hasDefinedGQLError(code, joinOrganizationError),
)and then use isJoinBlocked both here and on the log-out button's condition below. The per-code messages stay as they are.
| return translate('text_620bc4d4269a55014d493fb7') | ||
| } | ||
|
|
||
| if (hasDefinedGQLError('EmailAlreadyUsed', acceptInviteError)) { |
There was a problem hiding this comment.
text_1786557508910guitmzid55q is "You are already a member of this organization." - true for the joinOrganization case below, but not here: on the sign-up path EmailAlreadyUsed means an account now exists for the invited email, which the test name (should explain when an account was created after the invitation was loaded) states correctly. As written the user is told something false and left on a sign-up form that cannot succeed.
Worth a dedicated key, plus an actual recovery - refetchInvite() in onError would return existingUser: true, flipping mode to logInRequired and swapping in the log-in form with no action from the user:
onError: (mutationError) => {
if (hasDefinedGQLError('EmailAlreadyUsed', mutationError)) {
refetchInvite().catch(() => undefined)
}
},|
|
||
| // Logging out clears the Apollo store without refetching the active queries, so the invite has | ||
| // to be queried again to render the logged out flow. | ||
| const onLogOut = async () => { |
There was a problem hiding this comment.
Nit: refetchInvite() here can reject and nothing catches it, while onJoinOrganization does .catch(() => undefined). await refetchInvite().catch(() => undefined) would keep the two consistent - the hook's own error state still drives the fallback card. onSubmitPassword has the same shape but predates this PR.



BIL-534
Context
The invitation page assumes the invited email has no Lago account. It logs the visitor out and always tries to create a new password.
Description
Requires lago-api#6146 to be deployed first: it queries
existingUserand callsjoinOrganizationjoinOrganizationmutation, and offer to log out when another user is logged in.