diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index ef36f1fa64d..3b9c9b58afe 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -2771,6 +2771,7 @@ type ConnectedAccountDTO { authFailedAt: DateTime handleAliases: [String!] scopes: [String!] + connectionParameters: ImapSmtpCaldavConnectionParameters lastSignedInAt: DateTime userWorkspaceId: UUID! createdAt: DateTime! diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index 1465e8ea943..f890a419a39 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -2424,6 +2424,7 @@ export interface ConnectedAccountDTO { authFailedAt?: Scalars['DateTime'] handleAliases?: Scalars['String'][] scopes?: Scalars['String'][] + connectionParameters?: ImapSmtpCaldavConnectionParameters lastSignedInAt?: Scalars['DateTime'] userWorkspaceId: Scalars['UUID'] createdAt: Scalars['DateTime'] @@ -5630,6 +5631,7 @@ export interface ConnectedAccountDTOGenqlSelection{ authFailedAt?: boolean | number handleAliases?: boolean | number scopes?: boolean | number + connectionParameters?: ImapSmtpCaldavConnectionParametersGenqlSelection lastSignedInAt?: boolean | number userWorkspaceId?: boolean | number createdAt?: boolean | number diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts index 1b37c43fb07..8991fa80885 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -5479,6 +5479,9 @@ export default { "scopes": [ 1 ], + "connectionParameters": [ + 291 + ], "lastSignedInAt": [ 4 ], diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 5b15978f529..3fbee4b5675 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1019,6 +1019,7 @@ export type ConfigVariablesGroupData = { export type ConnectedAccountDto = { __typename?: 'ConnectedAccountDTO'; authFailedAt?: Maybe; + connectionParameters?: Maybe; createdAt: Scalars['DateTime']; handle: Scalars['String']; handleAliases?: Maybe>; @@ -7073,7 +7074,7 @@ export type MyCalendarChannelsQuery = { __typename?: 'Query', myCalendarChannels export type MyConnectedAccountsQueryVariables = Exact<{ [key: string]: never; }>; -export type MyConnectedAccountsQuery = { __typename?: 'Query', myConnectedAccounts: Array<{ __typename?: 'ConnectedAccountDTO', id: string, handle: string, provider: string, authFailedAt?: string | null, scopes?: Array | null, handleAliases?: Array | null, lastSignedInAt?: string | null, userWorkspaceId: string, createdAt: string, updatedAt: string }> }; +export type MyConnectedAccountsQuery = { __typename?: 'Query', myConnectedAccounts: Array<{ __typename?: 'ConnectedAccountDTO', id: string, handle: string, provider: string, authFailedAt?: string | null, scopes?: Array | null, handleAliases?: Array | null, lastSignedInAt?: string | null, userWorkspaceId: string, createdAt: string, updatedAt: string, connectionParameters?: { __typename?: 'ImapSmtpCaldavConnectionParameters', IMAP?: { __typename?: 'ConnectionParametersOutput', host: string, port: number, secure?: boolean | null, username?: string | null, password: string } | null, SMTP?: { __typename?: 'ConnectionParametersOutput', host: string, port: number, secure?: boolean | null, username?: string | null, password: string } | null, CALDAV?: { __typename?: 'ConnectionParametersOutput', host: string, username?: string | null, password: string } | null } | null }> }; export type MyMessageChannelsQueryVariables = Exact<{ connectedAccountId?: InputMaybe; @@ -8386,7 +8387,7 @@ export const UpdateMessageFolderDocument = {"kind":"Document","definitions":[{"k export const UpdateMessageFoldersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMessageFolders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UpdateMessageFoldersInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateMessageFolders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"isSynced"}}]}}]}}]} as unknown as DocumentNode; export const GetConnectedImapSmtpCaldavAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetConnectedImapSmtpCaldavAccount"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getConnectedImapSmtpCaldavAccount"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"handle"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"connectionParameters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"IMAP"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"}},{"kind":"Field","name":{"kind":"Name","value":"port"}},{"kind":"Field","name":{"kind":"Name","value":"secure"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"password"}}]}},{"kind":"Field","name":{"kind":"Name","value":"SMTP"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"port"}},{"kind":"Field","name":{"kind":"Name","value":"secure"}},{"kind":"Field","name":{"kind":"Name","value":"password"}}]}},{"kind":"Field","name":{"kind":"Name","value":"CALDAV"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"password"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const MyCalendarChannelsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MyCalendarChannels"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"connectedAccountId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myCalendarChannels"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"connectedAccountId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"connectedAccountId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"handle"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"syncStatus"}},{"kind":"Field","name":{"kind":"Name","value":"syncStage"}},{"kind":"Field","name":{"kind":"Name","value":"syncStageStartedAt"}},{"kind":"Field","name":{"kind":"Name","value":"isContactAutoCreationEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"contactAutoCreationPolicy"}},{"kind":"Field","name":{"kind":"Name","value":"isSyncEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"connectedAccountId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; -export const MyConnectedAccountsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MyConnectedAccounts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myConnectedAccounts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"handle"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}},{"kind":"Field","name":{"kind":"Name","value":"authFailedAt"}},{"kind":"Field","name":{"kind":"Name","value":"scopes"}},{"kind":"Field","name":{"kind":"Name","value":"handleAliases"}},{"kind":"Field","name":{"kind":"Name","value":"lastSignedInAt"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; +export const MyConnectedAccountsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MyConnectedAccounts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myConnectedAccounts"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"handle"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}},{"kind":"Field","name":{"kind":"Name","value":"authFailedAt"}},{"kind":"Field","name":{"kind":"Name","value":"scopes"}},{"kind":"Field","name":{"kind":"Name","value":"handleAliases"}},{"kind":"Field","name":{"kind":"Name","value":"lastSignedInAt"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"connectionParameters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"IMAP"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"}},{"kind":"Field","name":{"kind":"Name","value":"port"}},{"kind":"Field","name":{"kind":"Name","value":"secure"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"password"}}]}},{"kind":"Field","name":{"kind":"Name","value":"SMTP"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"}},{"kind":"Field","name":{"kind":"Name","value":"port"}},{"kind":"Field","name":{"kind":"Name","value":"secure"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"password"}}]}},{"kind":"Field","name":{"kind":"Name","value":"CALDAV"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"host"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"password"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const MyMessageChannelsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MyMessageChannels"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"connectedAccountId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myMessageChannels"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"connectedAccountId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"connectedAccountId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"handle"}},{"kind":"Field","name":{"kind":"Name","value":"visibility"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"isContactAutoCreationEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"contactAutoCreationPolicy"}},{"kind":"Field","name":{"kind":"Name","value":"messageFolderImportPolicy"}},{"kind":"Field","name":{"kind":"Name","value":"excludeNonProfessionalEmails"}},{"kind":"Field","name":{"kind":"Name","value":"excludeGroupEmails"}},{"kind":"Field","name":{"kind":"Name","value":"isSyncEnabled"}},{"kind":"Field","name":{"kind":"Name","value":"syncStatus"}},{"kind":"Field","name":{"kind":"Name","value":"syncStage"}},{"kind":"Field","name":{"kind":"Name","value":"syncStageStartedAt"}},{"kind":"Field","name":{"kind":"Name","value":"connectedAccountId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const MyMessageFoldersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MyMessageFolders"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"messageChannelId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myMessageFolders"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"messageChannelId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"messageChannelId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"isSynced"}},{"kind":"Field","name":{"kind":"Name","value":"isSentFolder"}},{"kind":"Field","name":{"kind":"Name","value":"parentFolderId"}},{"kind":"Field","name":{"kind":"Name","value":"externalId"}},{"kind":"Field","name":{"kind":"Name","value":"messageChannelId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode; export const AddAiProviderDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"AddAiProvider"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"providerName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"providerConfig"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"JSON"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addAiProvider"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"providerName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"providerName"}}},{"kind":"Argument","name":{"kind":"Name","value":"providerConfig"},"value":{"kind":"Variable","name":{"kind":"Name","value":"providerConfig"}}}]}]}}]} as unknown as DocumentNode; diff --git a/packages/twenty-front/src/modules/accounts/types/CalendarChannel.ts b/packages/twenty-front/src/modules/accounts/types/CalendarChannel.ts index 5805bc731a2..44905671cb1 100644 --- a/packages/twenty-front/src/modules/accounts/types/CalendarChannel.ts +++ b/packages/twenty-front/src/modules/accounts/types/CalendarChannel.ts @@ -1,41 +1,22 @@ +import { + type CalendarChannelContactAutoCreationPolicy, + type CalendarChannelSyncStage, + type CalendarChannelSyncStatus, +} from 'twenty-shared/types'; import { type CalendarChannelVisibility } from '~/generated/graphql'; -export enum CalendarChannelSyncStatus { - NOT_SYNCED = 'NOT_SYNCED', - ONGOING = 'ONGOING', - ACTIVE = 'ACTIVE', - FAILED_INSUFFICIENT_PERMISSIONS = 'FAILED_INSUFFICIENT_PERMISSIONS', - FAILED_UNKNOWN = 'FAILED_UNKNOWN', -} - -export enum CalendarChannelSyncStage { - PENDING_CONFIGURATION = 'PENDING_CONFIGURATION', - CALENDAR_EVENT_LIST_FETCH_PENDING = 'CALENDAR_EVENT_LIST_FETCH_PENDING', - CALENDAR_EVENT_LIST_FETCH_SCHEDULED = 'CALENDAR_EVENT_LIST_FETCH_SCHEDULED', - CALENDAR_EVENT_LIST_FETCH_ONGOING = 'CALENDAR_EVENT_LIST_FETCH_ONGOING', - CALENDAR_EVENTS_IMPORT_PENDING = 'CALENDAR_EVENTS_IMPORT_PENDING', - CALENDAR_EVENTS_IMPORT_SCHEDULED = 'CALENDAR_EVENTS_IMPORT_SCHEDULED', - CALENDAR_EVENTS_IMPORT_ONGOING = 'CALENDAR_EVENTS_IMPORT_ONGOING', - FAILED = 'FAILED', -} - -export enum CalendarChannelContactAutoCreationPolicy { - AS_PARTICIPANT_AND_ORGANIZER = 'AS_PARTICIPANT_AND_ORGANIZER', - AS_PARTICIPANT = 'AS_PARTICIPANT', - AS_ORGANIZER = 'AS_ORGANIZER', - NONE = 'NONE', -} export type CalendarChannel = { id: string; handle: string; + visibility: CalendarChannelVisibility; isContactAutoCreationEnabled: boolean; contactAutoCreationPolicy: CalendarChannelContactAutoCreationPolicy; isSyncEnabled: boolean; - visibility: CalendarChannelVisibility; syncStatus: CalendarChannelSyncStatus; syncStage: CalendarChannelSyncStage; - syncCursor: string; - syncStageStartedAt: Date; - throttleFailureCount: number; + syncStageStartedAt: string | null; + connectedAccountId: string; + createdAt: string; + updatedAt: string; __typename: 'CalendarChannel'; }; diff --git a/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts b/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts index bba9be1fbb7..9c494d5d9a9 100644 --- a/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts +++ b/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts @@ -7,14 +7,15 @@ export type ConnectedAccount = { id: string; handle: string; provider: ConnectedAccountProvider; - accessToken: string; - refreshToken: string; - accountOwnerId: string; - lastSyncHistoryId: string; - authFailedAt: Date | null; + authFailedAt: string | null; + scopes: string[] | null; + handleAliases: string[] | null; + lastSignedInAt: string | null; + userWorkspaceId: string; + connectionParameters: ImapSmtpCaldavAccount | null; + createdAt: string; + updatedAt: string; messageChannels: MessageChannel[]; calendarChannels: CalendarChannel[]; - scopes: string[] | null; - connectionParameters?: ImapSmtpCaldavAccount; __typename: 'ConnectedAccount'; }; diff --git a/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts b/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts index c963e10f4c7..e0ba8608a91 100644 --- a/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts +++ b/packages/twenty-front/src/modules/accounts/types/MessageChannel.ts @@ -1,57 +1,27 @@ -import { type ImapSmtpCaldavAccount } from '@/accounts/types/ImapSmtpCaldavAccount'; -import { type MessageFolder } from '@/accounts/types/MessageFolder'; -import { type ConnectedAccountProvider } from 'twenty-shared/types'; +import { + type MessageChannelContactAutoCreationPolicy, + type MessageChannelSyncStage, + type MessageChannelSyncStatus, + type MessageFolderImportPolicy, +} from 'twenty-shared/types'; import { type MessageChannelVisibility } from '~/generated/graphql'; -export enum MessageChannelContactAutoCreationPolicy { - SENT_AND_RECEIVED = 'SENT_AND_RECEIVED', - SENT = 'SENT', - NONE = 'NONE', -} - -export enum MessageFolderImportPolicy { - ALL_FOLDERS = 'ALL_FOLDERS', - SELECTED_FOLDERS = 'SELECTED_FOLDERS', -} - -export enum MessageChannelSyncStatus { - NOT_SYNCED = 'NOT_SYNCED', - ONGOING = 'ONGOING', - ACTIVE = 'ACTIVE', - FAILED_INSUFFICIENT_PERMISSIONS = 'FAILED_INSUFFICIENT_PERMISSIONS', - FAILED_UNKNOWN = 'FAILED_UNKNOWN', -} - -export enum MessageChannelSyncStage { - PENDING_CONFIGURATION = 'PENDING_CONFIGURATION', - MESSAGE_LIST_FETCH_PENDING = 'MESSAGE_LIST_FETCH_PENDING', - MESSAGE_LIST_FETCH_SCHEDULED = 'MESSAGE_LIST_FETCH_SCHEDULED', - MESSAGE_LIST_FETCH_ONGOING = 'MESSAGE_LIST_FETCH_ONGOING', - MESSAGES_IMPORT_PENDING = 'MESSAGES_IMPORT_PENDING', - MESSAGES_IMPORT_SCHEDULED = 'MESSAGES_IMPORT_SCHEDULED', - MESSAGES_IMPORT_ONGOING = 'MESSAGES_IMPORT_ONGOING', - FAILED = 'FAILED', -} - export type MessageChannel = { id: string; handle: string; + visibility: MessageChannelVisibility; + type: string; + isContactAutoCreationEnabled: boolean; contactAutoCreationPolicy: MessageChannelContactAutoCreationPolicy; + messageFolderImportPolicy: MessageFolderImportPolicy; excludeNonProfessionalEmails: boolean; excludeGroupEmails: boolean; isSyncEnabled: boolean; - messageFolders: MessageFolder[]; - visibility: MessageChannelVisibility; - messageFolderImportPolicy: MessageFolderImportPolicy; syncStatus: MessageChannelSyncStatus; syncStage: MessageChannelSyncStage; - syncCursor: string; - syncStageStartedAt: Date; - throttleFailureCount: number; - connectedAccount?: { - id: string; - provider: ConnectedAccountProvider; - connectionParameters?: ImapSmtpCaldavAccount; - }; + syncStageStartedAt: string | null; + connectedAccountId: string; + createdAt: string; + updatedAt: string; __typename: 'MessageChannel'; }; diff --git a/packages/twenty-front/src/modules/accounts/types/MessageFolder.ts b/packages/twenty-front/src/modules/accounts/types/MessageFolder.ts index f8fa66382d8..2fcc3328297 100644 --- a/packages/twenty-front/src/modules/accounts/types/MessageFolder.ts +++ b/packages/twenty-front/src/modules/accounts/types/MessageFolder.ts @@ -1,11 +1,12 @@ export type MessageFolder = { id: string; name: string; - syncCursor: string; - isSentFolder: boolean; isSynced: boolean; - messageChannelId: string; + isSentFolder: boolean; parentFolderId: string | null; externalId: string | null; + messageChannelId: string; + createdAt: string; + updatedAt: string; __typename: 'MessageFolder'; }; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx index dc496b74fbc..9b0f1ebaa48 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx @@ -8,6 +8,7 @@ import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import React from 'react'; +import { CalendarChannelSyncStage } from 'twenty-shared/types'; import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledCalenderContainer = styled.div` @@ -20,7 +21,12 @@ export const SettingsAccountsCalendarChannelsContainer = () => { SETTINGS_ACCOUNT_CALENDAR_CHANNELS_TAB_LIST_COMPONENT_ID, ); - const { channels: calendarChannels } = useMyCalendarChannels(); + const { channels: allCalendarChannels } = useMyCalendarChannels(); + + const calendarChannels = allCalendarChannels.filter( + (channel) => + channel.syncStage !== CalendarChannelSyncStage.PENDING_CONFIGURATION, + ); const tabs = [ ...calendarChannels.map((calendarChannel) => ({ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx index 776795d2fec..4b1e42a1463 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationCard.tsx @@ -1,7 +1,7 @@ -import { MessageChannelContactAutoCreationPolicy } from '@/accounts/types/MessageChannel'; import { SettingsAccountsMessageAutoCreationIcon } from '@/settings/accounts/components/SettingsAccountsMessageAutoCreationIcon'; import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard'; import { msg } from '@lingui/core/macro'; +import { MessageChannelContactAutoCreationPolicy } from 'twenty-shared/types'; type SettingsAccountsMessageAutoCreationCardProps = { onChange: (nextValue: MessageChannelContactAutoCreationPolicy) => void; 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 df818de18fa..367a16c3edc 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx @@ -1,10 +1,6 @@ import { styled } from '@linaria/react'; -import { - type MessageChannel, - type MessageChannelContactAutoCreationPolicy, - type MessageFolderImportPolicy, -} from '@/accounts/types/MessageChannel'; +import { type MessageChannel } from '@/accounts/types/MessageChannel'; import { UPDATE_MESSAGE_CHANNEL } from '@/settings/accounts/graphql/mutations/updateMessageChannel'; import { useMutation } from '@apollo/client/react'; import { SettingsAccountsMessageAutoCreationCard } from '@/settings/accounts/components/SettingsAccountsMessageAutoCreationCard'; @@ -16,6 +12,10 @@ import { H2Title, IconBriefcase, IconUsers } from 'twenty-ui/display'; import { Card, Section } from 'twenty-ui/layout'; import { themeCssVariables } from 'twenty-ui/theme-constants'; import { type MessageChannelVisibility } from '~/generated/graphql'; +import { + type MessageChannelContactAutoCreationPolicy, + type MessageFolderImportPolicy, +} from 'twenty-shared/types'; type SettingsAccountsMessageChannelDetailsProps = { messageChannel: Pick< @@ -26,7 +26,6 @@ type SettingsAccountsMessageChannelDetailsProps = { | 'excludeNonProfessionalEmails' | 'excludeGroupEmails' | 'isSyncEnabled' - | 'messageFolders' | 'messageFolderImportPolicy' >; }; 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 9a61d9b125e..50305150806 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelsContainer.tsx @@ -11,6 +11,7 @@ import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTab import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState'; import React, { useCallback } from 'react'; +import { MessageChannelSyncStage } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { themeCssVariables } from 'twenty-ui/theme-constants'; @@ -27,7 +28,13 @@ export const SettingsAccountsMessageChannelsContainer = () => { settingsAccountsSelectedMessageChannelState, ); - const { channels: messageChannels } = useMyMessageChannels(); + const { channels: allMessageChannels } = useMyMessageChannels(); + + const messageChannels = allMessageChannels.filter( + (channel) => + channel.isSyncEnabled && + channel.syncStage !== MessageChannelSyncStage.PENDING_CONFIGURATION, + ); const tabs = messageChannels.map((messageChannel) => ({ id: messageChannel.id, diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx index 280576a2ba4..c7ce7886ec3 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderCard.tsx @@ -1,8 +1,8 @@ -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'; +import { MessageFolderImportPolicy } from 'twenty-shared/types'; type SettingsAccountsMessageFolderCardProps = { onChange: (nextValue: MessageFolderImportPolicy) => void; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx index a32792377a3..39e7f6f0687 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx @@ -1,6 +1,6 @@ import { styled } from '@linaria/react'; +import { MessageFolderImportPolicy } from 'twenty-shared/types'; -import { MessageFolderImportPolicy } from '@/accounts/types/MessageChannel'; import { themeCssVariables } from 'twenty-ui/theme-constants'; type SettingsAccountsMessageFolderIconProps = { 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 9811a647818..ebcc16b94dd 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRowDropdownMenu.tsx @@ -1,8 +1,11 @@ -import { useApolloClient, useMutation } from '@apollo/client/react'; import { type ConnectedAccount } from '@/accounts/types/ConnectedAccount'; -import { CalendarChannelSyncStage } from '@/accounts/types/CalendarChannel'; -import { MessageChannelSyncStage } from '@/accounts/types/MessageChannel'; -import { ConnectedAccountProvider, SettingsPath } from 'twenty-shared/types'; +import { useApolloClient, useMutation } from '@apollo/client/react'; +import { + CalendarChannelSyncStage, + ConnectedAccountProvider, + MessageChannelSyncStage, + SettingsPath, +} from 'twenty-shared/types'; import { useTriggerProviderReconnect } from '@/settings/accounts/hooks/useTriggerProviderReconnect'; import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsMessageChannelDetails.stories.tsx b/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsMessageChannelDetails.stories.tsx index 5eca969d471..21a48eb707a 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsMessageChannelDetails.stories.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/__stories__/SettingsAccountsMessageChannelDetails.stories.tsx @@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite'; import { MessageChannelContactAutoCreationPolicy, MessageFolderImportPolicy, -} from '@/accounts/types/MessageChannel'; +} from 'twenty-shared/types'; import { SettingsAccountsMessageChannelDetails } from '@/settings/accounts/components/SettingsAccountsMessageChannelDetails'; import { ComponentDecorator } from 'twenty-ui/testing'; import { MessageChannelVisibility } from '~/generated/graphql'; @@ -27,7 +27,6 @@ const meta: Meta = { excludeGroupEmails: false, isSyncEnabled: true, visibility: MessageChannelVisibility.SHARE_EVERYTHING, - messageFolders: [], messageFolderImportPolicy: MessageFolderImportPolicy.ALL_FOLDERS, }, }, diff --git a/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeFolderIdsForSyncToggle.test.ts b/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeFolderIdsForSyncToggle.test.ts index d02ff6abe73..2b787048268 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeFolderIdsForSyncToggle.test.ts +++ b/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeFolderIdsForSyncToggle.test.ts @@ -15,6 +15,7 @@ describe('computeFolderIdsForSyncToggle', () => { externalId?: string | null; isSynced?: boolean; }): MessageFolder => ({ + __typename: 'MessageFolder', id, name, parentFolderId, @@ -22,8 +23,8 @@ describe('computeFolderIdsForSyncToggle', () => { isSentFolder: false, isSynced, messageChannelId: 'channel-1', - __typename: 'MessageFolder', - syncCursor: '', + createdAt: '2026-01-01T00:00:00Z', + updatedAt: '2026-01-01T00:00:00Z', }); describe('when syncing a folder', () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeMessageFolderTree.test.ts b/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeMessageFolderTree.test.ts index d9b701e637b..03f564d9979 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeMessageFolderTree.test.ts +++ b/packages/twenty-front/src/modules/settings/accounts/components/message-folders/utils/__tests__/computeMessageFolderTree.test.ts @@ -8,6 +8,7 @@ describe('computeMessageFolderTree', () => { parentFolderId: string | null = null, externalId: string | null = null, ): MessageFolder => ({ + __typename: 'MessageFolder', id, name, parentFolderId, @@ -15,8 +16,8 @@ describe('computeMessageFolderTree', () => { isSentFolder: false, isSynced: false, messageChannelId: '20202020-1c25-4d02-bf25-6aeccf7ea419', - __typename: 'MessageFolder', - syncCursor: '', + createdAt: '2026-01-01T00:00:00Z', + updatedAt: '2026-01-01T00:00:00Z', }); it('should return empty array for empty input', () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/graphql/queries/getMyConnectedAccounts.ts b/packages/twenty-front/src/modules/settings/accounts/graphql/queries/getMyConnectedAccounts.ts index d530376d6a7..17067453bf1 100644 --- a/packages/twenty-front/src/modules/settings/accounts/graphql/queries/getMyConnectedAccounts.ts +++ b/packages/twenty-front/src/modules/settings/accounts/graphql/queries/getMyConnectedAccounts.ts @@ -11,6 +11,27 @@ export const GET_MY_CONNECTED_ACCOUNTS = gql` handleAliases lastSignedInAt userWorkspaceId + connectionParameters { + IMAP { + host + port + secure + username + password + } + SMTP { + host + port + secure + username + password + } + CALDAV { + host + username + password + } + } createdAt updatedAt } diff --git a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyCalendarChannels.ts b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyCalendarChannels.ts index 707ea57719a..81ae12a4be7 100644 --- a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyCalendarChannels.ts +++ b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyCalendarChannels.ts @@ -1,66 +1,18 @@ import { type CalendarChannel } from '@/accounts/types/CalendarChannel'; import { GET_MY_CALENDAR_CHANNELS } from '@/settings/accounts/graphql/queries/getMyCalendarChannels'; import { useApolloClient, useQuery } from '@apollo/client/react'; -import { useMemo } from 'react'; - -type MetadataCalendarChannel = { - id: string; - handle: string; - visibility: string; - syncStatus: string; - syncStage: string; - syncStageStartedAt: string | null; - isContactAutoCreationEnabled: boolean; - contactAutoCreationPolicy: string; - isSyncEnabled: boolean; - connectedAccountId: string; - createdAt: string; - updatedAt: string; -}; export const useMyCalendarChannels = () => { const apolloClient = useApolloClient(); - const { data: metadataData, loading: metadataLoading } = useQuery<{ - myCalendarChannels: MetadataCalendarChannel[]; + const { data, loading } = useQuery<{ + myCalendarChannels: CalendarChannel[]; }>(GET_MY_CALENDAR_CHANNELS, { client: apolloClient, }); - const channels = useMemo(() => { - if (!metadataData?.myCalendarChannels) { - return []; - } - - return metadataData.myCalendarChannels - .filter( - (channel: MetadataCalendarChannel) => - channel.syncStage !== 'PENDING_CONFIGURATION', - ) - .map( - (channel: MetadataCalendarChannel) => - ({ - id: channel.id, - handle: channel.handle, - visibility: channel.visibility, - isContactAutoCreationEnabled: channel.isContactAutoCreationEnabled, - contactAutoCreationPolicy: channel.contactAutoCreationPolicy, - isSyncEnabled: channel.isSyncEnabled, - syncStatus: channel.syncStatus, - syncStage: channel.syncStage, - syncCursor: '', - syncStageStartedAt: channel.syncStageStartedAt - ? new Date(channel.syncStageStartedAt) - : null, - throttleFailureCount: 0, - connectedAccountId: channel.connectedAccountId, - __typename: 'CalendarChannel', - }) as CalendarChannel, - ); - }, [metadataData]); - return { - channels, - loading: metadataLoading, + channels: data?.myCalendarChannels ?? [], + loading, }; }; diff --git a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyConnectedAccounts.ts b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyConnectedAccounts.ts index 7fd0763270f..33d17fba6a6 100644 --- a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyConnectedAccounts.ts +++ b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyConnectedAccounts.ts @@ -5,24 +5,16 @@ import { useMyMessageChannels } from '@/settings/accounts/hooks/useMyMessageChan import { useApolloClient, useQuery } from '@apollo/client/react'; import { useMemo } from 'react'; -type MetadataConnectedAccount = { - id: string; - handle: string; - provider: string; - authFailedAt: string | null; - scopes: string[] | null; - handleAliases: string[] | null; - lastSignedInAt: string | null; - userWorkspaceId: string; - createdAt: string; - updatedAt: string; -}; +type CoreConnectedAccount = Omit< + ConnectedAccount, + 'messageChannels' | 'calendarChannels' +>; export const useMyConnectedAccounts = () => { const apolloClient = useApolloClient(); - const { data: metadataData, loading: metadataLoading } = useQuery<{ - myConnectedAccounts: MetadataConnectedAccount[]; + const { data, loading: accountsLoading } = useQuery<{ + myConnectedAccounts: CoreConnectedAccount[]; }>(GET_MY_CONNECTED_ACCOUNTS, { client: apolloClient, }); @@ -33,48 +25,24 @@ export const useMyConnectedAccounts = () => { useMyCalendarChannels(); const accounts = useMemo(() => { - if (!metadataData?.myConnectedAccounts) { + if (!data?.myConnectedAccounts) { return []; } - return metadataData.myConnectedAccounts - .map( - (account: MetadataConnectedAccount) => - ({ - id: account.id, - handle: account.handle, - provider: account.provider, - accessToken: '', - refreshToken: '', - accountOwnerId: account.userWorkspaceId, - lastSyncHistoryId: '', - authFailedAt: account.authFailedAt - ? new Date(account.authFailedAt) - : null, - messageChannels: messageChannels.filter( - (channel) => - 'connectedAccountId' in channel && - channel.connectedAccountId === account.id, - ), - calendarChannels: calendarChannels.filter( - (channel) => - 'connectedAccountId' in channel && - channel.connectedAccountId === account.id, - ), - scopes: account.scopes, - __typename: 'ConnectedAccount', - }) as ConnectedAccount, - ) - .filter( - (account) => - account.messageChannels.length > 0 || - account.calendarChannels.length > 0, - ); - }, [metadataData, messageChannels, calendarChannels]); + return data.myConnectedAccounts.map((account) => ({ + ...account, + messageChannels: messageChannels.filter( + (channel) => channel.connectedAccountId === account.id, + ), + calendarChannels: calendarChannels.filter( + (channel) => channel.connectedAccountId === account.id, + ), + })); + }, [data, messageChannels, calendarChannels]); return { accounts, loading: - metadataLoading || messageChannelsLoading || calendarChannelsLoading, + accountsLoading || messageChannelsLoading || calendarChannelsLoading, }; }; diff --git a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageChannels.ts b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageChannels.ts index 52508367973..063a49e44c0 100644 --- a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageChannels.ts +++ b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageChannels.ts @@ -1,74 +1,18 @@ import { type MessageChannel } from '@/accounts/types/MessageChannel'; import { GET_MY_MESSAGE_CHANNELS } from '@/settings/accounts/graphql/queries/getMyMessageChannels'; import { useApolloClient, useQuery } from '@apollo/client/react'; -import { useMemo } from 'react'; - -type MetadataMessageChannel = { - id: string; - handle: string; - visibility: string; - type: string; - isContactAutoCreationEnabled: boolean; - contactAutoCreationPolicy: string; - messageFolderImportPolicy: string; - excludeNonProfessionalEmails: boolean; - excludeGroupEmails: boolean; - isSyncEnabled: boolean; - syncStatus: string; - syncStage: string; - syncStageStartedAt: string | null; - connectedAccountId: string; - createdAt: string; - updatedAt: string; -}; export const useMyMessageChannels = () => { const apolloClient = useApolloClient(); - const { data: metadataData, loading: metadataLoading } = useQuery<{ - myMessageChannels: MetadataMessageChannel[]; + const { data, loading } = useQuery<{ + myMessageChannels: MessageChannel[]; }>(GET_MY_MESSAGE_CHANNELS, { client: apolloClient, }); - const channels = useMemo(() => { - if (!metadataData?.myMessageChannels) { - return []; - } - - return metadataData.myMessageChannels - .filter( - (channel: MetadataMessageChannel) => - channel.isSyncEnabled && - channel.syncStage !== 'PENDING_CONFIGURATION', - ) - .map( - (channel: MetadataMessageChannel) => - ({ - id: channel.id, - handle: channel.handle, - visibility: channel.visibility, - contactAutoCreationPolicy: channel.contactAutoCreationPolicy, - excludeNonProfessionalEmails: channel.excludeNonProfessionalEmails, - excludeGroupEmails: channel.excludeGroupEmails, - isSyncEnabled: channel.isSyncEnabled, - messageFolders: [], - messageFolderImportPolicy: channel.messageFolderImportPolicy, - syncStatus: channel.syncStatus, - syncStage: channel.syncStage, - syncCursor: '', - syncStageStartedAt: channel.syncStageStartedAt - ? new Date(channel.syncStageStartedAt) - : null, - throttleFailureCount: 0, - connectedAccountId: channel.connectedAccountId, - __typename: 'MessageChannel', - }) as MessageChannel, - ); - }, [metadataData]); - return { - channels, - loading: metadataLoading, + channels: data?.myMessageChannels ?? [], + loading, }; }; diff --git a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageFolders.ts b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageFolders.ts index e179c7769f6..4e6dad0479b 100644 --- a/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageFolders.ts +++ b/packages/twenty-front/src/modules/settings/accounts/hooks/useMyMessageFolders.ts @@ -1,52 +1,19 @@ import { type MessageFolder } from '@/accounts/types/MessageFolder'; import { GET_MY_MESSAGE_FOLDERS } from '@/settings/accounts/graphql/queries/getMyMessageFolders'; import { useApolloClient, useQuery } from '@apollo/client/react'; -import { useMemo } from 'react'; - -type MetadataMessageFolder = { - id: string; - name: string | null; - isSynced: boolean; - isSentFolder: boolean; - parentFolderId: string | null; - externalId: string | null; - messageChannelId: string; - createdAt: string; - updatedAt: string; -}; export const useMyMessageFolders = (messageChannelId?: string) => { const apolloClient = useApolloClient(); - const { data: metadataData, loading: metadataLoading } = useQuery<{ - myMessageFolders: MetadataMessageFolder[]; + const { data, loading } = useQuery<{ + myMessageFolders: MessageFolder[]; }>(GET_MY_MESSAGE_FOLDERS, { client: apolloClient, variables: messageChannelId ? { messageChannelId } : undefined, }); - const messageFolders = useMemo(() => { - if (!metadataData?.myMessageFolders) { - return []; - } - - return metadataData.myMessageFolders.map( - (folder: MetadataMessageFolder) => ({ - id: folder.id, - name: folder.name ?? '', - syncCursor: '', - isSynced: folder.isSynced, - isSentFolder: folder.isSentFolder, - parentFolderId: folder.parentFolderId, - messageChannelId: folder.messageChannelId, - externalId: folder.externalId, - __typename: 'MessageFolder' as const, - }), - ); - }, [metadataData]); - return { - messageFolders, - loading: metadataLoading, + messageFolders: data?.myMessageFolders ?? [], + loading, }; }; diff --git a/packages/twenty-front/src/modules/settings/accounts/utils/__tests__/computeSyncStatus.test.ts b/packages/twenty-front/src/modules/settings/accounts/utils/__tests__/computeSyncStatus.test.ts index e14808475c2..4df640ad683 100644 --- a/packages/twenty-front/src/modules/settings/accounts/utils/__tests__/computeSyncStatus.test.ts +++ b/packages/twenty-front/src/modules/settings/accounts/utils/__tests__/computeSyncStatus.test.ts @@ -1,13 +1,11 @@ +import { SyncStatus } from '@/settings/accounts/constants/SyncStatus'; +import { computeSyncStatus } from '@/settings/accounts/utils/computeSyncStatus'; import { CalendarChannelSyncStage, CalendarChannelSyncStatus, -} from '@/accounts/types/CalendarChannel'; -import { MessageChannelSyncStage, MessageChannelSyncStatus, -} from '@/accounts/types/MessageChannel'; -import { SyncStatus } from '@/settings/accounts/constants/SyncStatus'; -import { computeSyncStatus } from '@/settings/accounts/utils/computeSyncStatus'; +} from 'twenty-shared/types'; describe('computeSyncStatus', () => { test('should return PENDING_CONFIGURATION when message channel sync stage is PENDING_CONFIGURATION', () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/utils/computeSyncStatus.ts b/packages/twenty-front/src/modules/settings/accounts/utils/computeSyncStatus.ts index 8cc4a38f03d..80cd18af9bc 100644 --- a/packages/twenty-front/src/modules/settings/accounts/utils/computeSyncStatus.ts +++ b/packages/twenty-front/src/modules/settings/accounts/utils/computeSyncStatus.ts @@ -1,14 +1,12 @@ +import { type CalendarChannel } from '@/accounts/types/CalendarChannel'; +import { type MessageChannel } from '@/accounts/types/MessageChannel'; +import { SyncStatus } from '@/settings/accounts/constants/SyncStatus'; import { - type CalendarChannel, CalendarChannelSyncStage, CalendarChannelSyncStatus, -} from '@/accounts/types/CalendarChannel'; -import { - type MessageChannel, MessageChannelSyncStage, MessageChannelSyncStatus, -} from '@/accounts/types/MessageChannel'; -import { SyncStatus } from '@/settings/accounts/constants/SyncStatus'; +} from 'twenty-shared/types'; export const computeSyncStatus = ( messageChannel?: Pick, diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx index 88bce32133b..baa60d6d0c0 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionEmailBase.tsx @@ -113,7 +113,7 @@ export const WorkflowEditActionEmailBase = ({ const filter: { or: object[] } = { or: [ { - accountOwnerId: { + userWorkspaceId: { eq: currentWorkspaceMember?.id, }, }, @@ -139,7 +139,7 @@ export const WorkflowEditActionEmailBase = ({ handle: true, provider: true, scopes: true, - accountOwnerId: true, + userWorkspaceId: true, connectionParameters: true, }, }); @@ -181,7 +181,7 @@ export const WorkflowEditActionEmailBase = ({ label: account.handle, value: account.id, }; - if (account.accountOwnerId === currentWorkspaceMember?.id) { + if (account.userWorkspaceId === currentWorkspaceMember?.id) { connectedAccountOptions.push(selectOption); } else { emptyOption = selectOption; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionEmailBase.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionEmailBase.stories.tsx index 88076068220..03e4a712319 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionEmailBase.stories.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/__stories__/WorkflowEditActionEmailBase.stories.tsx @@ -53,8 +53,7 @@ const CONFIGURED_SEND_EMAIL_ACTION: WorkflowSendEmailAction = { valid: true, settings: { input: { - connectedAccountId: mockedConnectedAccountRecords[0] - .accountOwnerId as string, + connectedAccountId: mockedConnectedAccountRecords[0].id as string, recipients: { to: 'test@twenty.com', cc: '', diff --git a/packages/twenty-server/src/engine/metadata-modules/connected-account/dtos/connected-account.dto.ts b/packages/twenty-server/src/engine/metadata-modules/connected-account/dtos/connected-account.dto.ts index 1ea4fbbe3da..7fa46795dd0 100644 --- a/packages/twenty-server/src/engine/metadata-modules/connected-account/dtos/connected-account.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/connected-account/dtos/connected-account.dto.ts @@ -10,6 +10,7 @@ import { } from 'class-validator'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; +import { ImapSmtpCaldavConnectionParametersDTO } from 'src/engine/core-modules/imap-smtp-caldav-connection/dtos/imap-smtp-caldav-connection.dto'; @ObjectType('ConnectedAccountDTO') export class ConnectedAccountDTO { @@ -54,8 +55,9 @@ export class ConnectedAccountDTO { @Field(() => [String], { nullable: true }) scopes: string[] | null; - @HideField() - connectionParameters: Record | null; + @IsOptional() + @Field(() => ImapSmtpCaldavConnectionParametersDTO, { nullable: true }) + connectionParameters: ImapSmtpCaldavConnectionParametersDTO | null; @IsDateString() @IsOptional() diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.spec.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.spec.ts index a5bbc680c36..7b2eeb522c9 100644 --- a/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.spec.ts @@ -331,7 +331,7 @@ describe('SyncMessageFoldersService', () => { id: 'folder-1', externalId: 'child-ext', name: 'Projects', - parentFolderId: 'old-parent-uuid', + parentFolderId: 'old-parent-ext', }); const discoveredFolders = [ createMockDiscoveredFolder({ @@ -360,7 +360,7 @@ describe('SyncMessageFoldersService', () => { expect(mockMessageFolderRepository.update).toHaveBeenCalledWith( { id: 'folder-1', messageChannelId: 'channel-123', workspaceId }, expect.objectContaining({ - parentFolderId: 'new-parent-uuid', + parentFolderId: 'new-parent-id', }), ); }); diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.ts index 16a050552a8..981e536af9b 100644 --- a/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/services/sync-message-folders.service.ts @@ -115,12 +115,6 @@ export class SyncMessageFoldersService { messageChannelId: string, workspaceId: string, ): Promise { - const externalIdToUuidMap = new Map( - existingFolders - .filter((folder) => isDefined(folder.externalId)) - .map((folder) => [folder.externalId as string, folder.id]), - ); - const foldersToCreate = computeFoldersToCreate({ discoveredFolders, existingFolders, @@ -130,7 +124,6 @@ export class SyncMessageFoldersService { const foldersToUpdate = computeFoldersToUpdate({ discoveredFolders, existingFolders, - externalIdToUuidMap, }); const folderIdsToDelete = computeFolderIdsToDelete({ diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/__tests__/compute-folders-to-update.util.spec.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/__tests__/compute-folders-to-update.util.spec.ts index f68c1d1860f..e3cbe2ce232 100644 --- a/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/__tests__/compute-folders-to-update.util.spec.ts +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/__tests__/compute-folders-to-update.util.spec.ts @@ -2,8 +2,6 @@ import { MessageFolderPendingSyncAction } from 'twenty-shared/types'; import { computeFoldersToUpdate } from 'src/modules/messaging/message-folder-manager/utils/compute-folders-to-update.util'; describe('computeFoldersToUpdate', () => { - const emptyMap = new Map(); - it('should detect folder rename from provider', () => { const discoveredFolders = [ { @@ -31,15 +29,12 @@ describe('computeFoldersToUpdate', () => { const result = computeFoldersToUpdate({ discoveredFolders, existingFolders, - externalIdToUuidMap: emptyMap, }); expect(result.get('folder-id')?.name).toBe('Work Emails'); }); it('should detect folder moved to different parent', () => { - const existingParentUuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; - const discoveredFolders = [ { name: 'Subfolder', @@ -57,23 +52,18 @@ describe('computeFoldersToUpdate', () => { externalId: 'sub-1', isSynced: true, isSentFolder: false, - parentFolderId: 'old-parent-uuid', + parentFolderId: 'old-parent-ext', syncCursor: 'cursor', pendingSyncAction: MessageFolderPendingSyncAction.NONE, }, ]; - const externalIdToUuidMap = new Map([ - ['new-parent-ext', existingParentUuid], - ]); - const result = computeFoldersToUpdate({ discoveredFolders, existingFolders, - externalIdToUuidMap, }); - expect(result.get('folder-id')?.parentFolderId).toBe(existingParentUuid); + expect(result.get('folder-id')?.parentFolderId).toBe('new-parent-ext'); }); it('should not flag unchanged folders for update', () => { @@ -98,7 +88,6 @@ describe('computeFoldersToUpdate', () => { const result = computeFoldersToUpdate({ discoveredFolders, existingFolders, - externalIdToUuidMap: emptyMap, }); expect(result.size).toBe(0); @@ -131,7 +120,6 @@ describe('computeFoldersToUpdate', () => { const result = computeFoldersToUpdate({ discoveredFolders, existingFolders, - externalIdToUuidMap: emptyMap, }); expect(result.size).toBe(0); diff --git a/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/compute-folders-to-update.util.ts b/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/compute-folders-to-update.util.ts index 49b7595d79b..4c044ec4cbd 100644 --- a/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/compute-folders-to-update.util.ts +++ b/packages/twenty-server/src/modules/messaging/message-folder-manager/utils/compute-folders-to-update.util.ts @@ -11,11 +11,9 @@ import { type MessageFolderEntity } from 'src/engine/metadata-modules/message-fo export const computeFoldersToUpdate = ({ discoveredFolders, existingFolders, - externalIdToUuidMap, }: { discoveredFolders: DiscoveredMessageFolder[]; existingFolders: MessageFolder[]; - externalIdToUuidMap: Map; }): Map> => { const existingFoldersByExternalId = new Map( existingFolders.map((folder) => [folder.externalId, folder]), @@ -32,16 +30,14 @@ export const computeFoldersToUpdate = ({ continue; } - const resolvedParentFolderId = isNonEmptyString( - discoveredFolder.parentFolderId, - ) - ? (externalIdToUuidMap.get(discoveredFolder.parentFolderId) ?? null) + const parentFolderId = isNonEmptyString(discoveredFolder.parentFolderId) + ? discoveredFolder.parentFolderId : null; const discoveredFolderData = { name: discoveredFolder.name, isSentFolder: discoveredFolder.isSentFolder, - parentFolderId: resolvedParentFolderId, + parentFolderId, }; const existingFolderData = {