diff --git a/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts b/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts index 4b8321115f..d82c9a1dd4 100644 --- a/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts +++ b/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts @@ -9,6 +9,11 @@ export enum MessageChannelContactAutoCreationPolicy { NONE = 'NONE', } +export enum MessageFolderImportPolicy { + ALL_FOLDERS = 'ALL_FOLDERS', + SELECTED_FOLDERS = 'SELECTED_FOLDERS', +} + export enum MessageChannelSyncStatus { NOT_SYNCED = 'NOT_SYNCED', ONGOING = 'ONGOING', @@ -38,6 +43,7 @@ export type MessageChannel = { isSyncEnabled: boolean; messageFolders: MessageFolder[]; visibility: MessageChannelVisibility; + messageFolderImportPolicy: MessageFolderImportPolicy; syncStatus: MessageChannelSyncStatus; syncStage: MessageChannelSyncStage; syncCursor: string; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx index be802b0332..0344c573fc 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx @@ -3,11 +3,12 @@ import styled from '@emotion/styled'; import { type MessageChannel, type MessageChannelContactAutoCreationPolicy, + type MessageFolderImportPolicy, } from '@/accounts/types/MessageChannel'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { SettingsAccountsMessageAutoCreationCard } from '@/settings/accounts/components/SettingsAccountsMessageAutoCreationCard'; -import { SettingsAccountsMessageFoldersCard } from '@/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard'; +import { SettingsAccountsMessageFolderCard } from '@/settings/accounts/components/SettingsAccountsMessageFolderCard'; import { SettingsAccountsMessageVisibilityCard } from '@/settings/accounts/components/SettingsAccountsMessageVisibilityCard'; import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; @@ -29,6 +30,7 @@ type SettingsAccountsMessageChannelDetailsProps = { | 'excludeGroupEmails' | 'isSyncEnabled' | 'messageFolders' + | 'messageFolderImportPolicy' >; }; @@ -87,17 +89,26 @@ export const SettingsAccountsMessageChannelDetails = ({ }); }; + const handleMessageFolderImportPolicyChange = ( + value: MessageFolderImportPolicy, + ) => { + updateOneRecord({ + idToUpdate: messageChannel.id, + updateOneRecordInput: { messageFolderImportPolicy: value }, + }); + }; + return ( {isFolderControlEnabled && messageChannel.messageFolders && (
-
)} diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx index 48aa9dafbd..29aeeb53cd 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx @@ -1,5 +1,5 @@ import styled from '@emotion/styled'; -import { useRecoilValue } from 'recoil'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { type ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { type MessageChannel } from '@/accounts/types/MessageChannel'; @@ -11,10 +11,12 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { SettingsAccountsMessageChannelDetails } from '@/settings/accounts/components/SettingsAccountsMessageChannelDetails'; import { SettingsNewAccountSection } from '@/settings/accounts/components/SettingsNewAccountSection'; import { SETTINGS_ACCOUNT_MESSAGE_CHANNELS_TAB_LIST_COMPONENT_ID } from '@/settings/accounts/constants/SettingsAccountMessageChannelsTabListComponentId'; +import { settingsAccountsSelectedMessageChannelState } from '@/settings/accounts/states/settingsAccountsSelectedMessageChannelState'; import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue'; import React from 'react'; +import { isDefined } from 'twenty-shared/utils'; const StyledMessageContainer = styled.div` padding-bottom: ${({ theme }) => theme.spacing(6)}; @@ -26,6 +28,9 @@ export const SettingsAccountsMessageChannelsContainer = () => { SETTINGS_ACCOUNT_MESSAGE_CHANNELS_TAB_LIST_COMPONENT_ID, ); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); + const setSelectedMessageChannel = useSetRecoilState( + settingsAccountsSelectedMessageChannelState, + ); const messageChannelObjectMetadataItem = useObjectMetadataItem({ objectNameSingular: CoreObjectNameSingular.MessageChannel, @@ -57,6 +62,9 @@ export const SettingsAccountsMessageChannelsContainer = () => { recordGqlFields: generateDepthOneRecordGqlFields( messageChannelObjectMetadataItem, ), + onCompleted: (data) => { + setSelectedMessageChannel(data[0]); + }, skip: !accounts.length, }); @@ -69,6 +77,15 @@ export const SettingsAccountsMessageChannelsContainer = () => { return ; } + const handleTabChange = (tabId: string) => { + const selectedMessageChannel = messageChannels.find( + (channel) => channel.id === tabId, + ); + if (isDefined(selectedMessageChannel)) { + setSelectedMessageChannel(selectedMessageChannel); + } + }; + return ( <> {tabs.length > 1 && ( @@ -78,6 +95,7 @@ export const SettingsAccountsMessageChannelsContainer = () => { componentInstanceId={ SETTINGS_ACCOUNT_MESSAGE_CHANNELS_TAB_LIST_COMPONENT_ID } + onChangeTab={handleTabChange} /> )} diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx new file mode 100644 index 0000000000..280576a2ba --- /dev/null +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx @@ -0,0 +1,46 @@ +import { MessageFolderImportPolicy } from '@/accounts/types/MessageChannel'; +import { SettingsAccountsMessageFoldersCard } from '@/settings/accounts/components/message-folders/SettingsAccountsMessageFoldersCard'; +import { SettingsAccountsMessageFolderIcon } from '@/settings/accounts/components/SettingsAccountsMessageFolderIcon'; +import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard'; +import { msg } from '@lingui/core/macro'; + +type SettingsAccountsMessageFolderCardProps = { + onChange: (nextValue: MessageFolderImportPolicy) => void; + value?: MessageFolderImportPolicy; +}; + +const INBOX_SETTINGS_VISIBILITY_OPTIONS = [ + { + title: msg`Everything`, + description: msg`Import all emails`, + value: MessageFolderImportPolicy.ALL_FOLDERS, + cardMedia: ( + + ), + }, + { + title: msg`Some folders`, + description: msg`Import only selected folders/labels`, + value: MessageFolderImportPolicy.SELECTED_FOLDERS, + cardMedia: ( + + ), + cardContentExpanded: , + }, +]; + +export const SettingsAccountsMessageFolderCard = ({ + onChange, + value = MessageFolderImportPolicy.SELECTED_FOLDERS, +}: SettingsAccountsMessageFolderCardProps) => ( + +); diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx new file mode 100644 index 0000000000..92af0a5620 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx @@ -0,0 +1,69 @@ +import styled from '@emotion/styled'; + +import { MessageFolderImportPolicy } from '@/accounts/types/MessageChannel'; +import { SettingsAccountsCardMedia } from '@/settings/accounts/components/SettingsAccountsCardMedia'; + +type SettingsAccountsMessageFolderIconProps = { + className?: string; + value?: MessageFolderImportPolicy; +}; + +const StyledCardMedia = styled(SettingsAccountsCardMedia)` + align-items: stretch; + flex-direction: column; +`; + +const StyledFolderRow = styled.div` + align-items: center; + display: flex; + gap: 2px; +`; + +const StyledFolderIcon = styled.div<{ isDisabled?: boolean }>` + background-color: ${({ isDisabled, theme }) => + isDisabled ? theme.background.quaternary : theme.accent.accent4060}; + border-radius: 1px; + height: 5px; + width: 5px; +`; + +const StyledFolderLabel = styled.div<{ isDisabled?: boolean }>` + background-color: ${({ isDisabled, theme }) => + isDisabled ? theme.background.quaternary : theme.accent.accent4060}; + border-radius: 1px; + flex: 1; + height: 5px; +`; + +export const SettingsAccountsMessageFolderIcon = ({ + className, + value, +}: SettingsAccountsMessageFolderIconProps) => { + const isSelectedFolders = + value === MessageFolderImportPolicy.SELECTED_FOLDERS; + + return ( + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx index 5a262a20f1..7856821857 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx @@ -2,8 +2,8 @@ import styled from '@emotion/styled'; import { type MessageDescriptor } from '@lingui/core'; import { Trans } from '@lingui/react'; import { type ReactNode } from 'react'; -import { Card, CardContent } from 'twenty-ui/layout'; import { Radio } from 'twenty-ui/input'; +import { Card, CardContent } from 'twenty-ui/layout'; type SettingsAccountsRadioSettingsCardProps