fix(): several ui improvements (#10556)
Close #10531 --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> Co-authored-by: Etienne <45695613+etiennejouan@users.noreply.github.com> Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Crowdin Bot <support+bot@crowdin.com> Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
@ -2482,7 +2482,7 @@ export type GetSsoIdentityProvidersQueryVariables = Exact<{ [key: string]: never
|
|||||||
|
|
||||||
export type GetSsoIdentityProvidersQuery = { __typename?: 'Query', getSSOIdentityProviders: Array<{ __typename?: 'FindAvailableSSOIDPOutput', type: IdentityProviderType, id: string, name: string, issuer: string, status: SsoIdentityProviderStatus }> };
|
export type GetSsoIdentityProvidersQuery = { __typename?: 'Query', getSSOIdentityProviders: Array<{ __typename?: 'FindAvailableSSOIDPOutput', type: IdentityProviderType, id: string, name: string, issuer: string, status: SsoIdentityProviderStatus }> };
|
||||||
|
|
||||||
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, analyticsTinybirdJwts?: { __typename?: 'AnalyticsTinybirdJwtMap', getWebhookAnalytics: string, getPageviewsAnalytics: string, getUsersAnalytics: string, getServerlessFunctionDuration: string, getServerlessFunctionSuccessRate: string, getServerlessFunctionErrorCount: string } | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', settingsPermissions?: Array<SettingsPermissions> | null, objectRecordsPermissions?: Array<PermissionsOnAllObjectRecords> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, customDomain?: string | null, metadataVersion: number, workspaceMembersCount?: number | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: FeatureFlagKey, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, canUpdateAllSettings: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean } | null } | null, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, subdomain: string, customDomain?: string | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null } } | null }> };
|
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, analyticsTinybirdJwts?: { __typename?: 'AnalyticsTinybirdJwtMap', getWebhookAnalytics: string, getPageviewsAnalytics: string, getUsersAnalytics: string, getServerlessFunctionDuration: string, getServerlessFunctionSuccessRate: string, getServerlessFunctionErrorCount: string } | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', settingsPermissions?: Array<SettingsPermissions> | null, objectRecordsPermissions?: Array<PermissionsOnAllObjectRecords> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, customDomain?: string | null, isCustomDomainEnabled: boolean, metadataVersion: number, workspaceMembersCount?: number | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: FeatureFlagKey, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, canUpdateAllSettings: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean } | null } | null, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, subdomain: string, customDomain?: string | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null } } | null }> };
|
||||||
|
|
||||||
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
|
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
@ -2499,7 +2499,7 @@ export type UploadProfilePictureMutation = { __typename?: 'Mutation', uploadProf
|
|||||||
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
|
export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, analyticsTinybirdJwts?: { __typename?: 'AnalyticsTinybirdJwtMap', getWebhookAnalytics: string, getPageviewsAnalytics: string, getUsersAnalytics: string, getServerlessFunctionDuration: string, getServerlessFunctionSuccessRate: string, getServerlessFunctionErrorCount: string } | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', settingsPermissions?: Array<SettingsPermissions> | null, objectRecordsPermissions?: Array<PermissionsOnAllObjectRecords> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, customDomain?: string | null, metadataVersion: number, workspaceMembersCount?: number | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: FeatureFlagKey, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, canUpdateAllSettings: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean } | null } | null, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, subdomain: string, customDomain?: string | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null } } | null }> } };
|
export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canAccessFullAdminPanel: boolean, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, analyticsTinybirdJwts?: { __typename?: 'AnalyticsTinybirdJwtMap', getWebhookAnalytics: string, getPageviewsAnalytics: string, getUsersAnalytics: string, getServerlessFunctionDuration: string, getServerlessFunctionSuccessRate: string, getServerlessFunctionErrorCount: string } | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, userEmail: string, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, currentUserWorkspace?: { __typename?: 'UserWorkspace', settingsPermissions?: Array<SettingsPermissions> | null, objectRecordsPermissions?: Array<PermissionsOnAllObjectRecords> | null } | null, currentWorkspace?: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, isPublicInviteLinkEnabled: boolean, isGoogleAuthEnabled: boolean, isMicrosoftAuthEnabled: boolean, isPasswordAuthEnabled: boolean, subdomain: string, hasValidEnterpriseKey: boolean, customDomain?: string | null, isCustomDomainEnabled: boolean, metadataVersion: number, workspaceMembersCount?: number | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null }, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: FeatureFlagKey, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null, billingSubscriptions: Array<{ __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus }>, defaultRole?: { __typename?: 'Role', id: string, label: string, description?: string | null, canUpdateAllSettings: boolean, isEditable: boolean, canReadAllObjectRecords: boolean, canUpdateAllObjectRecords: boolean, canSoftDeleteAllObjectRecords: boolean, canDestroyAllObjectRecords: boolean } | null } | null, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, subdomain: string, customDomain?: string | null, workspaceUrls: { __typename?: 'workspaceUrls', subdomainUrl: string, customUrl?: string | null } } | null }> } };
|
||||||
|
|
||||||
export type ActivateWorkflowVersionMutationVariables = Exact<{
|
export type ActivateWorkflowVersionMutationVariables = Exact<{
|
||||||
workflowVersionId: Scalars['String'];
|
workflowVersionId: Scalars['String'];
|
||||||
@ -2793,6 +2793,7 @@ export const UserQueryFragmentFragmentDoc = gql`
|
|||||||
subdomain
|
subdomain
|
||||||
hasValidEnterpriseKey
|
hasValidEnterpriseKey
|
||||||
customDomain
|
customDomain
|
||||||
|
isCustomDomainEnabled
|
||||||
workspaceUrls {
|
workspaceUrls {
|
||||||
subdomainUrl
|
subdomainUrl
|
||||||
customUrl
|
customUrl
|
||||||
|
|||||||
@ -14,7 +14,7 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
width: 100%;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* https://stackoverflow.com/questions/44543157/how-to-hide-the-google-invisible-recaptcha-badge */
|
/* https://stackoverflow.com/questions/44543157/how-to-hide-the-google-invisible-recaptcha-badge */
|
||||||
|
|||||||
@ -19,6 +19,7 @@ export type CurrentWorkspace = Pick<
|
|||||||
| 'isMicrosoftAuthEnabled'
|
| 'isMicrosoftAuthEnabled'
|
||||||
| 'isPasswordAuthEnabled'
|
| 'isPasswordAuthEnabled'
|
||||||
| 'hasValidEnterpriseKey'
|
| 'hasValidEnterpriseKey'
|
||||||
|
| 'isCustomDomainEnabled'
|
||||||
| 'subdomain'
|
| 'subdomain'
|
||||||
| 'customDomain'
|
| 'customDomain'
|
||||||
| 'workspaceUrls'
|
| 'workspaceUrls'
|
||||||
|
|||||||
@ -28,6 +28,8 @@ const Wrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({
|
|||||||
isGoogleAuthEnabled: true,
|
isGoogleAuthEnabled: true,
|
||||||
isMicrosoftAuthEnabled: false,
|
isMicrosoftAuthEnabled: false,
|
||||||
isPasswordAuthEnabled: true,
|
isPasswordAuthEnabled: true,
|
||||||
|
customDomain: 'my-custom-domain.com',
|
||||||
|
isCustomDomainEnabled: true,
|
||||||
workspaceUrls: {
|
workspaceUrls: {
|
||||||
subdomainUrl: 'https://twenty.twenty.com',
|
subdomainUrl: 'https://twenty.twenty.com',
|
||||||
customUrl: 'https://my-custom-domain.com',
|
customUrl: 'https://my-custom-domain.com',
|
||||||
|
|||||||
@ -24,10 +24,6 @@ const StyledCard = styled(Card)<{
|
|||||||
cursor: ${({ disabled, onClick }) =>
|
cursor: ${({ disabled, onClick }) =>
|
||||||
disabled ? 'not-allowed' : onClick ? 'pointer' : 'default'};
|
disabled ? 'not-allowed' : onClick ? 'pointer' : 'default'};
|
||||||
width: 100%;
|
width: 100%;
|
||||||
& :hover {
|
|
||||||
background-color: ${({ theme }) => theme.background.quaternary};
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledCardContent = styled(CardContent)<object>`
|
const StyledCardContent = styled(CardContent)<object>`
|
||||||
@ -35,6 +31,11 @@ const StyledCardContent = styled(CardContent)<object>`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
padding: ${({ theme }) => theme.spacing(2, 2)};
|
padding: ${({ theme }) => theme.spacing(2, 2)};
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.background.quaternary};
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledHeader = styled.div`
|
const StyledHeader = styled.div`
|
||||||
|
|||||||
@ -23,6 +23,7 @@ const StyledSettingsPageContainer = styled.div<{
|
|||||||
return OBJECT_SETTINGS_WIDTH + 'px';
|
return OBJECT_SETTINGS_WIDTH + 'px';
|
||||||
}};
|
}};
|
||||||
padding-bottom: ${({ theme }) => theme.spacing(20)};
|
padding-bottom: ${({ theme }) => theme.spacing(20)};
|
||||||
|
height: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SettingsPageContainer = ({
|
export const SettingsPageContainer = ({
|
||||||
|
|||||||
@ -11,13 +11,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {
|
import { AutogrowWrapper, IconComponent, IconEye, IconEyeOff } from 'twenty-ui';
|
||||||
AutogrowWrapper,
|
|
||||||
IconComponent,
|
|
||||||
IconEye,
|
|
||||||
IconEyeOff,
|
|
||||||
Loader,
|
|
||||||
} from 'twenty-ui';
|
|
||||||
import { useCombinedRefs } from '~/hooks/useCombinedRefs';
|
import { useCombinedRefs } from '~/hooks/useCombinedRefs';
|
||||||
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
|
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
|
||||||
|
|
||||||
@ -202,7 +196,6 @@ export type TextInputV2ComponentProps = Omit<
|
|||||||
dataTestId?: string;
|
dataTestId?: string;
|
||||||
sizeVariant?: TextInputV2Size;
|
sizeVariant?: TextInputV2Size;
|
||||||
inheritFontStyles?: boolean;
|
inheritFontStyles?: boolean;
|
||||||
loading?: boolean;
|
|
||||||
rightAdornment?: string;
|
rightAdornment?: string;
|
||||||
leftAdornment?: string;
|
leftAdornment?: string;
|
||||||
};
|
};
|
||||||
@ -240,7 +233,6 @@ const TextInputV2Component = forwardRef<
|
|||||||
inheritFontStyles = false,
|
inheritFontStyles = false,
|
||||||
dataTestId,
|
dataTestId,
|
||||||
autoGrow = false,
|
autoGrow = false,
|
||||||
loading = false,
|
|
||||||
rightAdornment,
|
rightAdornment,
|
||||||
leftAdornment,
|
leftAdornment,
|
||||||
},
|
},
|
||||||
@ -349,12 +341,6 @@ const TextInputV2Component = forwardRef<
|
|||||||
<RightIcon size={theme.icon.size.md} />
|
<RightIcon size={theme.icon.size.md} />
|
||||||
</StyledTrailingIcon>
|
</StyledTrailingIcon>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!error && type !== INPUT_TYPE_PASSWORD && !!loading && (
|
|
||||||
<StyledTrailingIcon>
|
|
||||||
<Loader color={'gray'} />
|
|
||||||
</StyledTrailingIcon>
|
|
||||||
)}
|
|
||||||
</StyledTrailingIconContainer>
|
</StyledTrailingIconContainer>
|
||||||
</StyledInputContainer>
|
</StyledInputContainer>
|
||||||
{!noErrorHelper && error && (
|
{!noErrorHelper && error && (
|
||||||
|
|||||||
@ -45,6 +45,7 @@ export const USER_QUERY_FRAGMENT = gql`
|
|||||||
subdomain
|
subdomain
|
||||||
hasValidEnterpriseKey
|
hasValidEnterpriseKey
|
||||||
customDomain
|
customDomain
|
||||||
|
isCustomDomainEnabled
|
||||||
workspaceUrls {
|
workspaceUrls {
|
||||||
subdomainUrl
|
subdomainUrl
|
||||||
customUrl
|
customUrl
|
||||||
|
|||||||
@ -56,8 +56,11 @@ export const SettingsWorkspace = () => {
|
|||||||
title={t`Customize Domain`}
|
title={t`Customize Domain`}
|
||||||
Icon={<IconWorld />}
|
Icon={<IconWorld />}
|
||||||
Status={
|
Status={
|
||||||
currentWorkspace?.customDomain ? (
|
currentWorkspace?.customDomain &&
|
||||||
|
currentWorkspace?.isCustomDomainEnabled ? (
|
||||||
<Status text={'Active'} color={'turquoise'} />
|
<Status text={'Active'} color={'turquoise'} />
|
||||||
|
) : currentWorkspace?.customDomain ? (
|
||||||
|
<Status text={'Inactive'} color={'orange'} />
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,16 +3,21 @@ import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useLingui } from '@lingui/react/macro';
|
import { useLingui } from '@lingui/react/macro';
|
||||||
import { Controller, useFormContext } from 'react-hook-form';
|
import { Controller, useFormContext } from 'react-hook-form';
|
||||||
import { H2Title, Section } from 'twenty-ui';
|
import { Button, H2Title, IconReload, Section } from 'twenty-ui';
|
||||||
import { SettingsCustomDomainRecords } from '~/pages/settings/workspace/SettingsCustomDomainRecords';
|
import { SettingsCustomDomainRecords } from '~/pages/settings/workspace/SettingsCustomDomainRecords';
|
||||||
import { SettingsCustomDomainRecordsStatus } from '~/pages/settings/workspace/SettingsCustomDomainRecordsStatus';
|
import { SettingsCustomDomainRecordsStatus } from '~/pages/settings/workspace/SettingsCustomDomainRecordsStatus';
|
||||||
import { customDomainRecordsState } from '~/pages/settings/workspace/states/customDomainRecordsState';
|
import { customDomainRecordsState } from '~/pages/settings/workspace/states/customDomainRecordsState';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
|
import { useCheckCustomDomainValidRecords } from '~/pages/settings/workspace/hooks/useCheckCustomDomainValidRecords';
|
||||||
|
|
||||||
const StyledDomainFormWrapper = styled.div`
|
const StyledDomainFormWrapper = styled.div`
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledButton = styled(Button)`
|
||||||
|
align-self: flex-start;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledRecordsWrapper = styled.div`
|
const StyledRecordsWrapper = styled.div`
|
||||||
@ -28,6 +33,12 @@ export const SettingsCustomDomain = () => {
|
|||||||
customDomainRecordsState,
|
customDomainRecordsState,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { checkCustomDomainRecords } = useCheckCustomDomainValidRecords();
|
||||||
|
|
||||||
|
if (!customDomainRecords && !loading) {
|
||||||
|
checkCustomDomainRecords();
|
||||||
|
}
|
||||||
|
|
||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||||
|
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@ -53,11 +64,18 @@ export const SettingsCustomDomain = () => {
|
|||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
placeholder="crm.yourdomain.com"
|
placeholder="crm.yourdomain.com"
|
||||||
error={error?.message}
|
error={error?.message}
|
||||||
loading={!!loading}
|
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<StyledButton
|
||||||
|
loading={loading}
|
||||||
|
Icon={IconReload}
|
||||||
|
title={t`Reload`}
|
||||||
|
variant="primary"
|
||||||
|
onClick={checkCustomDomainRecords}
|
||||||
|
type="button"
|
||||||
|
/>
|
||||||
</StyledDomainFormWrapper>
|
</StyledDomainFormWrapper>
|
||||||
{currentWorkspace?.customDomain && (
|
{currentWorkspace?.customDomain && (
|
||||||
<StyledRecordsWrapper>
|
<StyledRecordsWrapper>
|
||||||
|
|||||||
@ -1,48 +0,0 @@
|
|||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
|
||||||
import { useEffect, useCallback } from 'react';
|
|
||||||
import { useSetRecoilState, useRecoilValue } from 'recoil';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
|
||||||
import { useCheckCustomDomainValidRecordsMutation } from '~/generated/graphql';
|
|
||||||
import { customDomainRecordsState } from '~/pages/settings/workspace/states/customDomainRecordsState';
|
|
||||||
|
|
||||||
export const SettingsCustomDomainEffect = () => {
|
|
||||||
const [checkCustomDomainValidRecords] =
|
|
||||||
useCheckCustomDomainValidRecordsMutation();
|
|
||||||
|
|
||||||
const setCustomDomainRecords = useSetRecoilState(customDomainRecordsState);
|
|
||||||
|
|
||||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
|
||||||
|
|
||||||
const checkCustomDomainValidRecordsPolling = useCallback(async () => {
|
|
||||||
setCustomDomainRecords((currentState) => ({
|
|
||||||
...currentState,
|
|
||||||
loading: true,
|
|
||||||
}));
|
|
||||||
checkCustomDomainValidRecords({
|
|
||||||
onCompleted: (data) => {
|
|
||||||
if (isDefined(data.checkCustomDomainValidRecords)) {
|
|
||||||
setCustomDomainRecords({
|
|
||||||
loading: false,
|
|
||||||
customDomainRecords: data.checkCustomDomainValidRecords,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}, [checkCustomDomainValidRecords, setCustomDomainRecords]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let pollIntervalFn: null | ReturnType<typeof setInterval> = null;
|
|
||||||
if (isDefined(currentWorkspace?.customDomain)) {
|
|
||||||
checkCustomDomainValidRecordsPolling();
|
|
||||||
pollIntervalFn = setInterval(checkCustomDomainValidRecordsPolling, 6000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (isDefined(pollIntervalFn)) {
|
|
||||||
clearInterval(pollIntervalFn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [checkCustomDomainValidRecordsPolling, currentWorkspace?.customDomain]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
@ -18,17 +18,21 @@ const StyledTable = styled(Table)`
|
|||||||
|
|
||||||
const StyledTableCell = styled(TableCell)`
|
const StyledTableCell = styled(TableCell)`
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
padding: 0 ${({ theme }) => theme.spacing(3)} 0 0;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledButton = styled(Button)`
|
const StyledButton = styled(Button)`
|
||||||
-moz-user-select: text;
|
|
||||||
-ms-user-select: text;
|
|
||||||
-webkit-user-select: text;
|
|
||||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
font-family: ${({ theme }) => theme.font.family};
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.regular};
|
font-weight: ${({ theme }) => theme.font.weight.regular};
|
||||||
height: ${({ theme }) => theme.spacing(6)};
|
height: ${({ theme }) => theme.spacing(6)};
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
|||||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import { SettingsCustomDomainEffect } from '~/pages/settings/workspace/SettingsCustomDomainEffect';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export const SettingsDomain = () => {
|
export const SettingsDomain = () => {
|
||||||
@ -229,12 +228,7 @@ export const SettingsDomain = () => {
|
|||||||
>
|
>
|
||||||
<SettingsPageContainer>
|
<SettingsPageContainer>
|
||||||
<SettingsSubdomain />
|
<SettingsSubdomain />
|
||||||
{isCustomDomainEnabled && (
|
{isCustomDomainEnabled && <SettingsCustomDomain />}
|
||||||
<>
|
|
||||||
<SettingsCustomDomainEffect />
|
|
||||||
<SettingsCustomDomain />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
|
|||||||
@ -14,15 +14,6 @@ const StyledDomainFormWrapper = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledDomain = styled.h2`
|
|
||||||
align-self: flex-start;
|
|
||||||
color: ${({ theme }) => theme.font.color.secondary};
|
|
||||||
font-size: ${({ theme }) => theme.font.size.md};
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
|
||||||
margin: ${({ theme }) => theme.spacing(2)};
|
|
||||||
white-space: nowrap;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const SettingsSubdomain = () => {
|
export const SettingsSubdomain = () => {
|
||||||
const domainConfiguration = useRecoilValue(domainConfigurationState);
|
const domainConfiguration = useRecoilValue(domainConfigurationState);
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@ -51,13 +42,13 @@ export const SettingsSubdomain = () => {
|
|||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
error={error?.message}
|
error={error?.message}
|
||||||
disabled={!!currentWorkspace?.customDomain}
|
disabled={!!currentWorkspace?.customDomain}
|
||||||
|
rightAdornment={
|
||||||
|
isDefined(domainConfiguration.frontDomain)
|
||||||
|
? `.${domainConfiguration.frontDomain}`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
{isDefined(domainConfiguration.frontDomain) && (
|
|
||||||
<StyledDomain>
|
|
||||||
{`.${domainConfiguration.frontDomain}`}
|
|
||||||
</StyledDomain>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -0,0 +1,32 @@
|
|||||||
|
import { customDomainRecordsState } from '~/pages/settings/workspace/states/customDomainRecordsState';
|
||||||
|
import { useCheckCustomDomainValidRecordsMutation } from '~/generated/graphql';
|
||||||
|
import { isDefined } from 'twenty-shared';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
export const useCheckCustomDomainValidRecords = () => {
|
||||||
|
const [checkCustomDomainValidRecords] =
|
||||||
|
useCheckCustomDomainValidRecordsMutation();
|
||||||
|
|
||||||
|
const setCustomDomainRecords = useSetRecoilState(customDomainRecordsState);
|
||||||
|
|
||||||
|
const checkCustomDomainRecords = () => {
|
||||||
|
setCustomDomainRecords((currentState) => ({
|
||||||
|
...currentState,
|
||||||
|
loading: true,
|
||||||
|
}));
|
||||||
|
checkCustomDomainValidRecords({
|
||||||
|
onCompleted: (data) => {
|
||||||
|
if (isDefined(data.checkCustomDomainValidRecords)) {
|
||||||
|
setCustomDomainRecords({
|
||||||
|
loading: false,
|
||||||
|
customDomainRecords: data.checkCustomDomainValidRecords,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
checkCustomDomainRecords,
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user