4689 multi workspace i should be able to accept an invite if im already logged in (#5454)

- split signInUp to separate Invitation from signInUp
- update redirection logic
- add a resolver for userWorkspace
- add a mutation to add a user to a workspace
- authorize /invite/hash while loggedIn
- add a button to join a workspace

### Base functionnality

https://github.com/twentyhq/twenty/assets/29927851/a1075a4e-a2af-4184-aa3e-e163711277a1

### Error handling

https://github.com/twentyhq/twenty/assets/29927851/1bdd78ce-933a-4860-a87a-3f1f7bda389e
This commit is contained in:
martmull
2024-05-20 12:11:38 +02:00
committed by GitHub
parent 1ceeb68da8
commit 88f5eb669e
17 changed files with 340 additions and 101 deletions

View File

@ -6,11 +6,17 @@ import { motion } from 'framer-motion';
import { useRecoilState, useRecoilValue } from 'recoil';
import { IconGoogle, IconMicrosoft } from 'twenty-ui';
import { FooterNote } from '@/auth/sign-in-up/components/FooterNote';
import { HorizontalSeparator } from '@/auth/sign-in-up/components/HorizontalSeparator';
import { useHandleResetPassword } from '@/auth/sign-in-up/hooks/useHandleResetPassword';
import {
SignInUpMode,
SignInUpStep,
useSignInUp,
} from '@/auth/sign-in-up/hooks/useSignInUp';
import { useSignInUpForm } from '@/auth/sign-in-up/hooks/useSignInUpForm';
import { useSignInWithGoogle } from '@/auth/sign-in-up/hooks/useSignInWithGoogle';
import { useSignInWithMicrosoft } from '@/auth/sign-in-up/hooks/useSignInWithMicrosoft';
import { useWorkspaceFromInviteHash } from '@/auth/sign-in-up/hooks/useWorkspaceFromInviteHash';
import { isRequestingCaptchaTokenState } from '@/captcha/states/isRequestingCaptchaTokenState';
import { authProvidersState } from '@/client-config/states/authProvidersState';
import { captchaProviderState } from '@/client-config/states/captchaProviderState';
@ -18,16 +24,8 @@ import { Loader } from '@/ui/feedback/loader/components/Loader';
import { MainButton } from '@/ui/input/button/components/MainButton';
import { TextInput } from '@/ui/input/components/TextInput';
import { ActionLink } from '@/ui/navigation/link/components/ActionLink';
import { AnimatedEaseIn } from '@/ui/utilities/animation/components/AnimatedEaseIn';
import { isDefined } from '~/utils/isDefined';
import { Logo } from '../../components/Logo';
import { Title } from '../../components/Title';
import { SignInUpMode, SignInUpStep, useSignInUp } from '../hooks/useSignInUp';
import { FooterNote } from './FooterNote';
import { HorizontalSeparator } from './HorizontalSeparator';
const StyledContentContainer = styled.div`
margin-bottom: ${({ theme }) => theme.spacing(8)};
margin-top: ${({ theme }) => theme.spacing(4)};
@ -55,14 +53,12 @@ export const SignInUpForm = () => {
);
const [authProviders] = useRecoilState(authProvidersState);
const [showErrors, setShowErrors] = useState(false);
const { handleResetPassword } = useHandleResetPassword();
const workspace = useWorkspaceFromInviteHash();
const { signInWithGoogle } = useSignInWithGoogle();
const { signInWithMicrosoft } = useSignInWithMicrosoft();
const { form } = useSignInUpForm();
const { handleResetPassword } = useHandleResetPassword();
const {
isInviteMode,
signInUpStep,
signInUpMode,
continueWithCredentials,
@ -101,23 +97,6 @@ export const SignInUpForm = () => {
return signInUpMode === SignInUpMode.SignIn ? 'Sign in' : 'Sign up';
}, [signInUpMode, signInUpStep]);
const title = useMemo(() => {
if (isInviteMode) {
return `Join ${workspace?.displayName ?? ''} team`;
}
if (
signInUpStep === SignInUpStep.Init ||
signInUpStep === SignInUpStep.Email
) {
return 'Welcome to Twenty';
}
return signInUpMode === SignInUpMode.SignIn
? 'Sign in to Twenty'
: 'Sign up to Twenty';
}, [signInUpMode, workspace?.displayName, isInviteMode, signInUpStep]);
const theme = useTheme();
const shouldWaitForCaptchaToken =
@ -143,10 +122,6 @@ export const SignInUpForm = () => {
return (
<>
<AnimatedEaseIn>
<Logo workspaceLogo={workspace?.logo} />
</AnimatedEaseIn>
<Title animate>{title}</Title>
<StyledContentContainer>
{authProviders.google && (
<>

View File

@ -4,8 +4,13 @@ import { useGetWorkspaceFromInviteHashQuery } from '~/generated/graphql';
export const useWorkspaceFromInviteHash = () => {
const workspaceInviteHash = useParams().workspaceInviteHash;
const { data: workspaceFromInviteHash } = useGetWorkspaceFromInviteHashQuery({
variables: { inviteHash: workspaceInviteHash || '' },
});
return workspaceFromInviteHash?.findWorkspaceFromInviteHash;
const { data: workspaceFromInviteHash, loading } =
useGetWorkspaceFromInviteHashQuery({
variables: { inviteHash: workspaceInviteHash || '' },
});
return {
workspace: workspaceFromInviteHash?.findWorkspaceFromInviteHash,
workspaceInviteHash,
loading,
};
};