feat(settings): add domain validation effect and delete functionality (#11643)

Introduced a new effect component to validate custom domain DNS records
on mount, centralizing logic. Added a button to reset the custom domain
field, improving user control and form handling. Refactored related code
for maintainability and enhanced UI structure.

Fix https://github.com/twentyhq/core-team-issues/issues/853
This commit is contained in:
Antoine Moreaux
2025-04-18 10:18:36 +02:00
committed by GitHub
parent 53042cc9dc
commit 8a2a004fb5
3 changed files with 54 additions and 21 deletions

View File

@ -0,0 +1,15 @@
/* @license Enterprise */
import { useCheckCustomDomainValidRecords } from '~/pages/settings/workspace/hooks/useCheckCustomDomainValidRecords';
import { useEffect } from 'react';
export const CheckCustomDomainValidRecordsEffect = () => {
const { checkCustomDomainRecords } = useCheckCustomDomainValidRecords();
useEffect(() => {
checkCustomDomainRecords();
// Check custom domain only needs to run once at mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <></>;
};

View File

@ -9,15 +9,22 @@ import { customDomainRecordsState } from '~/pages/settings/workspace/states/cust
import { useRecoilValue } from 'recoil';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useCheckCustomDomainValidRecords } from '~/pages/settings/workspace/hooks/useCheckCustomDomainValidRecords';
import { Button } from 'twenty-ui/input';
import { H2Title, IconReload } from 'twenty-ui/display';
import { Button, ButtonGroup } from 'twenty-ui/input';
import { H2Title, IconReload, IconTrash } from 'twenty-ui/display';
import { Section } from 'twenty-ui/layout';
import { CheckCustomDomainValidRecordsEffect } from '~/pages/settings/workspace/CheckCustomDomainValidRecordsEffect';
const StyledDomainFormWrapper = styled.div`
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledButtonGroup = styled(ButtonGroup)`
& > :not(:first-of-type) > button {
border-left: none;
}
`;
const StyledButton = styled(Button)`
align-self: flex-start;
`;
@ -37,24 +44,26 @@ export const SettingsCustomDomain = () => {
const { checkCustomDomainRecords } = useCheckCustomDomainValidRecords();
if (!customDomainRecords && !isLoading) {
checkCustomDomainRecords();
}
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const { t } = useLingui();
const { control } = useFormContext<{
const { control, setValue, trigger } = useFormContext<{
customDomain: string;
}>();
const deleteCustomDomain = () => {
setValue('customDomain', '');
trigger();
};
return (
<Section>
<H2Title
title={t`Custom Domain`}
description={t`Set the name of your custom domain and configure your DNS records.`}
/>
<CheckCustomDomainValidRecordsEffect />
<StyledDomainFormWrapper>
<Controller
name="customDomain"
@ -70,14 +79,22 @@ export const SettingsCustomDomain = () => {
/>
)}
/>
<StyledButton
isLoading={isLoading}
Icon={IconReload}
title={t`Reload`}
variant="primary"
onClick={checkCustomDomainRecords}
type="button"
/>
<StyledButtonGroup>
<StyledButton
isLoading={isLoading}
Icon={IconReload}
title={t`Reload`}
variant="primary"
onClick={checkCustomDomainRecords}
type="button"
/>
<StyledButton
Icon={IconTrash}
variant="primary"
onClick={deleteCustomDomain}
type="button"
/>
</StyledButtonGroup>
</StyledDomainFormWrapper>
{currentWorkspace?.customDomain && (
<StyledRecordsWrapper>

View File

@ -16,12 +16,13 @@ export const useCheckCustomDomainValidRecords = () => {
}));
checkCustomDomainValidRecords({
onCompleted: (data) => {
if (isDefined(data.checkCustomDomainValidRecords)) {
setCustomDomainRecords({
isLoading: false,
customDomainRecords: data.checkCustomDomainValidRecords,
});
}
setCustomDomainRecords((currentState) => ({
...currentState,
isLoading: false,
...(isDefined(data.checkCustomDomainValidRecords)
? { customDomainRecords: data.checkCustomDomainValidRecords }
: {}),
}));
},
});
};