diff --git a/package.json b/package.json index 41e8e4b35..c9c7f6f1e 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@linaria/core": "^6.2.0", "@linaria/react": "^6.2.1", "@mdx-js/react": "^3.0.0", + "@microsoft/microsoft-graph-client": "^3.0.7", "@nestjs/apollo": "^11.0.5", "@nestjs/axios": "^3.0.1", "@nestjs/cli": "^9.0.0", @@ -201,6 +202,7 @@ "@graphql-codegen/typescript": "^3.0.4", "@graphql-codegen/typescript-operations": "^3.0.4", "@graphql-codegen/typescript-react-apollo": "^3.3.7", + "@microsoft/microsoft-graph-types": "^2.40.0", "@nestjs/cli": "^9.0.0", "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.0.0", diff --git a/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountEmailAliases.tsx b/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountEmailAliases.tsx index c3f381c1b..67fc042a9 100644 --- a/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountEmailAliases.tsx +++ b/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountEmailAliases.tsx @@ -1,7 +1,7 @@ import { InformationBanner } from '@/information-banner/components/InformationBanner'; import { useAccountToReconnect } from '@/information-banner/hooks/useAccountToReconnect'; import { InformationBannerKeys } from '@/information-banner/types/InformationBannerKeys'; -import { useTriggerGoogleApisOAuth } from '@/settings/accounts/hooks/useTriggerGoogleApisOAuth'; +import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth'; import { IconRefresh } from 'twenty-ui'; export const InformationBannerReconnectAccountEmailAliases = () => { @@ -9,7 +9,7 @@ export const InformationBannerReconnectAccountEmailAliases = () => { InformationBannerKeys.ACCOUNTS_TO_RECONNECT_EMAIL_ALIASES, ); - const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth(); + const { triggerApisOAuth } = useTriggerApisOAuth(); if (!accountToReconnect) { return null; @@ -20,7 +20,7 @@ export const InformationBannerReconnectAccountEmailAliases = () => { message={`Please reconnect your mailbox ${accountToReconnect?.handle} to update your email aliases:`} buttonTitle="Reconnect" buttonIcon={IconRefresh} - buttonOnClick={() => triggerGoogleApisOAuth()} + buttonOnClick={() => triggerApisOAuth(accountToReconnect.provider)} /> ); }; diff --git a/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountInsufficientPermissions.tsx b/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountInsufficientPermissions.tsx index 7f74a129b..306452b56 100644 --- a/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountInsufficientPermissions.tsx +++ b/packages/twenty-front/src/modules/information-banner/components/reconnect-account/InformationBannerReconnectAccountInsufficientPermissions.tsx @@ -1,7 +1,7 @@ import { InformationBanner } from '@/information-banner/components/InformationBanner'; import { useAccountToReconnect } from '@/information-banner/hooks/useAccountToReconnect'; import { InformationBannerKeys } from '@/information-banner/types/InformationBannerKeys'; -import { useTriggerGoogleApisOAuth } from '@/settings/accounts/hooks/useTriggerGoogleApisOAuth'; +import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth'; import { IconRefresh } from 'twenty-ui'; export const InformationBannerReconnectAccountInsufficientPermissions = () => { @@ -9,7 +9,7 @@ export const InformationBannerReconnectAccountInsufficientPermissions = () => { InformationBannerKeys.ACCOUNTS_TO_RECONNECT_INSUFFICIENT_PERMISSIONS, ); - const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth(); + const { triggerApisOAuth } = useTriggerApisOAuth(); if (!accountToReconnect) { return null; @@ -21,7 +21,7 @@ export const InformationBannerReconnectAccountInsufficientPermissions = () => { reconnect for updates:`} buttonTitle="Reconnect" buttonIcon={IconRefresh} - buttonOnClick={() => triggerGoogleApisOAuth()} + buttonOnClick={() => triggerApisOAuth(accountToReconnect.provider)} /> ); }; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx index 238371241..6000afa1f 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx @@ -1,5 +1,5 @@ import { useNavigate } from 'react-router-dom'; -import { IconGoogle } from 'twenty-ui'; +import { IconComponent, IconGoogle, IconMicrosoft } from 'twenty-ui'; import { ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { SettingsAccountsListEmptyStateCard } from '@/settings/accounts/components/SettingsAccountsListEmptyStateCard'; @@ -9,6 +9,11 @@ import { SettingsPath } from '@/types/SettingsPath'; import { SettingsAccountsConnectedAccountsRowRightContainer } from '@/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer'; import { SettingsListCard } from '../../components/SettingsListCard'; +const ProviderIcons: { [k: string]: IconComponent } = { + google: IconGoogle, + microsoft: IconMicrosoft, +}; + export const SettingsAccountsConnectedAccountsListCard = ({ accounts, loading, @@ -27,7 +32,7 @@ export const SettingsAccountsConnectedAccountsListCard = ({ items={accounts} getItemLabel={(account) => account.handle} isLoading={loading} - RowIcon={IconGoogle} + RowIconFn={(row) => ProviderIcons[row.provider]} RowRightComponent={({ item: account }) => ( )} diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx index 8500264c4..d532691fc 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx @@ -1,7 +1,14 @@ +import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth'; +import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import styled from '@emotion/styled'; -import { Button, Card, CardContent, CardHeader, IconGoogle } from 'twenty-ui'; - -import { useTriggerGoogleApisOAuth } from '@/settings/accounts/hooks/useTriggerGoogleApisOAuth'; +import { + Button, + Card, + CardContent, + CardHeader, + IconGoogle, + IconMicrosoft, +} from 'twenty-ui'; const StyledHeader = styled(CardHeader)` align-items: center; @@ -12,6 +19,7 @@ const StyledHeader = styled(CardHeader)` const StyledBody = styled(CardContent)` display: flex; justify-content: center; + gap: ${({ theme }) => theme.spacing(2)}; `; type SettingsAccountsListEmptyStateCardProps = { @@ -21,11 +29,10 @@ type SettingsAccountsListEmptyStateCardProps = { export const SettingsAccountsListEmptyStateCard = ({ label, }: SettingsAccountsListEmptyStateCardProps) => { - const { triggerGoogleApisOAuth } = useTriggerGoogleApisOAuth(); - - const handleOnClick = async () => { - await triggerGoogleApisOAuth(); - }; + const { triggerApisOAuth } = useTriggerApisOAuth(); + const isMicrosoftSyncEnabled = useIsFeatureEnabled( + 'IS_MICROSOFT_SYNC_ENABLED', + ); return ( @@ -35,8 +42,16 @@ export const SettingsAccountsListEmptyStateCard = ({ Icon={IconGoogle} title="Connect with Google" variant="secondary" - onClick={handleOnClick} + onClick={() => triggerApisOAuth('google')} /> + {isMicrosoftSyncEnabled && ( +