diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 0d542cf7dc..71b16415c1 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1469,6 +1469,7 @@ export type DomainValidRecords = { __typename?: 'DomainValidRecords'; domain: Scalars['String']['output']; id: Scalars['UUID']['output']; + isCustomDomainEnabled?: Maybe; records: Array; }; @@ -8613,7 +8614,7 @@ export type UploadWorkspaceLogoMutation = { __typename?: 'Mutation', uploadWorks export type CheckCustomDomainValidRecordsMutationVariables = Exact<{ [key: string]: never; }>; -export type CheckCustomDomainValidRecordsMutation = { __typename?: 'Mutation', checkCustomDomainValidRecords?: { __typename?: 'DomainValidRecords', id: string, domain: string, records: Array<{ __typename?: 'DomainRecord', type: string, key: string, value: string, validationType: string, status: string }> } | null }; +export type CheckCustomDomainValidRecordsMutation = { __typename?: 'Mutation', checkCustomDomainValidRecords?: { __typename?: 'DomainValidRecords', id: string, domain: string, isCustomDomainEnabled?: boolean | null, records: Array<{ __typename?: 'DomainRecord', type: string, key: string, value: string, validationType: string, status: string }> } | null }; export type GetAiSystemPromptPreviewQueryVariables = Exact<{ [key: string]: never; }>; @@ -8953,7 +8954,7 @@ export const ActivateWorkspaceDocument = {"kind":"Document","definitions":[{"kin export const DeleteCurrentWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteCurrentWorkspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteCurrentWorkspace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const UpdateWorkspaceDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateWorkspace"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateWorkspaceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateWorkspace"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"customDomain"}},{"kind":"Field","name":{"kind":"Name","value":"subdomain"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"allowImpersonation"}},{"kind":"Field","name":{"kind":"Name","value":"isPublicInviteLinkEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isGoogleAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isMicrosoftAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isPasswordAuthEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"isTwoFactorAuthenticationEnforced"}},{"kind":"Field","name":{"kind":"Name","value":"isInternalMessagesImportEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRole"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"RoleFragment"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RoleFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Role"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"isEditable"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToUsers"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToAgents"}},{"kind":"Field","name":{"kind":"Name","value":"canBeAssignedToApiKeys"}}]}}]} as unknown as DocumentNode; export const UploadWorkspaceLogoDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UploadWorkspaceLogo"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"file"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Upload"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadWorkspaceLogo"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"file"},"value":{"kind":"Variable","name":{"kind":"Name","value":"file"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]} as unknown as DocumentNode; -export const CheckCustomDomainValidRecordsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CheckCustomDomainValidRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkCustomDomainValidRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"validationType"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CheckCustomDomainValidRecordsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CheckCustomDomainValidRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"checkCustomDomainValidRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isCustomDomainEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"records"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"validationType"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]}}]} as unknown as DocumentNode; export const GetAiSystemPromptPreviewDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetAiSystemPromptPreview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAiSystemPromptPreview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sections"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"estimatedTokenCount"}}]}},{"kind":"Field","name":{"kind":"Name","value":"estimatedTokenCount"}}]}}]}}]} as unknown as DocumentNode; export const GetPublicWorkspaceDataByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetPublicWorkspaceDataById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getPublicWorkspaceDataById"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}}]}}]}}]} as unknown as DocumentNode; export const GetWorkspaceFromInviteHashDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetWorkspaceFromInviteHash"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inviteHash"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findWorkspaceFromInviteHash"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"inviteHash"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inviteHash"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"displayName"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"allowImpersonation"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx b/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx index a8f584b86d..83edb0f91a 100644 --- a/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx +++ b/packages/twenty-front/src/modules/settings/domains/components/SettingsCustomDomain.tsx @@ -110,7 +110,7 @@ export const SettingsCustomDomain = () => { Icon={IconReload} title={t`Reload`} variant="primary" - onClick={checkCustomDomainRecords} + onClick={() => checkCustomDomainRecords()} type="button" /> diff --git a/packages/twenty-front/src/modules/settings/domains/hooks/useCheckCustomDomainValidRecords.ts b/packages/twenty-front/src/modules/settings/domains/hooks/useCheckCustomDomainValidRecords.ts index 98ae922aa2..d8484ef234 100644 --- a/packages/twenty-front/src/modules/settings/domains/hooks/useCheckCustomDomainValidRecords.ts +++ b/packages/twenty-front/src/modules/settings/domains/hooks/useCheckCustomDomainValidRecords.ts @@ -5,21 +5,24 @@ import { isDefined } from 'twenty-shared/utils'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { customDomainRecordsState } from '@/settings/domains/states/customDomainRecordsState'; import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState'; -import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; export const useCheckCustomDomainValidRecords = () => { const [checkCustomDomainValidRecords] = useMutation( CheckCustomDomainValidRecordsDocument, ); const { enqueueErrorSnackBar } = useSnackBar(); - const currentWorkspace = useAtomStateValue(currentWorkspaceState); + const [currentWorkspace, setCurrentWorkspace] = useAtomState( + currentWorkspaceState, + ); const [{ isLoading }, setCustomDomainRecords] = useAtomState( customDomainRecordsState, ); - const checkCustomDomainRecords = () => { - if (isLoading || !currentWorkspace?.customDomain) { + const checkCustomDomainRecords = ( + customDomain: string | null | undefined = currentWorkspace?.customDomain, + ) => { + if (isLoading || !customDomain) { return; } setCustomDomainRecords((currentState) => ({ @@ -28,13 +31,28 @@ export const useCheckCustomDomainValidRecords = () => { })); checkCustomDomainValidRecords({ onCompleted: (data) => { + const validRecords = data.checkCustomDomainValidRecords; + setCustomDomainRecords((currentState) => ({ ...currentState, isLoading: false, - ...(isDefined(data.checkCustomDomainValidRecords) - ? { customDomainRecords: data.checkCustomDomainValidRecords } + ...(isDefined(validRecords) + ? { customDomainRecords: validRecords } : {}), })); + + const nextIsCustomDomainEnabled = validRecords?.isCustomDomainEnabled; + + if (isDefined(nextIsCustomDomainEnabled)) { + setCurrentWorkspace((previousWorkspace) => + isDefined(previousWorkspace) + ? { + ...previousWorkspace, + isCustomDomainEnabled: nextIsCustomDomainEnabled, + } + : previousWorkspace, + ); + } }, onError: (error) => { enqueueErrorSnackBar({ apolloError: error }); diff --git a/packages/twenty-front/src/modules/settings/domains/hooks/useSettingsCustomDomain.ts b/packages/twenty-front/src/modules/settings/domains/hooks/useSettingsCustomDomain.ts index 4093167819..676aa5a86f 100644 --- a/packages/twenty-front/src/modules/settings/domains/hooks/useSettingsCustomDomain.ts +++ b/packages/twenty-front/src/modules/settings/domains/hooks/useSettingsCustomDomain.ts @@ -65,7 +65,7 @@ export const useSettingsCustomDomain = () => { }); enqueueSuccessSnackBar({ message: t`Custom domain updated` }); setIsSubmitting(false); - checkCustomDomainRecords(); + checkCustomDomainRecords(domainValue); }, onError: (mutationError) => { if ( diff --git a/packages/twenty-front/src/modules/workspace/graphql/queries/checkCustomDomainValidRecords.ts b/packages/twenty-front/src/modules/workspace/graphql/queries/checkCustomDomainValidRecords.ts index 4f85bd9387..172ad6aa31 100644 --- a/packages/twenty-front/src/modules/workspace/graphql/queries/checkCustomDomainValidRecords.ts +++ b/packages/twenty-front/src/modules/workspace/graphql/queries/checkCustomDomainValidRecords.ts @@ -5,6 +5,7 @@ export const CHECK_CUSTOM_DOMAIN_VALID_RECORDS = gql` checkCustomDomainValidRecords { id domain + isCustomDomainEnabled records { type key diff --git a/packages/twenty-server/src/engine/core-modules/dns-manager/dtos/domain-valid-records.ts b/packages/twenty-server/src/engine/core-modules/dns-manager/dtos/domain-valid-records.ts index 7a65a463aa..c4e5a1a93c 100644 --- a/packages/twenty-server/src/engine/core-modules/dns-manager/dtos/domain-valid-records.ts +++ b/packages/twenty-server/src/engine/core-modules/dns-manager/dtos/domain-valid-records.ts @@ -30,4 +30,7 @@ export class DomainValidRecords { @Field(() => [DomainRecord]) records: Array; + + @Field(() => Boolean, { nullable: true }) + isCustomDomainEnabled?: boolean; } diff --git a/packages/twenty-server/src/engine/core-modules/domain/custom-domain-manager/services/custom-domain-manager.service.ts b/packages/twenty-server/src/engine/core-modules/domain/custom-domain-manager/services/custom-domain-manager.service.ts index 052f3fff4e..d9433a7d4d 100644 --- a/packages/twenty-server/src/engine/core-modules/domain/custom-domain-manager/services/custom-domain-manager.service.ts +++ b/packages/twenty-server/src/engine/core-modules/domain/custom-domain-manager/services/custom-domain-manager.service.ts @@ -124,6 +124,9 @@ export class CustomDomainManagerService { ); } - return customDomainWithRecords; + return { + ...customDomainWithRecords, + isCustomDomainEnabled: workspace.isCustomDomainEnabled, + }; } }