diff --git a/packages/twenty-front/src/modules/settings/components/SettingsListCard.tsx b/packages/twenty-front/src/modules/settings/components/SettingsListCard.tsx index 6ca88219a..b1b35854a 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsListCard.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsListCard.tsx @@ -42,7 +42,7 @@ type SettingsListCardProps = { hasFooter?: boolean; isLoading?: boolean; onRowClick?: (item: ListItem) => void; - RowIcon: IconComponent; + RowIcon?: IconComponent; RowRightComponent: ComponentType<{ item: ListItem }>; footerButtonLabel?: string; onFooterButtonClick?: () => void; diff --git a/packages/twenty-front/src/modules/settings/components/SettingsListItemCardContent.tsx b/packages/twenty-front/src/modules/settings/components/SettingsListItemCardContent.tsx index 206951eb6..2daae18f5 100644 --- a/packages/twenty-front/src/modules/settings/components/SettingsListItemCardContent.tsx +++ b/packages/twenty-front/src/modules/settings/components/SettingsListItemCardContent.tsx @@ -14,16 +14,17 @@ const StyledRow = styled(CardContent)` gap: ${({ theme }) => theme.spacing(2)}; padding: ${({ theme }) => theme.spacing(2)}; padding-left: ${({ theme }) => theme.spacing(3)}; + min-height: ${({ theme }) => theme.spacing(6)}; `; -const StyledAccountHandle = styled.span` +const StyledLabel = styled.span` flex: 1 0 auto; `; type SettingsListItemCardContentProps = { label: string; divider?: boolean; - LeftIcon: IconComponent; + LeftIcon?: IconComponent; onClick?: () => void; rightComponent: ReactNode; }; @@ -39,8 +40,8 @@ export const SettingsListItemCardContent = ({ return ( - - {label} + {!!LeftIcon && } + {label} {rightComponent} ); diff --git a/packages/twenty-front/src/modules/settings/integrations/components/SettingsIntegrationDatabaseTablesListCard.tsx b/packages/twenty-front/src/modules/settings/integrations/components/SettingsIntegrationDatabaseTablesListCard.tsx new file mode 100644 index 000000000..1581ecc37 --- /dev/null +++ b/packages/twenty-front/src/modules/settings/integrations/components/SettingsIntegrationDatabaseTablesListCard.tsx @@ -0,0 +1,50 @@ +import { Controller, useFormContext } from 'react-hook-form'; +import styled from '@emotion/styled'; +import { z } from 'zod'; + +import { SettingsListCard } from '@/settings/components/SettingsListCard'; +import { Toggle } from '@/ui/input/components/Toggle'; + +export const settingsIntegrationsDatabaseTablesSchema = z.object({ + syncedTablesById: z.record(z.boolean()), +}); + +export type SettingsIntegrationsDatabaseTablesFormValues = z.infer< + typeof settingsIntegrationsDatabaseTablesSchema +>; + +type SettingsIntegrationDatabaseTablesListCardProps = { + tables: { id: string; name: string; isSynced?: boolean }[]; +}; + +const StyledRowRightContainer = styled.div` + align-items: center; + display: flex; + gap: ${({ theme }) => theme.spacing(1)}; +`; + +export const SettingsIntegrationDatabaseTablesListCard = ({ + tables, +}: SettingsIntegrationDatabaseTablesListCardProps) => { + const { control } = + useFormContext(); + + return ( + ( + + ( + + )} + /> + + )} + getItemLabel={(table) => table.name} + /> + ); +}; diff --git a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx index dd1594ea2..c84390bd8 100644 --- a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx @@ -1,8 +1,15 @@ import { useEffect } from 'react'; +import { FormProvider, useForm } from 'react-hook-form'; import { useNavigate, useParams } from 'react-router-dom'; +import { zodResolver } from '@hookform/resolvers/zod'; import { IconSettings } from 'twenty-ui'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; +import { + SettingsIntegrationDatabaseTablesListCard, + SettingsIntegrationsDatabaseTablesFormValues, + settingsIntegrationsDatabaseTablesSchema, +} from '@/settings/integrations/components/SettingsIntegrationDatabaseTablesListCard'; import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories'; import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath'; import { AppPath } from '@/types/AppPath'; @@ -47,37 +54,54 @@ export const SettingsIntegrationDatabaseConnection = () => { } }, [integration, databaseKey, navigate, isIntegrationAvailable, connection]); + const formConfig = useForm({ + mode: 'onTouched', + resolver: zodResolver(settingsIntegrationsDatabaseTablesSchema), + }); + if (!isIntegrationAvailable || !connection) return null; const settingsIntegrationsPagePath = getSettingsPagePath( SettingsPath.Integrations, ); + const tables = mockedRemoteObjectIntegrations[0].connections[0].tables; + return ( - - - -
- - + + + -
-
-
+
+ + +
+
+ + +
+ + + ); }; diff --git a/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts b/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts index aa64e7800..5369b9316 100644 --- a/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts +++ b/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts @@ -7,13 +7,19 @@ export const mockedRemoteObjectIntegrations = [ id: '67cbfd35-8dd4-4591-b9d4-c1906281a5da', key: 'twenty_postgres', name: 'Twenty_postgres', - tables: [{ name: '1' }], + tables: [ + { id: 'invoices', name: 'Invoices' }, + { id: 'quotes', name: 'Quotes', isSynced: true }, + { id: 'customers', name: 'Customers', isSynced: false }, + { id: 'subscriptions', name: 'Subscriptions', isSynced: true }, + { id: 'payments', name: 'Payments' }, + ], }, { id: '3740cd85-7a1e-45b5-8b0d-47e1921d01f3', key: 'image_postgres', name: 'Image_postgres', - tables: [{ name: '2' }, { name: '3' }], + tables: [], }, ], },