Update Connected Accounts Design (#13332)
/closes #13328 --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
@ -1,40 +1,65 @@
|
||||
import { ConnectedAccount } from '@/accounts/types/ConnectedAccount';
|
||||
import { SettingsAccountsListEmptyStateCard } from '@/settings/accounts/components/SettingsAccountsListEmptyStateCard';
|
||||
import { SettingsConnectedAccountsTableHeader } from '@/settings/accounts/components/SettingsConnectedAccountsTableHeader';
|
||||
import { SettingsConnectedAccountsTableRow } from '@/settings/components/SettingsConnectedAccountsTableRow';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { Table } from '@/ui/layout/table/components/Table';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { SettingsAccountsConnectedAccountsRowRightContainer } from '@/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
|
||||
import { SettingsConnectedAccountIcon } from '@/settings/accounts/components/SettingsConnectedAccountIcon';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { SettingsListCard } from '../../components/SettingsListCard';
|
||||
|
||||
const StyledTableRows = styled.div`
|
||||
padding-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
const StyledAddAccountSection = styled(Section)`
|
||||
border-top: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-top: ${({ theme }) => theme.spacing(2)};
|
||||
padding-bottom: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
export const SettingsAccountsConnectedAccountsListCard = ({
|
||||
accounts,
|
||||
loading,
|
||||
}: {
|
||||
accounts: ConnectedAccount[];
|
||||
loading?: boolean;
|
||||
}) => {
|
||||
const navigate = useNavigateSettings();
|
||||
const { t } = useLingui();
|
||||
const navigateSettings = useNavigateSettings();
|
||||
|
||||
if (!accounts.length) {
|
||||
return <SettingsAccountsListEmptyStateCard />;
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsListCard
|
||||
items={accounts}
|
||||
getItemLabel={(account) => account.handle}
|
||||
isLoading={loading}
|
||||
RowIconFn={(row) => SettingsConnectedAccountIcon({ account: row })}
|
||||
RowRightComponent={({ item: account }) => (
|
||||
<SettingsAccountsConnectedAccountsRowRightContainer account={account} />
|
||||
)}
|
||||
hasFooter={true}
|
||||
footerButtonLabel={t`Add account`}
|
||||
onFooterButtonClick={() => navigate(SettingsPath.NewAccount)}
|
||||
/>
|
||||
<Section>
|
||||
<Table>
|
||||
<SettingsConnectedAccountsTableHeader />
|
||||
<StyledTableRows>
|
||||
{accounts.map((account) => (
|
||||
<SettingsConnectedAccountsTableRow
|
||||
key={account.id}
|
||||
account={account}
|
||||
/>
|
||||
))}
|
||||
</StyledTableRows>
|
||||
</Table>
|
||||
<StyledAddAccountSection>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title={t`Add account`}
|
||||
variant="secondary"
|
||||
size="small"
|
||||
onClick={() => navigateSettings(SettingsPath.NewAccount)}
|
||||
/>
|
||||
</StyledAddAccountSection>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ import { Status } from 'twenty-ui/display';
|
||||
const StyledRowRightContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
gap: ${({ theme }) => theme.spacing(4)};
|
||||
`;
|
||||
|
||||
export const SettingsAccountsConnectedAccountsRowRightContainer = ({
|
||||
|
||||
@ -3,40 +3,30 @@ import { isGoogleMessagingEnabledState } from '@/client-config/states/isGoogleMe
|
||||
import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicrosoftCalendarEnabledState';
|
||||
import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState';
|
||||
import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth';
|
||||
import { SettingsCard } from '@/settings/components/SettingsCard';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import { IconAt, IconGoogle, IconMicrosoft } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { Card, CardContent, CardHeader } from 'twenty-ui/layout';
|
||||
import { UndecoratedLink } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
const StyledHeader = styled(CardHeader)`
|
||||
align-items: center;
|
||||
const StyledCardsContainer = styled.div`
|
||||
display: flex;
|
||||
height: ${({ theme }) => theme.spacing(6)};
|
||||
`;
|
||||
|
||||
const StyledBody = styled(CardContent)`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing(2)};
|
||||
`;
|
||||
|
||||
type SettingsAccountsListEmptyStateCardProps = {
|
||||
label?: string;
|
||||
};
|
||||
|
||||
export const SettingsAccountsListEmptyStateCard = ({
|
||||
label,
|
||||
}: SettingsAccountsListEmptyStateCardProps) => {
|
||||
export const SettingsAccountsListEmptyStateCard = () => {
|
||||
const { triggerApisOAuth } = useTriggerApisOAuth();
|
||||
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
|
||||
const isGoogleMessagingEnabled = useRecoilValue(
|
||||
isGoogleMessagingEnabledState,
|
||||
@ -56,36 +46,33 @@ export const SettingsAccountsListEmptyStateCard = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<StyledHeader>{label || t`No connected account`}</StyledHeader>
|
||||
<StyledBody>
|
||||
{(isGoogleMessagingEnabled || isGoogleCalendarEnabled) && (
|
||||
<Button
|
||||
Icon={IconGoogle}
|
||||
title={t`Connect with Google`}
|
||||
variant="secondary"
|
||||
onClick={() => triggerApisOAuth(ConnectedAccountProvider.GOOGLE)}
|
||||
/>
|
||||
)}
|
||||
<StyledCardsContainer>
|
||||
{(isGoogleMessagingEnabled || isGoogleCalendarEnabled) && (
|
||||
<SettingsCard
|
||||
Icon={<IconGoogle size={theme.icon.size.md} />}
|
||||
title={t`Connect with Google`}
|
||||
onClick={() => triggerApisOAuth(ConnectedAccountProvider.GOOGLE)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{(isMicrosoftMessagingEnabled || isMicrosoftCalendarEnabled) && (
|
||||
<Button
|
||||
Icon={IconMicrosoft}
|
||||
title={t`Connect with Microsoft`}
|
||||
variant="secondary"
|
||||
onClick={() => triggerApisOAuth(ConnectedAccountProvider.MICROSOFT)}
|
||||
/>
|
||||
)}
|
||||
{(isMicrosoftMessagingEnabled || isMicrosoftCalendarEnabled) && (
|
||||
<SettingsCard
|
||||
Icon={<IconMicrosoft size={theme.icon.size.md} />}
|
||||
title={t`Connect with Microsoft`}
|
||||
onClick={() => triggerApisOAuth(ConnectedAccountProvider.MICROSOFT)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isImapSmtpCaldavFeatureFlagEnabled && (
|
||||
<Button
|
||||
Icon={IconAt}
|
||||
{isImapSmtpCaldavFeatureFlagEnabled && (
|
||||
<UndecoratedLink
|
||||
to={getSettingsPath(SettingsPath.NewImapSmtpCaldavConnection)}
|
||||
>
|
||||
<SettingsCard
|
||||
Icon={<IconAt size={theme.icon.size.md} />}
|
||||
title={t`Connect Email Account`}
|
||||
variant="secondary"
|
||||
to={getSettingsPath(SettingsPath.NewImapSmtpCaldavConnection)}
|
||||
/>
|
||||
)}
|
||||
</StyledBody>
|
||||
</Card>
|
||||
</UndecoratedLink>
|
||||
)}
|
||||
</StyledCardsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -12,11 +12,11 @@ import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { ConnectedAccountProvider } from 'twenty-shared/types';
|
||||
import {
|
||||
IconAt,
|
||||
IconCalendarEvent,
|
||||
IconDotsVertical,
|
||||
IconMail,
|
||||
IconRefresh,
|
||||
IconSettings,
|
||||
IconTrash,
|
||||
} from 'twenty-ui/display';
|
||||
import { LightIconButton } from 'twenty-ui/input';
|
||||
@ -63,7 +63,7 @@ export const SettingsAccountsRowDropdownMenu = ({
|
||||
ConnectedAccountProvider.IMAP_SMTP_CALDAV && (
|
||||
<MenuItem
|
||||
text={t`Connection settings`}
|
||||
LeftIcon={IconSettings}
|
||||
LeftIcon={IconAt}
|
||||
onClick={() => {
|
||||
navigate(SettingsPath.EditImapSmtpCaldavConnection, {
|
||||
connectedAccountId: account.id,
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
import { Table } from '@/ui/layout/table/components/Table';
|
||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import styled from '@emotion/styled';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
|
||||
const StyledTableHeader = styled(TableHeader)`
|
||||
padding-right: ${({ theme }) => theme.spacing(14)};
|
||||
`;
|
||||
|
||||
export const SettingsConnectedAccountsTableHeader = () => {
|
||||
return (
|
||||
<Table>
|
||||
<TableRow gridAutoColumns="332px 1fr">
|
||||
<StyledTableHeader>
|
||||
<Trans>Account</Trans>
|
||||
</StyledTableHeader>
|
||||
<StyledTableHeader align={'right'}>
|
||||
<Trans>Status</Trans>
|
||||
</StyledTableHeader>
|
||||
</TableRow>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
@ -10,7 +10,7 @@ export const SettingsNewAccountSection = () => {
|
||||
title={t`New account`}
|
||||
description={t`Connect a new account to your workspace`}
|
||||
/>
|
||||
<SettingsAccountsListEmptyStateCard label={t`Choose your provider`} />
|
||||
<SettingsAccountsListEmptyStateCard />
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
import { ConnectedAccount } from '@/accounts/types/ConnectedAccount';
|
||||
import { SettingsAccountsConnectedAccountsRowRightContainer } from '@/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer';
|
||||
import { SettingsConnectedAccountIcon } from '@/settings/accounts/components/SettingsConnectedAccountIcon';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledNameCell = styled.div`
|
||||
align-items: center;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
&:hover {
|
||||
background: ${({ theme }) => theme.background.transparent.light};
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
|
||||
type SettingsConnectedAccountsTableRowProps = {
|
||||
account: ConnectedAccount;
|
||||
};
|
||||
|
||||
export const SettingsConnectedAccountsTableRow = ({
|
||||
account,
|
||||
}: SettingsConnectedAccountsTableRowProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const IconComponent = SettingsConnectedAccountIcon({ account });
|
||||
|
||||
return (
|
||||
<StyledTableRow key={account.id} gridAutoColumns="332px 1fr">
|
||||
<TableCell>
|
||||
<StyledNameCell>
|
||||
<IconComponent
|
||||
size={theme.icon.size.md}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
/>
|
||||
{account.handle}
|
||||
</StyledNameCell>
|
||||
</TableCell>
|
||||
<TableCell align={'right'}>
|
||||
<SettingsAccountsConnectedAccountsRowRightContainer account={account} />
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
);
|
||||
};
|
||||
@ -56,10 +56,7 @@ export const SettingsAccounts = () => {
|
||||
title={t`Connected accounts`}
|
||||
description={t`Manage your internet accounts.`}
|
||||
/>
|
||||
<SettingsAccountsConnectedAccountsListCard
|
||||
accounts={accounts}
|
||||
loading={loading}
|
||||
/>
|
||||
<SettingsAccountsConnectedAccountsListCard accounts={accounts} />
|
||||
</Section>
|
||||
<SettingsAccountsBlocklistSection />
|
||||
<SettingsAccountsSettingsSection />
|
||||
|
||||
Reference in New Issue
Block a user