From d8f4e7e2337cb541e5fbd13d885b5f3b4d6f31ec Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Mon, 23 Jun 2025 23:23:13 +0200 Subject: [PATCH] Add loader on workspace creation (#12806) Not my most brillant design but it should work! https://github.com/user-attachments/assets/b89ae6d8-84ca-43c4-a010-d0686d522183 --- .../src/pages/onboarding/CreateWorkspace.tsx | 157 ++++++++++++------ 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/packages/twenty-front/src/pages/onboarding/CreateWorkspace.tsx b/packages/twenty-front/src/pages/onboarding/CreateWorkspace.tsx index 9d12ea755..d7a91554a 100644 --- a/packages/twenty-front/src/pages/onboarding/CreateWorkspace.tsx +++ b/packages/twenty-front/src/pages/onboarding/CreateWorkspace.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; import { zodResolver } from '@hookform/resolvers/zod'; -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import { Controller, SubmitHandler, useForm } from 'react-hook-form'; import { Key } from 'ts-key-enum'; import { z } from 'zod'; @@ -16,6 +16,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { TextInputV2 } from '@/ui/input/components/TextInputV2'; import { Modal } from '@/ui/layout/modal/components/Modal'; import { Trans, useLingui } from '@lingui/react/macro'; +import { motion } from 'framer-motion'; import { isDefined } from 'twenty-shared/utils'; import { H2Title } from 'twenty-ui/display'; import { Loader } from 'twenty-ui/feedback'; @@ -35,6 +36,21 @@ const StyledButtonContainer = styled.div` width: 200px; `; +enum PendingCreationLoaderStep { + None = 'none', + Step1 = 'step-1', + Step2 = 'step-2', + Step3 = 'step-3', +} + +const StyledPendingCreationLoader = styled(motion.div)` + height: 388px; + width: 100%; + display: flex; + justify-content: center; + align-items: center; +`; + export const CreateWorkspace = () => { const { t } = useLingui(); const { enqueueSnackBar } = useSnackBar(); @@ -43,6 +59,9 @@ export const CreateWorkspace = () => { const { loadCurrentUser } = useAuth(); const [activateWorkspace] = useActivateWorkspaceMutation(); + const [pendingCreationLoaderStep, setPendingCreationLoaderStep] = useState( + PendingCreationLoaderStep.None, + ); const validationSchema = z .object({ @@ -68,6 +87,16 @@ export const CreateWorkspace = () => { const onSubmit: SubmitHandler
= useCallback( async (data) => { try { + setTimeout(() => { + setPendingCreationLoaderStep(PendingCreationLoaderStep.Step1); + }, 500); + setTimeout(() => { + setPendingCreationLoaderStep(PendingCreationLoaderStep.Step2); + }, 2000); + setTimeout(() => { + setPendingCreationLoaderStep(PendingCreationLoaderStep.Step3); + }, 5000); + const result = await activateWorkspace({ variables: { input: { @@ -84,6 +113,7 @@ export const CreateWorkspace = () => { await loadCurrentUser(); setNextOnboardingStatus(); } catch (error: any) { + setPendingCreationLoaderStep(PendingCreationLoaderStep.None); enqueueSnackBar(error?.message, { variant: SnackBarVariant.Error, }); @@ -108,55 +138,84 @@ export const CreateWorkspace = () => { return ( - - <Trans>Create your workspace</Trans> - - - - A shared environment where you will be able to manage your customer - relations with your team. - - - - - - - - - - ( - + {pendingCreationLoaderStep !== PendingCreationLoaderStep.None && ( + <> + + {pendingCreationLoaderStep === PendingCreationLoaderStep.Step1 && ( + + <Loader color="gray" /> + <Trans>Setting up your database</Trans> + )} - /> - - - - isSubmitting && } - fullWidth - /> - + {pendingCreationLoaderStep === PendingCreationLoaderStep.Step2 && ( + + <Loader color="gray" /> + <Trans>Creating your schema</Trans> + + )} + {pendingCreationLoaderStep === PendingCreationLoaderStep.Step3 && ( + + <Loader color="gray" /> + <Trans>Prefilling your workspace data</Trans> + + )} + + + )} + {pendingCreationLoaderStep === PendingCreationLoaderStep.None && ( + <> + + <Trans>Create your workspace</Trans> + + + + A shared environment where you will be able to manage your + customer relations with your team. + + + + + + + + + + + ( + + )} + /> + + + + isSubmitting && } + fullWidth + /> + + + )} ); };