Pass Billing Checkout var in url to bypass credit card (#9283)
This commit is contained in:
@ -31,6 +31,13 @@ We felt the need for a CRM platform that empowers rather than constrains. We bel
|
||||
<br>
|
||||
|
||||
# Demo
|
||||
|
||||
<!--
|
||||
You can use the following url to sign up to the cloud version without providing a credit card:
|
||||
|
||||
<a href="https://demo.twenty.com/?billingCheckoutSession={"plan":"PRO","recurringInterval":"MONTHLY","requirePaymentMethod":false,"skipPlanPage":true}">https://demo.twenty.com/?billingCheckoutSession={"plan":"PRO","recurringInterval":"MONTHLY","requirePaymentMethod":false,"skipPlanPage":true}</a>
|
||||
|
||||
-->
|
||||
Go to <a href="https://demo.twenty.com/">demo.twenty.com</a> and login with the following credentials:
|
||||
|
||||
```
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
"buffer": "^6.0.3",
|
||||
"docx": "^9.1.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"recoil-sync": "^0.2.0",
|
||||
"transliteration": "^2.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -115,6 +115,13 @@ export type Billing = {
|
||||
isBillingEnabled: Scalars['Boolean'];
|
||||
};
|
||||
|
||||
/** The different billing plans available */
|
||||
export enum BillingPlanKey {
|
||||
Base = 'BASE',
|
||||
Enterprise = 'ENTERPRISE',
|
||||
Pro = 'PRO'
|
||||
}
|
||||
|
||||
export type BillingSubscription = {
|
||||
__typename?: 'BillingSubscription';
|
||||
id: Scalars['UUID'];
|
||||
@ -182,6 +189,30 @@ export type ComputeStepOutputSchemaInput = {
|
||||
step: Scalars['JSON'];
|
||||
};
|
||||
|
||||
export type CreateFieldInput = {
|
||||
defaultValue?: InputMaybe<Scalars['JSON']>;
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
icon?: InputMaybe<Scalars['String']>;
|
||||
isActive?: InputMaybe<Scalars['Boolean']>;
|
||||
isCustom?: InputMaybe<Scalars['Boolean']>;
|
||||
isLabelSyncedWithName?: InputMaybe<Scalars['Boolean']>;
|
||||
isNullable?: InputMaybe<Scalars['Boolean']>;
|
||||
isRemoteCreation?: InputMaybe<Scalars['Boolean']>;
|
||||
isSystem?: InputMaybe<Scalars['Boolean']>;
|
||||
isUnique?: InputMaybe<Scalars['Boolean']>;
|
||||
label: Scalars['String'];
|
||||
name: Scalars['String'];
|
||||
objectMetadataId: Scalars['String'];
|
||||
options?: InputMaybe<Scalars['JSON']>;
|
||||
settings?: InputMaybe<Scalars['JSON']>;
|
||||
type: FieldMetadataType;
|
||||
};
|
||||
|
||||
export type CreateOneFieldMetadataInput = {
|
||||
/** The record to create */
|
||||
field: CreateFieldInput;
|
||||
};
|
||||
|
||||
export type CreateServerlessFunctionInput = {
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
name: Scalars['String'];
|
||||
@ -205,6 +236,11 @@ export type CursorPaging = {
|
||||
last?: InputMaybe<Scalars['Int']>;
|
||||
};
|
||||
|
||||
export type DeleteOneFieldInput = {
|
||||
/** The id of the field to delete. */
|
||||
id: Scalars['UUID'];
|
||||
};
|
||||
|
||||
export type DeleteOneObjectInput = {
|
||||
/** The id of the record to delete. */
|
||||
id: Scalars['UUID'];
|
||||
@ -447,12 +483,14 @@ export type Mutation = {
|
||||
computeStepOutputSchema: Scalars['JSON'];
|
||||
createOIDCIdentityProvider: SetupSsoOutput;
|
||||
createOneAppToken: AppToken;
|
||||
createOneField: Field;
|
||||
createOneObject: Object;
|
||||
createOneServerlessFunction: ServerlessFunction;
|
||||
createSAMLIdentityProvider: SetupSsoOutput;
|
||||
createWorkflowVersionStep: WorkflowAction;
|
||||
deactivateWorkflowVersion: Scalars['Boolean'];
|
||||
deleteCurrentWorkspace: Workspace;
|
||||
deleteOneField: Field;
|
||||
deleteOneObject: Object;
|
||||
deleteOneServerlessFunction: ServerlessFunction;
|
||||
deleteSSOIdentityProvider: DeleteSsoOutput;
|
||||
@ -478,6 +516,7 @@ export type Mutation = {
|
||||
switchWorkspace: PublicWorkspaceDataOutput;
|
||||
track: Analytics;
|
||||
updateBillingSubscription: UpdateBillingEntity;
|
||||
updateOneField: Field;
|
||||
updateOneObject: Object;
|
||||
updateOneServerlessFunction: ServerlessFunction;
|
||||
updatePasswordViaResetToken: InvalidatePassword;
|
||||
@ -528,7 +567,9 @@ export type MutationChallengeArgs = {
|
||||
|
||||
|
||||
export type MutationCheckoutSessionArgs = {
|
||||
plan?: BillingPlanKey;
|
||||
recurringInterval: SubscriptionInterval;
|
||||
requirePaymentMethod?: Scalars['Boolean'];
|
||||
successUrlPath?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
@ -543,6 +584,11 @@ export type MutationCreateOidcIdentityProviderArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationCreateOneFieldArgs = {
|
||||
input: CreateOneFieldMetadataInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationCreateOneServerlessFunctionArgs = {
|
||||
input: CreateServerlessFunctionInput;
|
||||
};
|
||||
@ -563,6 +609,11 @@ export type MutationDeactivateWorkflowVersionArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteOneFieldArgs = {
|
||||
input: DeleteOneFieldInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteOneObjectArgs = {
|
||||
input: DeleteOneObjectInput;
|
||||
};
|
||||
@ -665,6 +716,11 @@ export type MutationTrackArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateOneFieldArgs = {
|
||||
input: UpdateOneFieldMetadataInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateOneObjectArgs = {
|
||||
input: UpdateOneObjectInput;
|
||||
};
|
||||
@ -825,6 +881,8 @@ export type Query = {
|
||||
clientConfig: ClientConfig;
|
||||
currentUser: User;
|
||||
currentWorkspace: Workspace;
|
||||
field: Field;
|
||||
fields: FieldConnection;
|
||||
findAvailableWorkspacesByEmail: Array<AvailableWorkspaceOutput>;
|
||||
findManyServerlessFunctions: Array<ServerlessFunction>;
|
||||
findOneServerlessFunction: ServerlessFunction;
|
||||
@ -1241,6 +1299,22 @@ export type UpdateBillingEntity = {
|
||||
success: Scalars['Boolean'];
|
||||
};
|
||||
|
||||
export type UpdateFieldInput = {
|
||||
defaultValue?: InputMaybe<Scalars['JSON']>;
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
icon?: InputMaybe<Scalars['String']>;
|
||||
isActive?: InputMaybe<Scalars['Boolean']>;
|
||||
isCustom?: InputMaybe<Scalars['Boolean']>;
|
||||
isLabelSyncedWithName?: InputMaybe<Scalars['Boolean']>;
|
||||
isNullable?: InputMaybe<Scalars['Boolean']>;
|
||||
isSystem?: InputMaybe<Scalars['Boolean']>;
|
||||
isUnique?: InputMaybe<Scalars['Boolean']>;
|
||||
label?: InputMaybe<Scalars['String']>;
|
||||
name?: InputMaybe<Scalars['String']>;
|
||||
options?: InputMaybe<Scalars['JSON']>;
|
||||
settings?: InputMaybe<Scalars['JSON']>;
|
||||
};
|
||||
|
||||
export type UpdateObjectPayload = {
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
icon?: InputMaybe<Scalars['String']>;
|
||||
@ -1255,6 +1329,13 @@ export type UpdateObjectPayload = {
|
||||
shortcut?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type UpdateOneFieldMetadataInput = {
|
||||
/** The id of the record to update */
|
||||
id: Scalars['UUID'];
|
||||
/** The record to update */
|
||||
update: UpdateFieldInput;
|
||||
};
|
||||
|
||||
export type UpdateOneObjectInput = {
|
||||
/** The id of the object to update */
|
||||
id: Scalars['UUID'];
|
||||
@ -1944,6 +2025,8 @@ export type BillingPortalSessionQuery = { __typename?: 'Query', billingPortalSes
|
||||
export type CheckoutSessionMutationVariables = Exact<{
|
||||
recurringInterval: SubscriptionInterval;
|
||||
successUrlPath?: InputMaybe<Scalars['String']>;
|
||||
plan: BillingPlanKey;
|
||||
requirePaymentMethod: Scalars['Boolean'];
|
||||
}>;
|
||||
|
||||
|
||||
@ -3234,10 +3317,12 @@ export type BillingPortalSessionQueryHookResult = ReturnType<typeof useBillingPo
|
||||
export type BillingPortalSessionLazyQueryHookResult = ReturnType<typeof useBillingPortalSessionLazyQuery>;
|
||||
export type BillingPortalSessionQueryResult = Apollo.QueryResult<BillingPortalSessionQuery, BillingPortalSessionQueryVariables>;
|
||||
export const CheckoutSessionDocument = gql`
|
||||
mutation CheckoutSession($recurringInterval: SubscriptionInterval!, $successUrlPath: String) {
|
||||
mutation CheckoutSession($recurringInterval: SubscriptionInterval!, $successUrlPath: String, $plan: BillingPlanKey!, $requirePaymentMethod: Boolean!) {
|
||||
checkoutSession(
|
||||
recurringInterval: $recurringInterval
|
||||
successUrlPath: $successUrlPath
|
||||
plan: $plan
|
||||
requirePaymentMethod: $requirePaymentMethod
|
||||
) {
|
||||
url
|
||||
}
|
||||
@ -3260,6 +3345,8 @@ export type CheckoutSessionMutationFn = Apollo.MutationFunction<CheckoutSessionM
|
||||
* variables: {
|
||||
* recurringInterval: // value for 'recurringInterval'
|
||||
* successUrlPath: // value for 'successUrlPath'
|
||||
* plan: // value for 'plan'
|
||||
* requirePaymentMethod: // value for 'requirePaymentMethod'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const copilotQueryState = createState({
|
||||
key: 'activities/copilot-query',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const emailThreadIdWhenEmailThreadWasClosedState = createState<
|
||||
string | null
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { ActivityTargetableObject } from '../types/ActivityTargetableEntity';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const canCreateActivityState = createState<boolean>({
|
||||
key: 'canCreateActivityState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isActivityInCreateModeState = createState<boolean>({
|
||||
key: 'isActivityInCreateModeState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isUpsertingActivityInDBState = createState<boolean>({
|
||||
key: 'isUpsertingActivityInDBState',
|
||||
|
||||
@ -7,26 +7,29 @@ import { ExceptionHandlerProvider } from '@/error-handler/components/ExceptionHa
|
||||
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||
import { HelmetProvider } from 'react-helmet-async';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { RecoilURLSyncJSON } from 'recoil-sync';
|
||||
import { IconsProvider } from 'twenty-ui';
|
||||
|
||||
export const App = () => {
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<AppErrorBoundary>
|
||||
<CaptchaProvider>
|
||||
<RecoilDebugObserverEffect />
|
||||
<ApolloDevLogEffect />
|
||||
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||
<IconsProvider>
|
||||
<ExceptionHandlerProvider>
|
||||
<HelmetProvider>
|
||||
<AppRouter />
|
||||
</HelmetProvider>
|
||||
</ExceptionHandlerProvider>
|
||||
</IconsProvider>
|
||||
</SnackBarProviderScope>
|
||||
</CaptchaProvider>
|
||||
</AppErrorBoundary>
|
||||
<RecoilURLSyncJSON location={{ part: 'queryParams' }}>
|
||||
<AppErrorBoundary>
|
||||
<CaptchaProvider>
|
||||
<RecoilDebugObserverEffect />
|
||||
<ApolloDevLogEffect />
|
||||
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||
<IconsProvider>
|
||||
<ExceptionHandlerProvider>
|
||||
<HelmetProvider>
|
||||
<AppRouter />
|
||||
</HelmetProvider>
|
||||
</ExceptionHandlerProvider>
|
||||
</IconsProvider>
|
||||
</SnackBarProviderScope>
|
||||
</CaptchaProvider>
|
||||
</AppErrorBoundary>
|
||||
</RecoilURLSyncJSON>
|
||||
</RecoilRoot>
|
||||
);
|
||||
};
|
||||
|
||||
@ -43,16 +43,17 @@ import { getTimeFormatFromWorkspaceTimeFormat } from '@/localization/utils/getTi
|
||||
import { currentUserState } from '../states/currentUserState';
|
||||
import { tokenPairState } from '../states/tokenPairState';
|
||||
|
||||
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
||||
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
|
||||
import { useIsCurrentLocationOnAWorkspaceSubdomain } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspaceSubdomain';
|
||||
import { useLastAuthenticatedWorkspaceDomain } from '@/domain-manager/hooks/useLastAuthenticatedWorkspaceDomain';
|
||||
import { useReadWorkspaceSubdomainFromCurrentLocation } from '@/domain-manager/hooks/useReadWorkspaceSubdomainFromCurrentLocation';
|
||||
import { useRedirect } from '@/domain-manager/hooks/useRedirect';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
|
||||
import { isAppWaitingForFreshObjectMetadataState } from '@/object-metadata/states/isAppWaitingForFreshObjectMetadataState';
|
||||
import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthProvidersState';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { useRedirect } from '@/domain-manager/hooks/useRedirect';
|
||||
import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthProvidersState';
|
||||
|
||||
export const useAuth = () => {
|
||||
const setTokenPair = useSetRecoilState(tokenPairState);
|
||||
@ -382,6 +383,7 @@ export const useAuth = () => {
|
||||
params: {
|
||||
workspacePersonalInviteToken?: string;
|
||||
workspaceInviteHash?: string;
|
||||
billingCheckoutSession?: BillingCheckoutSession;
|
||||
},
|
||||
) => {
|
||||
const url = new URL(`${REACT_APP_SERVER_BASE_URL}${path}`);
|
||||
@ -394,6 +396,12 @@ export const useAuth = () => {
|
||||
params.workspacePersonalInviteToken,
|
||||
);
|
||||
}
|
||||
if (isDefined(params.billingCheckoutSession)) {
|
||||
url.searchParams.set(
|
||||
'billingCheckoutSessionState',
|
||||
JSON.stringify(params.billingCheckoutSession),
|
||||
);
|
||||
}
|
||||
|
||||
if (isDefined(workspaceSubdomain)) {
|
||||
url.searchParams.set('workspaceSubdomain', workspaceSubdomain);
|
||||
@ -408,6 +416,7 @@ export const useAuth = () => {
|
||||
(params: {
|
||||
workspacePersonalInviteToken?: string;
|
||||
workspaceInviteHash?: string;
|
||||
billingCheckoutSession?: BillingCheckoutSession;
|
||||
}) => {
|
||||
redirect(buildRedirectUrl('/auth/google', params));
|
||||
},
|
||||
@ -418,6 +427,7 @@ export const useAuth = () => {
|
||||
(params: {
|
||||
workspacePersonalInviteToken?: string;
|
||||
workspaceInviteHash?: string;
|
||||
billingCheckoutSession?: BillingCheckoutSession;
|
||||
}) => {
|
||||
redirect(buildRedirectUrl('/auth/microsoft', params));
|
||||
},
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { useSignInWithGoogle } from '@/auth/sign-in-up/hooks/useSignInWithGoogle';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { BillingPlanKey, SubscriptionInterval } from '~/generated/graphql';
|
||||
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useParams: jest.fn(),
|
||||
@ -13,10 +15,24 @@ jest.mock('@/auth/hooks/useAuth', () => ({
|
||||
}));
|
||||
|
||||
describe('useSignInWithGoogle', () => {
|
||||
const mockBillingCheckoutSession = {
|
||||
plan: BillingPlanKey.Pro,
|
||||
interval: SubscriptionInterval.Month,
|
||||
requirePaymentMethod: true,
|
||||
skipPlanPage: false,
|
||||
};
|
||||
|
||||
const Wrapper = getJestMetadataAndApolloMocksWrapper({
|
||||
apolloMocks: [],
|
||||
});
|
||||
|
||||
it('should call signInWithGoogle with correct params', () => {
|
||||
const signInWithGoogleMock = jest.fn();
|
||||
const mockUseParams = { workspaceInviteHash: 'testHash' };
|
||||
const mockSearchParams = new URLSearchParams('inviteToken=testToken');
|
||||
|
||||
const mockSearchParams = new URLSearchParams(
|
||||
'inviteToken=testToken&billingCheckoutSessionState={"plan":"Pro","interval":"Month","requirePaymentMethod":true,"skipPlanPage":false}',
|
||||
);
|
||||
|
||||
(useParams as jest.Mock).mockReturnValue(mockUseParams);
|
||||
(useSearchParams as jest.Mock).mockReturnValue([mockSearchParams]);
|
||||
@ -24,12 +40,15 @@ describe('useSignInWithGoogle', () => {
|
||||
signInWithGoogle: signInWithGoogleMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithGoogle());
|
||||
const { result } = renderHook(() => useSignInWithGoogle(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
result.current.signInWithGoogle();
|
||||
|
||||
expect(signInWithGoogleMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: 'testHash',
|
||||
workspacePersonalInviteToken: 'testToken',
|
||||
billingCheckoutSession: mockBillingCheckoutSession,
|
||||
});
|
||||
});
|
||||
|
||||
@ -44,12 +63,15 @@ describe('useSignInWithGoogle', () => {
|
||||
signInWithGoogle: signInWithGoogleMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithGoogle());
|
||||
const { result } = renderHook(() => useSignInWithGoogle(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
result.current.signInWithGoogle();
|
||||
|
||||
expect(signInWithGoogleMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: 'testHash',
|
||||
workspacePersonalInviteToken: undefined,
|
||||
billingCheckoutSession: mockBillingCheckoutSession,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { useSignInWithMicrosoft } from '@/auth/sign-in-up/hooks/useSignInWithMicrosoft';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useParams: jest.fn(),
|
||||
@ -13,6 +14,17 @@ jest.mock('@/auth/hooks/useAuth', () => ({
|
||||
}));
|
||||
|
||||
describe('useSignInWithMicrosoft', () => {
|
||||
const Wrapper = getJestMetadataAndApolloMocksWrapper({
|
||||
apolloMocks: [],
|
||||
});
|
||||
|
||||
const mockBillingCheckoutSession = {
|
||||
plan: 'PRO',
|
||||
interval: 'Month',
|
||||
requirePaymentMethod: true,
|
||||
skipPlanPage: false,
|
||||
};
|
||||
|
||||
it('should call signInWithMicrosoft with the correct parameters', () => {
|
||||
const workspaceInviteHashMock = 'testHash';
|
||||
const inviteTokenMock = 'testToken';
|
||||
@ -28,12 +40,15 @@ describe('useSignInWithMicrosoft', () => {
|
||||
signInWithMicrosoft: signInWithMicrosoftMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithMicrosoft());
|
||||
const { result } = renderHook(() => useSignInWithMicrosoft(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
result.current.signInWithMicrosoft();
|
||||
|
||||
expect(signInWithMicrosoftMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: workspaceInviteHashMock,
|
||||
workspacePersonalInviteToken: inviteTokenMock,
|
||||
billingCheckoutSession: mockBillingCheckoutSession,
|
||||
});
|
||||
});
|
||||
|
||||
@ -49,10 +64,13 @@ describe('useSignInWithMicrosoft', () => {
|
||||
signInWithMicrosoft: signInWithMicrosoftMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithMicrosoft());
|
||||
const { result } = renderHook(() => useSignInWithMicrosoft(), {
|
||||
wrapper: Wrapper,
|
||||
});
|
||||
result.current.signInWithMicrosoft();
|
||||
|
||||
expect(signInWithMicrosoftMock).toHaveBeenCalledWith({
|
||||
billingCheckoutSession: mockBillingCheckoutSession,
|
||||
workspaceInviteHash: workspaceInviteHashMock,
|
||||
workspacePersonalInviteToken: undefined,
|
||||
});
|
||||
|
||||
@ -1,15 +1,27 @@
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
||||
|
||||
export const useSignInWithGoogle = () => {
|
||||
const workspaceInviteHash = useParams().workspaceInviteHash;
|
||||
const [searchParams] = useSearchParams();
|
||||
const workspacePersonalInviteToken =
|
||||
searchParams.get('inviteToken') ?? undefined;
|
||||
const billingCheckoutSession = {
|
||||
plan: 'PRO',
|
||||
interval: 'Month',
|
||||
requirePaymentMethod: true,
|
||||
skipPlanPage: false,
|
||||
} as BillingCheckoutSession;
|
||||
|
||||
const { signInWithGoogle } = useAuth();
|
||||
return {
|
||||
signInWithGoogle: () =>
|
||||
signInWithGoogle({ workspaceInviteHash, workspacePersonalInviteToken }),
|
||||
signInWithGoogle({
|
||||
workspaceInviteHash,
|
||||
workspacePersonalInviteToken,
|
||||
billingCheckoutSession,
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,18 +1,23 @@
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
export const useSignInWithMicrosoft = () => {
|
||||
const workspaceInviteHash = useParams().workspaceInviteHash;
|
||||
const [searchParams] = useSearchParams();
|
||||
const workspacePersonalInviteToken =
|
||||
searchParams.get('inviteToken') ?? undefined;
|
||||
const billingCheckoutSession = useRecoilValue(billingCheckoutSessionState);
|
||||
|
||||
const { signInWithMicrosoft } = useAuth();
|
||||
return {
|
||||
signInWithMicrosoft: () =>
|
||||
signInWithMicrosoft({
|
||||
workspaceInviteHash,
|
||||
workspacePersonalInviteToken,
|
||||
billingCheckoutSession,
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { UserExists } from '~/generated/graphql';
|
||||
|
||||
export const availableSSOIdentityProvidersForAuthState = createState<
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { syncEffect } from 'recoil-sync';
|
||||
import { BillingPlanKey, SubscriptionInterval } from '~/generated/graphql';
|
||||
|
||||
export const billingCheckoutSessionState = createState<BillingCheckoutSession>({
|
||||
key: 'billingCheckoutSessionState',
|
||||
defaultValue: {
|
||||
plan: BillingPlanKey.Pro,
|
||||
interval: SubscriptionInterval.Month,
|
||||
requirePaymentMethod: true,
|
||||
skipPlanPage: false,
|
||||
},
|
||||
effects: [
|
||||
syncEffect({
|
||||
refine: (value: unknown) => {
|
||||
if (
|
||||
typeof value === 'object' &&
|
||||
value !== null &&
|
||||
'plan' in value &&
|
||||
'interval' in value &&
|
||||
'requirePaymentMethod' in value &&
|
||||
'skipPlanPage' 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,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { User } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { CurrentWorkspaceMember } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const currentWorkspaceMembersState = createState<
|
||||
CurrentWorkspaceMember[]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Workspace } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isCurrentUserLoadedState = createState<boolean>({
|
||||
key: 'isCurrentUserLoadedState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isVerifyPendingState = createState<boolean>({
|
||||
key: 'isVerifyPendingState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const previousUrlState = createState<string>({
|
||||
key: 'previousUrlState',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { SignInUpMode } from '@/auth/types/signInUpMode';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const signInUpModeState = createState<SignInUpMode>({
|
||||
key: 'signInUpModeState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export enum SignInUpStep {
|
||||
Init = 'init',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { AuthTokenPair } from '~/generated/graphql';
|
||||
import { cookieStorageEffect } from '~/utils/recoil-effects';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { PublicWorkspaceDataOutput } from '~/generated/graphql';
|
||||
|
||||
export const workspacePublicDataState =
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Workspace } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import { SubscriptionInterval } from '~/generated-metadata/graphql';
|
||||
import { BillingPlanKey } from '~/generated/graphql';
|
||||
|
||||
export type BillingCheckoutSession = {
|
||||
plan: BillingPlanKey;
|
||||
interval: SubscriptionInterval;
|
||||
requirePaymentMethod: boolean;
|
||||
skipPlanPage: boolean;
|
||||
};
|
||||
@ -4,10 +4,14 @@ export const CHECKOUT_SESSION = gql`
|
||||
mutation CheckoutSession(
|
||||
$recurringInterval: SubscriptionInterval!
|
||||
$successUrlPath: String
|
||||
$plan: BillingPlanKey!
|
||||
$requirePaymentMethod: Boolean!
|
||||
) {
|
||||
checkoutSession(
|
||||
recurringInterval: $recurringInterval
|
||||
successUrlPath: $successUrlPath
|
||||
plan: $plan
|
||||
requirePaymentMethod: $requirePaymentMethod
|
||||
) {
|
||||
url
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const captchaTokenState = createState<string | undefined>({
|
||||
key: 'captchaTokenState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isCaptchaScriptLoadedState = createState<boolean>({
|
||||
key: 'isCaptchaScriptLoadedState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRequestingCaptchaTokenState = createState<boolean>({
|
||||
key: 'isRequestingCaptchaTokenState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isLoadingTokensFromExtensionState = createState<boolean | null>({
|
||||
key: 'isLoadingTokensFromExtensionState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { ApiConfig } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { AuthProviders } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Billing } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Captcha } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const chromeExtensionIdState = createState<string | null | undefined>({
|
||||
key: 'chromeExtensionIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
type ClientConfigApiStatus = {
|
||||
isLoaded: boolean;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isAnalyticsEnabledState = createState<boolean>({
|
||||
key: 'isAnalyticsEnabled',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isDebugModeState = createState<boolean>({
|
||||
key: 'isDebugModeState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isDeveloperDefaultSignInPrefilledState = createState<boolean>({
|
||||
key: 'isDeveloperDefaultSignInPrefilledState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isMultiWorkspaceEnabledState = createState<boolean>({
|
||||
key: 'isMultiWorkspaceEnabled',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isSSOEnabledState = createState<boolean>({
|
||||
key: 'isSSOEnabledState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Sentry } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Support } from '~/generated/graphql';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const commandMenuSearchState = createState<string>({
|
||||
key: 'command-menu/commandMenuSearchState',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { CONTEXT_STORE_INSTANCE_ID_DEFAULT_VALUE } from '@/context-store/constants/ContextStoreInstanceIdDefaultValue';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const mainContextStoreComponentInstanceIdState = createState<string>({
|
||||
key: 'mainContextStoreComponentInstanceIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { ClientConfig } from '~/generated/graphql';
|
||||
|
||||
export const domainConfigurationState = createState<
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { cookieStorageEffect } from '~/utils/recoil-effects';
|
||||
import { createState } from 'twenty-ui';
|
||||
|
||||
export const lastAuthenticatedWorkspaceDomainState = createState<
|
||||
| {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { DateFormat } from '@/localization/constants/DateFormat';
|
||||
import { TimeFormat } from '@/localization/constants/TimeFormat';
|
||||
import { detectTimeZone } from '@/localization/utils/detectTimeZone';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const dateTimeFormatState = createState<{
|
||||
timeZone: string;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const currentMobileNavigationDrawerState = createState<
|
||||
'main' | 'settings'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isAppWaitingForFreshObjectMetadataState = createState<boolean>({
|
||||
key: 'isAppWaitingForFreshObjectMetadataState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
type AggregateOperation = {
|
||||
operation: AGGREGATE_OPERATIONS | null;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const lastShowPageRecordIdState = createState<string | null>({
|
||||
key: 'lastShowPageRecordIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Filter } from '@/object-record/object-filter-dropdown/types/Filter';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const recordIndexIsCompactModeActiveState = createState<boolean>({
|
||||
key: 'recordIndexIsCompactModeActiveState',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export type KanbanAggregateOperation = {
|
||||
operation?: AGGREGATE_OPERATIONS | null;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const recordIndexKanbanFieldMetadataIdState = createState<string | null>(
|
||||
{
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { Sort } from '@/object-record/object-sort-dropdown/types/Sort';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const recordIndexViewFilterGroupsState = createState<ViewFilterGroup[]>({
|
||||
key: 'recordIndexViewFilterGroupsState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isNewViewableRecordLoadingState = createState<boolean>({
|
||||
key: 'activities/is-new-viewable-record-loading',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const viewableRecordIdState = createState<string | null>({
|
||||
key: 'activities/viewable-record-id',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const viewableRecordNameSingularState = createState<string | null>({
|
||||
key: 'activities/viewable-record-name-singular',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { ReactNode, act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { createState } from 'twenty-ui';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { ReactNode, act } from 'react';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { createState } from 'twenty-ui';
|
||||
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNamePlural } from '@/object-metadata/types/CoreObjectNamePlural';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRemoveSortingModalOpenState = createState<boolean>({
|
||||
key: 'isRemoveSortingModalOpenState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isSoftFocusUsingMouseState = createState<boolean>({
|
||||
key: 'isSoftFocusUsingMouseState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const settingsPreviewRecordIdState = createState<string | null>({
|
||||
key: 'settingsPreviewRecordIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const apiKeyTokenState = createState<string | null>({
|
||||
key: 'apiKeyTokenState',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* @license Enterprise */
|
||||
|
||||
import { SSOIdentityProvider } from '@/settings/security/types/SSOIdentityProvider';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const SSOIdentitiesProvidersState = createState<
|
||||
Omit<SSOIdentityProvider, '__typename'>[]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { SpreadsheetImportDialogOptions } from '../types';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const activeDropdownFocusIdState = createState<string | null>({
|
||||
key: 'activeDropdownFocusIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const previousDropdownFocusIdState = createState<string | null>({
|
||||
key: 'previousDropdownFocusIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRightDrawerAnimationCompletedState = createState<boolean>({
|
||||
key: 'isRightDrawerAnimationCompletedState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRightDrawerMinimizedState = createState<boolean>({
|
||||
key: 'ui/layout/is-right-drawer-minimized',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRightDrawerOpenState = createState<boolean>({
|
||||
key: 'ui/layout/is-right-drawer-open',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { MessageThread } from '@/activities/emails/types/MessageThread';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const rightDrawerCloseEventState = createState<Event | null>({
|
||||
key: 'rightDrawerCloseEventState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { RightDrawerTopBarDropdownButtons } from '@/ui/layout/right-drawer/types/RightDrawerTopBarDropdownButtons';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { RightDrawerPages } from '../types/RightDrawerPages';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const isDefaultLayoutAuthModalVisibleState = createState<boolean>({
|
||||
key: 'isDefaultLayoutAuthModalVisibleState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const navigationMemorizedUrlState = createState<string>({
|
||||
key: 'navigationMemorizedUrlState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export type StepsState = {
|
||||
activeStep: number;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { INITIAL_HOTKEYS_SCOPE } from '../../constants/InitialHotkeysScope';
|
||||
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const internalHotkeysEnabledScopesState = createState<string[]>({
|
||||
key: 'internalHotkeysEnabledScopesState',
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
import { Keys } from 'react-hotkeys-hook/dist/types';
|
||||
import { createState } from 'twenty-ui';
|
||||
|
||||
export const pendingHotkeyState = createState<Keys | null>({
|
||||
key: 'pendingHotkeyState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const currentPageLocationState = createState<string>({
|
||||
key: 'currentPageLocationState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const openOverrideWorkflowDraftConfirmationModalState =
|
||||
createState<boolean>({
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const workflowCreateStepFromParentStepIdState = createState<
|
||||
string | undefined
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { WorkflowDiagram } from '@/workflow/types/WorkflowDiagram';
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const workflowDiagramState = createState<WorkflowDiagram | undefined>({
|
||||
key: 'workflowDiagramState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const workflowDiagramTriggerNodeSelectionState = createState<
|
||||
string | undefined
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const workflowIdState = createState<string | undefined>({
|
||||
key: 'workflowIdState',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createState } from 'twenty-ui';
|
||||
import { createState } from '@ui/utilities/state/utils/createState';
|
||||
|
||||
export const workflowLastCreatedStepIdState = createState<string | undefined>({
|
||||
key: 'workflowLastCreatedStepIdState',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user