diff --git a/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts b/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts new file mode 100644 index 000000000..8d9655060 --- /dev/null +++ b/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts @@ -0,0 +1,15 @@ +import { MessageChannel } from './MessageChannel'; + +type MessageChannelConnection = { edges: [MessageChannelEdge] }; +type MessageChannelEdge = { node: MessageChannel }; + +export type ConnectedAccount = { + id: string; + handle: string; + provider: string; + accessToken: string; + refreshToken: string; + accountOwnerId: string; + lastSyncHistoryId: string; + messageChannels: MessageChannelConnection; +}; diff --git a/packages/twenty-front/src/modules/accounts/types/Account.ts b/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts similarity index 89% rename from packages/twenty-front/src/modules/accounts/types/Account.ts rename to packages/twenty-front/src/modules/accounts/types/MessageChannel.ts index 9ef30adeb..ed49f7f0f 100644 --- a/packages/twenty-front/src/modules/accounts/types/Account.ts +++ b/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts @@ -1,6 +1,6 @@ import { InboxSettingsVisibilityValue } from '@/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection'; -export type Account = { +export type MessageChannel = { id: string; handle: string; isContactAutoCreationEnabled?: boolean; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCard.tsx index 6da1196a0..f9a17e9bb 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCard.tsx @@ -2,7 +2,7 @@ import { useNavigate } from 'react-router-dom'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { Account } from '@/accounts/types/Account'; +import { ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { SettingsAccountsRowDropdownMenu } from '@/settings/accounts/components/SettingsAccountsRowDropdownMenu'; import { IconAt, IconPlus } from '@/ui/display/icon'; import { IconGoogle } from '@/ui/display/icon/components/IconGoogle'; @@ -31,7 +31,7 @@ const StyledDropdown = styled(SettingsAccountsRowDropdownMenu)` `; type SettingsAccountsCardProps = { - accounts: Account[]; + accounts: ConnectedAccount[]; onAccountRemove?: (uuid: string) => void; }; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsSection.tsx index 6d3781e11..e3fbe3063 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsSection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsSection.tsx @@ -1,6 +1,6 @@ import { useRecoilValue } from 'recoil'; -import { Account } from '@/accounts/types/Account'; +import { ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; @@ -13,7 +13,7 @@ import { SettingsAccountsEmptyStateCard } from './SettingsAccountsEmptyStateCard export const SettingsAccountsConnectedAccountsSection = () => { const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); - const accounts = useFindManyRecords({ + const accounts = useFindManyRecords({ objectNameSingular: 'connectedAccount', filter: { accountOwnerId: { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsCard.tsx index 362be4c24..25cc99d88 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsCard.tsx @@ -1,7 +1,7 @@ import { useNavigate } from 'react-router-dom'; import styled from '@emotion/styled'; -import { Account } from '@/accounts/types/Account'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; import { IconChevronRight } from '@/ui/display/icon'; import { IconGmail } from '@/ui/display/icon/components/IconGmail'; import { Status } from '@/ui/display/status/components/Status'; @@ -18,24 +18,24 @@ const StyledRightContainer = styled.div` `; type SettingsAccountsEmailsCardProps = { - accounts: Account[]; + messageChannels: MessageChannel[]; }; export const SettingsAccountsEmailsCard = ({ - accounts, + messageChannels, }: SettingsAccountsEmailsCardProps) => { const navigate = useNavigate(); return ( - {accounts.map((account, index) => ( + {messageChannels.map((messageChannel, index) => ( - {account.isSynced ? ( + {messageChannel.isSynced ? ( ) : ( @@ -43,8 +43,10 @@ export const SettingsAccountsEmailsCard = ({ } - onClick={() => navigate(`/settings/accounts/emails/${account.id}`)} - divider={index < accounts.length - 1} + onClick={() => + navigate(`/settings/accounts/emails/${messageChannel.id}`) + } + divider={index < messageChannels.length - 1} /> ))} diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsSyncSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsSyncSection.tsx index d140db076..ba6a3a0a4 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsSyncSection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEmailsSyncSection.tsx @@ -1,20 +1,56 @@ +import { useRecoilValue } from 'recoil'; + +import { ConnectedAccount } from '@/accounts/types/ConnectedAccount'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; +import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; +import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { H2Title } from '@/ui/display/typography/components/H2Title'; import { Section } from '@/ui/layout/section/components/Section'; -import { mockedAccounts as accounts } from '~/testing/mock-data/accounts'; import { SettingsAccountsEmailsCard } from './SettingsAccountsEmailsCard'; import { SettingsAccountsEmptyStateCard } from './SettingsAccountsEmptyStateCard'; -export const SettingsAccountsEmailsSyncSection = () => ( -
- - {accounts.length ? ( - - ) : ( - - )} -
-); +export const SettingsAccountsEmailsSyncSection = () => { + const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + + const accounts = useFindManyRecords({ + objectNameSingular: 'connectedAccount', + filter: { + accountOwnerId: { + eq: currentWorkspaceMember?.id, + }, + }, + }).records; + + const messageChannels = useFindManyRecords({ + objectNameSingular: 'messageChannel', + filter: { + connectedAccountId: { + in: accounts.map((account) => account.id), + }, + }, + }).records; + + const messageChannelsWithSyncedEmails = messageChannels.map( + (messageChannel) => ({ + ...messageChannel, + isSynced: true, + }), + ); + + return ( +
+ + {accounts.length ? ( + + ) : ( + + )} +
+ ); +}; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsContactAutoCreationSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsContactAutoCreationSection.tsx index f7d966298..5d8a2a47c 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsContactAutoCreationSection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsContactAutoCreationSection.tsx @@ -1,7 +1,7 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { Account } from '@/accounts/types/Account'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; import { SettingsAccountsInboxSettingsCardMedia } from '@/settings/accounts/components/SettingsAccountsInboxSettingsCardMedia'; import { IconSend } from '@/ui/display/icon'; import { H2Title } from '@/ui/display/typography/components/H2Title'; @@ -24,12 +24,12 @@ const StyledTitle = styled.span` `; type SettingsAccountsInboxSettingsContactAutoCreateSectionProps = { - account: Account; + messageChannel: MessageChannel; onToggle: (value: boolean) => void; }; export const SettingsAccountsInboxSettingsContactAutoCreateSection = ({ - account, + messageChannel, onToggle, }: SettingsAccountsInboxSettingsContactAutoCreateSectionProps) => { const theme = useTheme(); @@ -47,7 +47,7 @@ export const SettingsAccountsInboxSettingsContactAutoCreateSection = ({ Auto-creation diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsSynchronizationSection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsSynchronizationSection.tsx index f8db05182..83a2f0eb0 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsSynchronizationSection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsSynchronizationSection.tsx @@ -1,7 +1,7 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { Account } from '@/accounts/types/Account'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; import { SettingsAccountsInboxSettingsCardMedia } from '@/settings/accounts/components/SettingsAccountsInboxSettingsCardMedia'; import { IconRefresh } from '@/ui/display/icon'; import { H2Title } from '@/ui/display/typography/components/H2Title'; @@ -24,12 +24,12 @@ const StyledTitle = styled.span` `; type SettingsAccountsInboxSettingsSynchronizationSectionProps = { - account: Account; + messageChannel: MessageChannel; onToggle: (value: boolean) => void; }; export const SettingsAccountsInboxSettingsSynchronizationSection = ({ - account, + messageChannel, onToggle, }: SettingsAccountsInboxSettingsSynchronizationSectionProps) => { const theme = useTheme(); @@ -49,7 +49,7 @@ export const SettingsAccountsInboxSettingsSynchronizationSection = ({ /> Sync emails - + diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection.tsx index 1a834edfc..a352c1bf2 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection.tsx @@ -8,8 +8,8 @@ import { CardContent } from '@/ui/layout/card/components/CardContent'; import { Section } from '@/ui/layout/section/components/Section'; export enum InboxSettingsVisibilityValue { - Everything = 'everything', - SubjectMetadata = 'subject-metadata', + Everything = 'share_everything', + SubjectMetadata = 'subject', Metadata = 'metadata', } @@ -108,7 +108,7 @@ export const SettingsAccountsInboxSettingsVisibilitySection = ({ index, ) => ( diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRow.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRow.tsx index 7023c3abe..a62beea23 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRow.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRow.tsx @@ -2,7 +2,8 @@ import { ReactNode } from 'react'; import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; -import { Account } from '@/accounts/types/Account'; +import { ConnectedAccount } from '@/accounts/types/ConnectedAccount'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; import { IconComponent } from '@/ui/display/icon/types/IconComponent'; import { CardContent } from '@/ui/layout/card/components/CardContent'; @@ -18,7 +19,7 @@ const StyledRow = styled(CardContent)` `; type SettingsAccountRowProps = { - account: Account; + account: ConnectedAccount | MessageChannel; divider?: boolean; LeftIcon: IconComponent; onClick?: () => void; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx index a9c1c421f..0119f51ed 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx @@ -1,6 +1,6 @@ import { useNavigate } from 'react-router-dom'; -import { Account } from '@/accounts/types/Account'; +import { ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { IconDotsVertical, IconMail, IconTrash } from '@/ui/display/icon'; import { LightIconButton } from '@/ui/input/button/components/LightIconButton'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; @@ -10,7 +10,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; type SettingsAccountsRowDropdownMenuProps = { - account: Account; + account: ConnectedAccount; className?: string; onRemove?: (uuid: string) => void; }; @@ -41,7 +41,9 @@ export const SettingsAccountsRowDropdownMenu = ({ LeftIcon={IconMail} text="Emails settings" onClick={() => { - navigate(`/settings/accounts/emails/${account.id}`); + navigate( + `/settings/accounts/emails/${account.messageChannels.edges[0].node.id}`, + ); closeDropdown(); }} /> diff --git a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmailsInboxSettings.tsx b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmailsInboxSettings.tsx index b3138a9d2..7d2713a5f 100644 --- a/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmailsInboxSettings.tsx +++ b/packages/twenty-front/src/pages/settings/accounts/SettingsAccountsEmailsInboxSettings.tsx @@ -1,8 +1,9 @@ import { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; -import { SettingsAccountsInboxSettingsContactAutoCreateSection } from '@/settings/accounts/components/SettingsAccountsInboxSettingsContactAutoCreationSection'; -import { SettingsAccountsInboxSettingsSynchronizationSection } from '@/settings/accounts/components/SettingsAccountsInboxSettingsSynchronizationSection'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; +import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; +import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { InboxSettingsVisibilityValue, SettingsAccountsInboxSettingsVisibilitySection, @@ -12,24 +13,34 @@ import { AppPath } from '@/types/AppPath'; import { IconSettings } from '@/ui/display/icon'; import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; -import { mockedAccounts } from '~/testing/mock-data/accounts'; export const SettingsAccountsEmailsInboxSettings = () => { const navigate = useNavigate(); - const { accountUuid = '' } = useParams(); - const account = mockedAccounts.find((account) => account.id === accountUuid); + const { accountUuid: messageChannelId = '' } = useParams(); + + const { record: messageChannel, loading } = useFindOneRecord({ + objectNameSingular: 'messageChannel', + objectRecordId: messageChannelId, + }); + + const { updateOneRecord } = useUpdateOneRecord({ + objectNameSingular: 'messageChannel', + }); + + const handleVisibilityChange = (_value: InboxSettingsVisibilityValue) => { + updateOneRecord({ + idToUpdate: messageChannelId, + updateOneRecordInput: { + visibility: _value, + }, + }); + }; useEffect(() => { - if (!account) navigate(AppPath.NotFound); - }, [account, navigate]); + if (!loading && !messageChannel) navigate(AppPath.NotFound); + }, [loading, messageChannel, navigate]); - if (!account) return null; - - const handleSynchronizationToggle = (_value: boolean) => {}; - - const handleContactAutoCreationToggle = (_value: boolean) => {}; - - const handleVisibilityChange = (_value: InboxSettingsVisibilityValue) => {}; + if (!messageChannel) return null; return ( @@ -38,21 +49,23 @@ export const SettingsAccountsEmailsInboxSettings = () => { links={[ { children: 'Accounts', href: '/settings/accounts' }, { children: 'Emails', href: '/settings/accounts/emails' }, - { children: account?.handle || '' }, + { children: messageChannel?.handle || '' }, ]} /> - + /> */} - + /> */} ); diff --git a/packages/twenty-front/src/testing/mock-data/accounts.ts b/packages/twenty-front/src/testing/mock-data/accounts.ts index b9526089f..41e74d649 100644 --- a/packages/twenty-front/src/testing/mock-data/accounts.ts +++ b/packages/twenty-front/src/testing/mock-data/accounts.ts @@ -1,8 +1,8 @@ -import { Account } from '@/accounts/types/Account'; import { BlockedEmail } from '@/accounts/types/BlockedEmail'; +import { MessageChannel } from '@/accounts/types/MessageChannel'; import { InboxSettingsVisibilityValue } from '@/settings/accounts/components/SettingsAccountsInboxSettingsVisibilitySection'; -export const mockedAccounts: Account[] = [ +export const mockedAccounts: MessageChannel[] = [ { handle: 'thomas@twenty.com', isSynced: true,