Remove recoil sync (#11569)
Recoil-sync was causing issues with Firefox, replacing it with a simpler mechanism to hydrate variables on page load --------- Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
This commit is contained in:
@ -54,7 +54,6 @@
|
|||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"docx": "^9.1.0",
|
"docx": "^9.1.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"recoil-sync": "^0.2.0",
|
|
||||||
"transliteration": "^2.3.5",
|
"transliteration": "^2.3.5",
|
||||||
"twenty-shared": "workspace:*",
|
"twenty-shared": "workspace:*",
|
||||||
"twenty-ui": "workspace:*"
|
"twenty-ui": "workspace:*"
|
||||||
|
|||||||
@ -9,35 +9,32 @@ import { i18n } from '@lingui/core';
|
|||||||
import { I18nProvider } from '@lingui/react';
|
import { I18nProvider } from '@lingui/react';
|
||||||
import { HelmetProvider } from 'react-helmet-async';
|
import { HelmetProvider } from 'react-helmet-async';
|
||||||
import { RecoilRoot } from 'recoil';
|
import { RecoilRoot } from 'recoil';
|
||||||
import { RecoilURLSyncJSON } from 'recoil-sync';
|
|
||||||
import { initialI18nActivate } from '~/utils/i18n/initialI18nActivate';
|
|
||||||
import { IconsProvider } from 'twenty-ui/display';
|
import { IconsProvider } from 'twenty-ui/display';
|
||||||
|
import { initialI18nActivate } from '~/utils/i18n/initialI18nActivate';
|
||||||
|
|
||||||
initialI18nActivate();
|
initialI18nActivate();
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
return (
|
return (
|
||||||
<RecoilRoot>
|
<RecoilRoot>
|
||||||
<RecoilURLSyncJSON location={{ part: 'queryParams' }}>
|
<AppErrorBoundary
|
||||||
<AppErrorBoundary
|
resetOnLocationChange={false}
|
||||||
resetOnLocationChange={false}
|
FallbackComponent={AppRootErrorFallback}
|
||||||
FallbackComponent={AppRootErrorFallback}
|
>
|
||||||
>
|
<I18nProvider i18n={i18n}>
|
||||||
<I18nProvider i18n={i18n}>
|
<RecoilDebugObserverEffect />
|
||||||
<RecoilDebugObserverEffect />
|
<ApolloDevLogEffect />
|
||||||
<ApolloDevLogEffect />
|
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||||
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
<IconsProvider>
|
||||||
<IconsProvider>
|
<ExceptionHandlerProvider>
|
||||||
<ExceptionHandlerProvider>
|
<HelmetProvider>
|
||||||
<HelmetProvider>
|
<AppRouter />
|
||||||
<AppRouter />
|
</HelmetProvider>
|
||||||
</HelmetProvider>
|
</ExceptionHandlerProvider>
|
||||||
</ExceptionHandlerProvider>
|
</IconsProvider>
|
||||||
</IconsProvider>
|
</SnackBarProviderScope>
|
||||||
</SnackBarProviderScope>
|
</I18nProvider>
|
||||||
</I18nProvider>
|
</AppErrorBoundary>
|
||||||
</AppErrorBoundary>
|
|
||||||
</RecoilURLSyncJSON>
|
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
|
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
|
||||||
import { usePageChangeEffectNavigateLocation } from '~/hooks/usePageChangeEffectNavigateLocation';
|
import { usePageChangeEffectNavigateLocation } from '~/hooks/usePageChangeEffectNavigateLocation';
|
||||||
|
import { useInitializeQueryParamState } from '~/modules/app/hooks/useInitializeQueryParamState';
|
||||||
|
|
||||||
// TODO: break down into smaller functions and / or hooks
|
// TODO: break down into smaller functions and / or hooks
|
||||||
// - moved usePageChangeEffectNavigateLocation into dedicated hook
|
// - moved usePageChangeEffectNavigateLocation into dedicated hook
|
||||||
@ -44,6 +45,8 @@ export const PageChangeEffect = () => {
|
|||||||
|
|
||||||
const eventTracker = useEventTracker();
|
const eventTracker = useEventTracker();
|
||||||
|
|
||||||
|
const { initializeQueryParamState } = useInitializeQueryParamState();
|
||||||
|
|
||||||
//TODO: refactor useResetTableRowSelection hook to not throw when the argument `recordTableId` is an empty string
|
//TODO: refactor useResetTableRowSelection hook to not throw when the argument `recordTableId` is an empty string
|
||||||
// - replace CoreObjectNamePlural.Person
|
// - replace CoreObjectNamePlural.Person
|
||||||
const objectNamePlural =
|
const objectNamePlural =
|
||||||
@ -64,10 +67,12 @@ export const PageChangeEffect = () => {
|
|||||||
}, [location, previousLocation, executeTasksOnAnyLocationChange]);
|
}, [location, previousLocation, executeTasksOnAnyLocationChange]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
initializeQueryParamState();
|
||||||
|
|
||||||
if (isDefined(pageChangeEffectNavigateLocation)) {
|
if (isDefined(pageChangeEffectNavigateLocation)) {
|
||||||
navigate(pageChangeEffectNavigateLocation);
|
navigate(pageChangeEffectNavigateLocation);
|
||||||
}
|
}
|
||||||
}, [navigate, pageChangeEffectNavigateLocation]);
|
}, [navigate, pageChangeEffectNavigateLocation, initializeQueryParamState]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isLeavingRecordIndexPage = !!matchPath(
|
const isLeavingRecordIndexPage = !!matchPath(
|
||||||
|
|||||||
@ -0,0 +1,66 @@
|
|||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { isQueryParamInitializedState } from '@/app/states/isQueryParamInitializedState';
|
||||||
|
import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState';
|
||||||
|
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
||||||
|
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
|
||||||
|
|
||||||
|
// Initialize state that are hydrated from query parameters
|
||||||
|
// We used to use recoil-sync to do this, but it was causing issues with Firefox
|
||||||
|
export const useInitializeQueryParamState = () => {
|
||||||
|
const initializeQueryParamState = useRecoilCallback(
|
||||||
|
({ set, snapshot }) =>
|
||||||
|
() => {
|
||||||
|
const isInitialized = snapshot
|
||||||
|
.getLoadable(isQueryParamInitializedState)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (!isInitialized) {
|
||||||
|
const handlers = {
|
||||||
|
billingCheckoutSession: (value: string) => {
|
||||||
|
try {
|
||||||
|
const parsedValue = JSON.parse(decodeURIComponent(value));
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof parsedValue === 'object' &&
|
||||||
|
parsedValue !== null &&
|
||||||
|
'plan' in parsedValue &&
|
||||||
|
'interval' in parsedValue &&
|
||||||
|
'requirePaymentMethod' in parsedValue
|
||||||
|
) {
|
||||||
|
set(
|
||||||
|
billingCheckoutSessionState,
|
||||||
|
parsedValue as BillingCheckoutSession,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(
|
||||||
|
'Failed to parse billingCheckoutSession from URL',
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
set(
|
||||||
|
billingCheckoutSessionState,
|
||||||
|
BILLING_CHECKOUT_SESSION_DEFAULT_VALUE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryParams = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
for (const [paramName, handler] of Object.entries(handlers)) {
|
||||||
|
const value = queryParams.get(paramName);
|
||||||
|
if (value !== null) {
|
||||||
|
handler(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set(isQueryParamInitializedState, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { initializeQueryParamState };
|
||||||
|
};
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { createState } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
|
export const isQueryParamInitializedState = createState<boolean>({
|
||||||
|
key: 'isQueryParamInitializedState',
|
||||||
|
defaultValue: false,
|
||||||
|
});
|
||||||
@ -10,18 +10,10 @@ const StyledContent = styled.div`
|
|||||||
|
|
||||||
type AuthModalProps = {
|
type AuthModalProps = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
isOpenAnimated?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AuthModal = ({
|
export const AuthModal = ({ children }: AuthModalProps) => (
|
||||||
children,
|
<Modal padding={'none'} modalVariant="primary">
|
||||||
isOpenAnimated = true,
|
|
||||||
}: AuthModalProps) => (
|
|
||||||
<Modal
|
|
||||||
padding={'none'}
|
|
||||||
modalVariant="primary"
|
|
||||||
isOpenAnimated={isOpenAnimated}
|
|
||||||
>
|
|
||||||
<ScrollWrapper componentInstanceId="scroll-wrapper-modal-content">
|
<ScrollWrapper componentInstanceId="scroll-wrapper-modal-content">
|
||||||
<StyledContent>{children}</StyledContent>
|
<StyledContent>{children}</StyledContent>
|
||||||
</ScrollWrapper>
|
</ScrollWrapper>
|
||||||
|
|||||||
@ -4,12 +4,10 @@ import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/Snac
|
|||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
|
|
||||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||||
import { animateModalState } from '@/auth/states/animateModalState';
|
|
||||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||||
import { EmailVerificationSent } from '../sign-in-up/components/EmailVerificationSent';
|
import { EmailVerificationSent } from '../sign-in-up/components/EmailVerificationSent';
|
||||||
@ -21,7 +19,6 @@ export const VerifyEmailEffect = () => {
|
|||||||
|
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const [isError, setIsError] = useState(false);
|
const [isError, setIsError] = useState(false);
|
||||||
const setAnimateModal = useSetRecoilState(animateModalState);
|
|
||||||
|
|
||||||
const email = searchParams.get('email');
|
const email = searchParams.get('email');
|
||||||
const emailVerificationToken = searchParams.get('emailVerificationToken');
|
const emailVerificationToken = searchParams.get('emailVerificationToken');
|
||||||
@ -52,7 +49,6 @@ export const VerifyEmailEffect = () => {
|
|||||||
|
|
||||||
const workspaceUrl = getWorkspaceUrl(workspaceUrls);
|
const workspaceUrl = getWorkspaceUrl(workspaceUrls);
|
||||||
if (workspaceUrl.slice(0, -1) !== window.location.origin) {
|
if (workspaceUrl.slice(0, -1) !== window.location.origin) {
|
||||||
setAnimateModal(false);
|
|
||||||
return await redirectToWorkspaceDomain(workspaceUrl, AppPath.Verify, {
|
return await redirectToWorkspaceDomain(workspaceUrl, AppPath.Verify, {
|
||||||
loginToken: loginToken.token,
|
loginToken: loginToken.token,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -41,7 +41,6 @@ import { getTimeFormatFromWorkspaceTimeFormat } from '@/localization/utils/getTi
|
|||||||
import { currentUserState } from '../states/currentUserState';
|
import { currentUserState } from '../states/currentUserState';
|
||||||
import { tokenPairState } from '../states/tokenPairState';
|
import { tokenPairState } from '../states/tokenPairState';
|
||||||
|
|
||||||
import { animateModalState } from '@/auth/states/animateModalState';
|
|
||||||
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
||||||
import {
|
import {
|
||||||
SignInUpStep,
|
SignInUpStep,
|
||||||
@ -115,7 +114,6 @@ export const useAuth = () => {
|
|||||||
const goToRecoilSnapshot = useGotoRecoilSnapshot();
|
const goToRecoilSnapshot = useGotoRecoilSnapshot();
|
||||||
|
|
||||||
const setDateTimeFormat = useSetRecoilState(dateTimeFormatState);
|
const setDateTimeFormat = useSetRecoilState(dateTimeFormatState);
|
||||||
const setAnimateModal = useSetRecoilState(animateModalState);
|
|
||||||
|
|
||||||
const [, setSearchParams] = useSearchParams();
|
const [, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
@ -422,7 +420,6 @@ export const useAuth = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isMultiWorkspaceEnabled) {
|
if (isMultiWorkspaceEnabled) {
|
||||||
setAnimateModal(false);
|
|
||||||
return await redirectToWorkspaceDomain(
|
return await redirectToWorkspaceDomain(
|
||||||
getWorkspaceUrl(signUpResult.data.signUp.workspace.workspaceUrls),
|
getWorkspaceUrl(signUpResult.data.signUp.workspace.workspaceUrls),
|
||||||
isEmailVerificationRequired ? AppPath.SignInUp : AppPath.Verify,
|
isEmailVerificationRequired ? AppPath.SignInUp : AppPath.Verify,
|
||||||
@ -446,7 +443,6 @@ export const useAuth = () => {
|
|||||||
handleGetAuthTokensFromLoginToken,
|
handleGetAuthTokensFromLoginToken,
|
||||||
setSignInUpStep,
|
setSignInUpStep,
|
||||||
setSearchParams,
|
setSearchParams,
|
||||||
setAnimateModal,
|
|
||||||
isEmailVerificationRequired,
|
isEmailVerificationRequired,
|
||||||
redirectToWorkspaceDomain,
|
redirectToWorkspaceDomain,
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
import { urlSyncEffect } from 'recoil-sync';
|
|
||||||
import { createState } from 'twenty-ui/utilities';
|
|
||||||
|
|
||||||
export const animateModalState = createState<boolean>({
|
|
||||||
key: 'animateModalState',
|
|
||||||
defaultValue: true,
|
|
||||||
effects: [
|
|
||||||
urlSyncEffect({
|
|
||||||
itemKey: 'animateModal',
|
|
||||||
refine: (value: unknown) => {
|
|
||||||
if (typeof value === 'boolean') {
|
|
||||||
return {
|
|
||||||
type: 'success',
|
|
||||||
value: value as boolean,
|
|
||||||
warnings: [],
|
|
||||||
} as const;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'failure',
|
|
||||||
message: 'Invalid animateModalState',
|
|
||||||
path: [] as any,
|
|
||||||
} as const;
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
@ -1,34 +1,8 @@
|
|||||||
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
||||||
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
|
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
|
||||||
import { syncEffect } from 'recoil-sync';
|
|
||||||
import { createState } from 'twenty-ui/utilities';
|
import { createState } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
export const billingCheckoutSessionState = createState<BillingCheckoutSession>({
|
export const billingCheckoutSessionState = createState<BillingCheckoutSession>({
|
||||||
key: 'billingCheckoutSessionState',
|
key: 'billingCheckoutSessionState',
|
||||||
defaultValue: BILLING_CHECKOUT_SESSION_DEFAULT_VALUE,
|
defaultValue: BILLING_CHECKOUT_SESSION_DEFAULT_VALUE,
|
||||||
effects: [
|
|
||||||
syncEffect({
|
|
||||||
itemKey: 'billingCheckoutSession',
|
|
||||||
refine: (value: unknown) => {
|
|
||||||
if (
|
|
||||||
typeof value === 'object' &&
|
|
||||||
value !== null &&
|
|
||||||
'plan' in value &&
|
|
||||||
'interval' in value &&
|
|
||||||
'requirePaymentMethod' in value
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
type: 'success',
|
|
||||||
value: value as BillingCheckoutSession,
|
|
||||||
warnings: [],
|
|
||||||
} as const;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'failure',
|
|
||||||
message: 'Invalid BillingCheckoutSessionState',
|
|
||||||
path: [] as any,
|
|
||||||
} as const;
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { animateModalState } from '@/auth/states/animateModalState';
|
|
||||||
import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState';
|
import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState';
|
||||||
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
|
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
@ -7,7 +6,6 @@ export const useBuildSearchParamsFromUrlSyncedStates = () => {
|
|||||||
const buildSearchParamsFromUrlSyncedStates = useRecoilCallback(
|
const buildSearchParamsFromUrlSyncedStates = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
async () => {
|
async () => {
|
||||||
const animateModal = snapshot.getLoadable(animateModalState).getValue();
|
|
||||||
const billingCheckoutSession = snapshot
|
const billingCheckoutSession = snapshot
|
||||||
.getLoadable(billingCheckoutSessionState)
|
.getLoadable(billingCheckoutSessionState)
|
||||||
.getValue();
|
.getValue();
|
||||||
@ -18,7 +16,6 @@ export const useBuildSearchParamsFromUrlSyncedStates = () => {
|
|||||||
billingCheckoutSession: JSON.stringify(billingCheckoutSession),
|
billingCheckoutSession: JSON.stringify(billingCheckoutSession),
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(animateModal === false ? { animateModal: 'false' } : {}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@ -1,19 +1,15 @@
|
|||||||
import { animateModalState } from '@/auth/states/animateModalState';
|
|
||||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
import { WorkspaceUrls } from '~/generated/graphql';
|
import { WorkspaceUrls } from '~/generated/graphql';
|
||||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||||
|
|
||||||
export const useImpersonationRedirect = () => {
|
export const useImpersonationRedirect = () => {
|
||||||
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
||||||
const setAnimateModal = useSetRecoilState(animateModalState);
|
|
||||||
|
|
||||||
const executeImpersonationRedirect = async (
|
const executeImpersonationRedirect = async (
|
||||||
workspaceUrls: WorkspaceUrls,
|
workspaceUrls: WorkspaceUrls,
|
||||||
loginToken: string,
|
loginToken: string,
|
||||||
) => {
|
) => {
|
||||||
setAnimateModal(false);
|
|
||||||
return await redirectToWorkspaceDomain(
|
return await redirectToWorkspaceDomain(
|
||||||
getWorkspaceUrl(workspaceUrls),
|
getWorkspaceUrl(workspaceUrls),
|
||||||
AppPath.Verify,
|
AppPath.Verify,
|
||||||
|
|||||||
@ -174,7 +174,6 @@ export type ModalProps = React.PropsWithChildren & {
|
|||||||
className?: string;
|
className?: string;
|
||||||
hotkeyScope?: ModalHotkeyScope;
|
hotkeyScope?: ModalHotkeyScope;
|
||||||
onEnter?: () => void;
|
onEnter?: () => void;
|
||||||
isOpenAnimated?: boolean;
|
|
||||||
modalVariant?: ModalVariants;
|
modalVariant?: ModalVariants;
|
||||||
} & (
|
} & (
|
||||||
| { isClosable: true; onClose: () => void }
|
| { isClosable: true; onClose: () => void }
|
||||||
@ -197,7 +196,6 @@ export const Modal = ({
|
|||||||
isClosable = false,
|
isClosable = false,
|
||||||
onClose,
|
onClose,
|
||||||
modalVariant = 'primary',
|
modalVariant = 'primary',
|
||||||
isOpenAnimated = true,
|
|
||||||
}: ModalProps) => {
|
}: ModalProps) => {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const modalRef = useRef<HTMLDivElement>(null);
|
const modalRef = useRef<HTMLDivElement>(null);
|
||||||
@ -263,7 +261,7 @@ export const Modal = ({
|
|||||||
ref={modalRef}
|
ref={modalRef}
|
||||||
size={size}
|
size={size}
|
||||||
padding={padding}
|
padding={padding}
|
||||||
initial={isOpenAnimated ? 'hidden' : 'visible'}
|
initial="hidden"
|
||||||
animate="visible"
|
animate="visible"
|
||||||
exit="exit"
|
exit="exit"
|
||||||
layout
|
layout
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { AuthModal } from '@/auth/components/AuthModal';
|
import { AuthModal } from '@/auth/components/AuthModal';
|
||||||
import { animateModalState } from '@/auth/states/animateModalState';
|
|
||||||
import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter';
|
import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter';
|
||||||
import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary';
|
import { AppErrorBoundary } from '@/error-handler/components/AppErrorBoundary';
|
||||||
import { AppFullScreenErrorFallback } from '@/error-handler/components/AppFullScreenErrorFallback';
|
import { AppFullScreenErrorFallback } from '@/error-handler/components/AppFullScreenErrorFallback';
|
||||||
@ -19,7 +18,6 @@ import { Global, css, useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { AnimatePresence, LayoutGroup, motion } from 'framer-motion';
|
import { AnimatePresence, LayoutGroup, motion } from 'framer-motion';
|
||||||
import { Outlet } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
import { useScreenSize } from 'twenty-ui/utilities';
|
import { useScreenSize } from 'twenty-ui/utilities';
|
||||||
|
|
||||||
const StyledLayout = styled.div`
|
const StyledLayout = styled.div`
|
||||||
@ -65,7 +63,6 @@ export const DefaultLayout = () => {
|
|||||||
const windowsWidth = useScreenSize().width;
|
const windowsWidth = useScreenSize().width;
|
||||||
const showAuthModal = useShowAuthModal();
|
const showAuthModal = useShowAuthModal();
|
||||||
const useShowFullScreen = useShowFullscreen();
|
const useShowFullScreen = useShowFullscreen();
|
||||||
const animateModal = useRecoilValue(animateModalState);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -111,7 +108,7 @@ export const DefaultLayout = () => {
|
|||||||
</StyledMainContainer>
|
</StyledMainContainer>
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
<LayoutGroup>
|
<LayoutGroup>
|
||||||
<AuthModal isOpenAnimated={animateModal}>
|
<AuthModal>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</AuthModal>
|
</AuthModal>
|
||||||
</LayoutGroup>
|
</LayoutGroup>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo';
|
import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo';
|
||||||
|
|
||||||
import { useAuth } from '@/auth/hooks/useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
import { animateModalState } from '@/auth/states/animateModalState';
|
|
||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { Workspaces, workspacesState } from '@/auth/states/workspaces';
|
import { Workspaces, workspacesState } from '@/auth/states/workspaces';
|
||||||
import { useBuildWorkspaceUrl } from '@/domain-manager/hooks/useBuildWorkspaceUrl';
|
import { useBuildWorkspaceUrl } from '@/domain-manager/hooks/useBuildWorkspaceUrl';
|
||||||
@ -67,7 +66,6 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
|||||||
const setMultiWorkspaceDropdownState = useSetRecoilState(
|
const setMultiWorkspaceDropdownState = useSetRecoilState(
|
||||||
multiWorkspaceDropdownState,
|
multiWorkspaceDropdownState,
|
||||||
);
|
);
|
||||||
const setAnimateModal = useSetRecoilState(animateModalState);
|
|
||||||
|
|
||||||
const handleChange = async (workspace: Workspaces[0]) => {
|
const handleChange = async (workspace: Workspaces[0]) => {
|
||||||
redirectToWorkspaceDomain(getWorkspaceUrl(workspace.workspaceUrls));
|
redirectToWorkspaceDomain(getWorkspaceUrl(workspace.workspaceUrls));
|
||||||
@ -76,7 +74,6 @@ export const MultiWorkspaceDropdownDefaultComponents = () => {
|
|||||||
const createWorkspace = () => {
|
const createWorkspace = () => {
|
||||||
signUpInNewWorkspaceMutation({
|
signUpInNewWorkspaceMutation({
|
||||||
onCompleted: async (data) => {
|
onCompleted: async (data) => {
|
||||||
setAnimateModal(false);
|
|
||||||
return await redirectToWorkspaceDomain(
|
return await redirectToWorkspaceDomain(
|
||||||
getWorkspaceUrl(data.signUpInNewWorkspace.workspace.workspaceUrls),
|
getWorkspaceUrl(data.signUpInNewWorkspace.workspace.workspaceUrls),
|
||||||
AppPath.Verify,
|
AppPath.Verify,
|
||||||
|
|||||||
@ -172,7 +172,7 @@ export const ChooseYourPlan = () => {
|
|||||||
?.baseProduct.name;
|
?.baseProduct.name;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal.Content>
|
<Modal.Content isVerticalCentered>
|
||||||
{isDefined(baseProductPrice) && isDefined(billing) ? (
|
{isDefined(baseProductPrice) && isDefined(billing) ? (
|
||||||
<>
|
<>
|
||||||
<Title noMarginTop>
|
<Title noMarginTop>
|
||||||
|
|||||||
27
yarn.lock
27
yarn.lock
@ -16495,13 +16495,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@recoiljs/refine@npm:^0.1.1":
|
|
||||||
version: 0.1.1
|
|
||||||
resolution: "@recoiljs/refine@npm:0.1.1"
|
|
||||||
checksum: 10c0/27ca1c4ea500b1b99a3af5ee48d6749310e5138e83b87ddfb41304e2222fa64567acb985f340334ab73980202ab277a0f133c40817fbec786076c06bfb3f5363
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@redis/bloom@npm:1.2.0, @redis/bloom@npm:^1.2.0":
|
"@redis/bloom@npm:1.2.0, @redis/bloom@npm:^1.2.0":
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
resolution: "@redis/bloom@npm:1.2.0"
|
resolution: "@redis/bloom@npm:1.2.0"
|
||||||
@ -50073,18 +50066,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"recoil-sync@npm:^0.2.0":
|
|
||||||
version: 0.2.0
|
|
||||||
resolution: "recoil-sync@npm:0.2.0"
|
|
||||||
dependencies:
|
|
||||||
"@recoiljs/refine": "npm:^0.1.1"
|
|
||||||
transit-js: "npm:^0.8.874"
|
|
||||||
peerDependencies:
|
|
||||||
recoil: ">=0.7.3"
|
|
||||||
checksum: 10c0/f3a671a3cfcecadb5bbb22d47b3b040721be1013ee91d4fa0570a64ca1707eb68e818b291a82e133551adf4a2dd2fc9a0715d550c1f1e3db82f3b8d9169e2a5a
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"recoil@npm:^0.7.7":
|
"recoil@npm:^0.7.7":
|
||||||
version: 0.7.7
|
version: 0.7.7
|
||||||
resolution: "recoil@npm:0.7.7"
|
resolution: "recoil@npm:0.7.7"
|
||||||
@ -54388,13 +54369,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"transit-js@npm:^0.8.874":
|
|
||||||
version: 0.8.874
|
|
||||||
resolution: "transit-js@npm:0.8.874"
|
|
||||||
checksum: 10c0/6ca0b413f1e3780a4a56b9bbde54b67a2ffefda1c052f8dc68bf28c1a3df4c29baa6f17f60484c9f2fb056a8c7dcd1fe04d24e091fb99afe1525e4d4406ad58a
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"transliteration@npm:^2.3.5":
|
"transliteration@npm:^2.3.5":
|
||||||
version: 2.3.5
|
version: 2.3.5
|
||||||
resolution: "transliteration@npm:2.3.5"
|
resolution: "transliteration@npm:2.3.5"
|
||||||
@ -55005,7 +54979,6 @@ __metadata:
|
|||||||
eslint-plugin-unused-imports: "npm:^3.0.0"
|
eslint-plugin-unused-imports: "npm:^3.0.0"
|
||||||
file-saver: "npm:^2.0.5"
|
file-saver: "npm:^2.0.5"
|
||||||
optionator: "npm:^0.9.1"
|
optionator: "npm:^0.9.1"
|
||||||
recoil-sync: "npm:^0.2.0"
|
|
||||||
transliteration: "npm:^2.3.5"
|
transliteration: "npm:^2.3.5"
|
||||||
twenty-shared: "workspace:*"
|
twenty-shared: "workspace:*"
|
||||||
twenty-ui: "workspace:*"
|
twenty-ui: "workspace:*"
|
||||||
|
|||||||
Reference in New Issue
Block a user