diff --git a/packages/twenty-front/src/App.tsx b/packages/twenty-front/src/App.tsx index 62d6f16c6..9dd101d0a 100644 --- a/packages/twenty-front/src/App.tsx +++ b/packages/twenty-front/src/App.tsx @@ -40,8 +40,9 @@ import { SettingsDevelopersApiKeysNew } from '~/pages/settings/developers/api-ke import { SettingsDevelopers } from '~/pages/settings/developers/SettingsDevelopers'; import { SettingsDevelopersWebhooksDetail } from '~/pages/settings/developers/webhooks/SettingsDevelopersWebhookDetail'; import { SettingsDevelopersWebhooksNew } from '~/pages/settings/developers/webhooks/SettingsDevelopersWebhooksNew'; -import { SettingsIntegrationDetail } from '~/pages/settings/integrations/SettingsIntegrationDetail'; -import { SettingsIntegrationNewDatabase } from '~/pages/settings/integrations/SettingsIntegrationNewDatabase'; +import { SettingsIntegrationDatabase } from '~/pages/settings/integrations/SettingsIntegrationDatabase'; +import { SettingsIntegrationDatabaseConnection } from '~/pages/settings/integrations/SettingsIntegrationDatabaseConnection'; +import { SettingsIntegrationNewDatabaseConnection } from '~/pages/settings/integrations/SettingsIntegrationNewDatabaseConnection'; import { SettingsIntegrations } from '~/pages/settings/integrations/SettingsIntegrations'; import { SettingsAppearance } from '~/pages/settings/SettingsAppearance'; import { SettingsBilling } from '~/pages/settings/SettingsBilling.tsx'; @@ -178,12 +179,16 @@ export const App = () => { element={} /> } + path={SettingsPath.IntegrationDatabase} + element={} /> } + path={SettingsPath.IntegrationNewDatabaseConnection} + element={} + /> + } /> theme.spacing(4)}; @@ -26,7 +26,7 @@ const StyledIntegrationLogoContainer = styled.div` width: ${({ theme }) => theme.spacing(4)}; `; -const StyledIntegrationLogo = styled.img` +const StyledDatabaseLogo = styled.img` height: 100%; `; @@ -36,35 +36,35 @@ const StyledRowRightContainer = styled.div` gap: ${({ theme }) => theme.spacing(1)}; `; -export const SettingsIntegrationDatabasesListCard = ({ - integrationLogoUrl, - databases, -}: SettingsIntegrationDatabasesListCardProps) => { +export const SettingsIntegrationDatabaseConnectionsListCard = ({ + databaseLogoUrl, + connections, +}: SettingsIntegrationDatabaseConnectionsListCardProps) => { const navigate = useNavigate(); return ( ( - - - + + + )} - RowRightComponent={({ item: database }) => ( + RowRightComponent={({ item: connection }) => ( )} - onRowClick={(database) => navigate(`./${database.key}`)} - getItemLabel={(database) => database.name} + onRowClick={(connection) => navigate(`./${connection.key}`)} + getItemLabel={(connection) => connection.name} hasFooter footerButtonLabel="Add connection" onFooterButtonClick={() => navigate('./new')} diff --git a/packages/twenty-front/src/modules/types/SettingsPath.ts b/packages/twenty-front/src/modules/types/SettingsPath.ts index bb36263d2..f61394d4e 100644 --- a/packages/twenty-front/src/modules/types/SettingsPath.ts +++ b/packages/twenty-front/src/modules/types/SettingsPath.ts @@ -21,8 +21,9 @@ export enum SettingsPath { DevelopersNewApiKey = 'api-keys/new', DevelopersApiKeyDetail = 'api-keys/:apiKeyId', Integrations = 'integrations', - IntegrationDetail = 'integrations/:integrationKey', - IntegrationNewDatabase = 'integrations/:integrationKey/new', + IntegrationDatabase = 'integrations/:databaseKey', + IntegrationDatabaseConnection = 'integrations/:databaseKey/:connectionKey', + IntegrationNewDatabaseConnection = 'integrations/:databaseKey/new', DevelopersNewWebhook = 'webhooks/new', DevelopersNewWebhookDetail = 'webhooks/:webhookId', } diff --git a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDetail.tsx b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabase.tsx similarity index 78% rename from packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDetail.tsx rename to packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabase.tsx index 7d6c6414a..625b16bec 100644 --- a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDetail.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabase.tsx @@ -3,7 +3,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { IconSettings } from 'twenty-ui'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; -import { SettingsIntegrationDatabasesListCard } from '@/settings/integrations/components/SettingsIntegrationDatabasesListCard'; +import { SettingsIntegrationDatabaseConnectionsListCard } from '@/settings/integrations/components/SettingsIntegrationDatabaseConnectionsListCard'; import { SettingsIntegrationPreview } from '@/settings/integrations/components/SettingsIntegrationPreview'; import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories'; import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath'; @@ -16,13 +16,13 @@ import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; import { mockedRemoteObjectIntegrations } from '~/testing/mock-data/remoteObjectDatabases'; -export const SettingsIntegrationDetail = () => { - const { integrationKey = '' } = useParams(); +export const SettingsIntegrationDatabase = () => { + const { databaseKey = '' } = useParams(); const navigate = useNavigate(); const [integrationCategoryAll] = useSettingsIntegrationCategories(); const integration = integrationCategoryAll.integrations.find( - ({ from: { key } }) => key === integrationKey, + ({ from: { key } }) => key === databaseKey, ); const isAirtableIntegrationEnabled = useIsFeatureEnabled( @@ -33,21 +33,21 @@ export const SettingsIntegrationDetail = () => { ); const isIntegrationAvailable = !!integration && - ((integrationKey === 'airtable' && isAirtableIntegrationEnabled) || - (integrationKey === 'postgresql' && isPostgresqlIntegrationEnabled)); + ((databaseKey === 'airtable' && isAirtableIntegrationEnabled) || + (databaseKey === 'postgresql' && isPostgresqlIntegrationEnabled)); useEffect(() => { if (!isIntegrationAvailable) { navigate(AppPath.NotFound); } - }, [integration, integrationKey, navigate, isIntegrationAvailable]); + }, [integration, databaseKey, navigate, isIntegrationAvailable]); if (!isIntegrationAvailable) return null; - const databases = + const connections = mockedRemoteObjectIntegrations.find( ({ key }) => key === integration.from.key, - )?.databases || []; + )?.connections || []; return ( @@ -69,9 +69,9 @@ export const SettingsIntegrationDetail = () => { title={`${integration.text} database`} description={`Connect or access your ${integration.text} data`} /> - diff --git a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx new file mode 100644 index 000000000..7dae2081a --- /dev/null +++ b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationDatabaseConnection.tsx @@ -0,0 +1,68 @@ +import { useEffect } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { IconSettings } from 'twenty-ui'; + +import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; +import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories'; +import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath'; +import { AppPath } from '@/types/AppPath'; +import { SettingsPath } from '@/types/SettingsPath'; +import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; +import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; +import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; +import { mockedRemoteObjectIntegrations } from '~/testing/mock-data/remoteObjectDatabases'; + +export const SettingsIntegrationDatabaseConnection = () => { + const { databaseKey = '', connectionKey = '' } = useParams(); + const navigate = useNavigate(); + + const [integrationCategoryAll] = useSettingsIntegrationCategories(); + const integration = integrationCategoryAll.integrations.find( + ({ from: { key } }) => key === databaseKey, + ); + + const isAirtableIntegrationEnabled = useIsFeatureEnabled( + 'IS_AIRTABLE_INTEGRATION_ENABLED', + ); + const isPostgresqlIntegrationEnabled = useIsFeatureEnabled( + 'IS_POSTGRESQL_INTEGRATION_ENABLED', + ); + const isIntegrationAvailable = + !!integration && + ((databaseKey === 'airtable' && isAirtableIntegrationEnabled) || + (databaseKey === 'postgresql' && isPostgresqlIntegrationEnabled)); + + const connections = + mockedRemoteObjectIntegrations.find( + ({ key }) => key === integration?.from.key, + )?.connections || []; + const connection = connections.find(({ key }) => key === connectionKey); + + useEffect(() => { + if (!isIntegrationAvailable || !connection) { + navigate(AppPath.NotFound); + } + }, [integration, databaseKey, navigate, isIntegrationAvailable, connection]); + + if (!isIntegrationAvailable || !connection) return null; + + return ( + + + + + + ); +}; diff --git a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabase.tsx b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabaseConnection.tsx similarity index 78% rename from packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabase.tsx rename to packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabaseConnection.tsx index 4c23501de..cb6daa5b2 100644 --- a/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabase.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabaseConnection.tsx @@ -9,13 +9,13 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer' import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb'; import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled'; -export const SettingsIntegrationNewDatabase = () => { - const { integrationKey = '' } = useParams(); +export const SettingsIntegrationNewDatabaseConnection = () => { + const { databaseKey = '' } = useParams(); const navigate = useNavigate(); const [integrationCategoryAll] = useSettingsIntegrationCategories(); const integration = integrationCategoryAll.integrations.find( - ({ from: { key } }) => key === integrationKey, + ({ from: { key } }) => key === databaseKey, ); const isAirtableIntegrationEnabled = useIsFeatureEnabled( @@ -26,14 +26,14 @@ export const SettingsIntegrationNewDatabase = () => { ); const isIntegrationAvailable = !!integration && - ((integrationKey === 'airtable' && isAirtableIntegrationEnabled) || - (integrationKey === 'postgresql' && isPostgresqlIntegrationEnabled)); + ((databaseKey === 'airtable' && isAirtableIntegrationEnabled) || + (databaseKey === 'postgresql' && isPostgresqlIntegrationEnabled)); useEffect(() => { if (!isIntegrationAvailable) { navigate(AppPath.NotFound); } - }, [integration, integrationKey, navigate, isIntegrationAvailable]); + }, [integration, databaseKey, navigate, isIntegrationAvailable]); if (!isIntegrationAvailable) return null; @@ -45,7 +45,7 @@ export const SettingsIntegrationNewDatabase = () => { { children: 'Integrations', href: '/settings/integrations' }, { children: integration.text, - href: `/settings/integrations/${integrationKey}`, + href: `/settings/integrations/${databaseKey}`, }, { children: 'New' }, ]} diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDetail.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx similarity index 56% rename from packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDetail.stories.tsx rename to packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx index 116343755..1114e3c75 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDetail.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabase.stories.tsx @@ -2,7 +2,7 @@ import { Meta, StoryObj } from '@storybook/react'; import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath'; import { SettingsPath } from '@/types/SettingsPath'; -import { SettingsIntegrationDetail } from '~/pages/settings/integrations/SettingsIntegrationDetail'; +import { SettingsIntegrationDatabase } from '~/pages/settings/integrations/SettingsIntegrationDatabase'; import { PageDecorator, PageDecoratorArgs, @@ -10,12 +10,12 @@ import { import { graphqlMocks } from '~/testing/graphqlMocks'; const meta: Meta = { - title: 'Pages/Settings/Integrations/SettingsIntegrationDetail', - component: SettingsIntegrationDetail, + title: 'Pages/Settings/Integrations/SettingsIntegrationDatabase', + component: SettingsIntegrationDatabase, decorators: [PageDecorator], args: { - routePath: getSettingsPagePath(SettingsPath.IntegrationDetail), - routeParams: { ':integrationKey': 'postgresql' }, + routePath: getSettingsPagePath(SettingsPath.IntegrationDatabase), + routeParams: { ':databaseKey': 'postgresql' }, }, parameters: { msw: graphqlMocks, @@ -24,6 +24,6 @@ const meta: Meta = { export default meta; -export type Story = StoryObj; +export type Story = StoryObj; export const Default: Story = {}; diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabaseConnection.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabaseConnection.stories.tsx new file mode 100644 index 000000000..df3dfedb8 --- /dev/null +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationDatabaseConnection.stories.tsx @@ -0,0 +1,32 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath'; +import { SettingsPath } from '@/types/SettingsPath'; +import { SettingsIntegrationDatabaseConnection } from '~/pages/settings/integrations/SettingsIntegrationDatabaseConnection'; +import { + PageDecorator, + PageDecoratorArgs, +} from '~/testing/decorators/PageDecorator'; +import { graphqlMocks } from '~/testing/graphqlMocks'; + +const meta: Meta = { + title: 'Pages/Settings/Integrations/SettingsIntegrationDatabaseConnection', + component: SettingsIntegrationDatabaseConnection, + decorators: [PageDecorator], + args: { + routePath: getSettingsPagePath(SettingsPath.IntegrationDatabaseConnection), + routeParams: { + ':databaseKey': 'postgresql', + ':connectionKey': 'twenty_postgres', + }, + }, + parameters: { + msw: graphqlMocks, + }, +}; + +export default meta; + +export type Story = StoryObj; + +export const Default: Story = {}; diff --git a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabase.stories.tsx b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx similarity index 61% rename from packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabase.stories.tsx rename to packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx index 0ee3ebb1b..aa98b1a9d 100644 --- a/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabase.stories.tsx +++ b/packages/twenty-front/src/pages/settings/integrations/__stories__/SettingsIntegrationNewDatabaseConnection.stories.tsx @@ -1,6 +1,6 @@ import { Meta, StoryObj } from '@storybook/react'; -import { SettingsIntegrationNewDatabase } from '~/pages/settings/integrations/SettingsIntegrationNewDatabase'; +import { SettingsIntegrationNewDatabaseConnection } from '~/pages/settings/integrations/SettingsIntegrationNewDatabaseConnection'; import { PageDecorator, PageDecoratorArgs, @@ -8,12 +8,12 @@ import { import { graphqlMocks } from '~/testing/graphqlMocks'; const meta: Meta = { - title: 'Pages/Settings/Integrations/SettingsIntegrationNewDatabase', - component: SettingsIntegrationNewDatabase, + title: 'Pages/Settings/Integrations/SettingsIntegrationNewDatabaseConnection', + component: SettingsIntegrationNewDatabaseConnection, decorators: [PageDecorator], args: { - routePath: '/settings/integrations/:integrationKey/new', - routeParams: { ':integrationKey': 'postgresql' }, + routePath: '/settings/integrations/:databaseKey/new', + routeParams: { ':databaseKey': 'postgresql' }, }, parameters: { msw: graphqlMocks, @@ -22,6 +22,6 @@ const meta: Meta = { export default meta; -export type Story = StoryObj; +export type Story = StoryObj; export const Default: Story = {}; diff --git a/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts b/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts index cb235a99f..aa64e7800 100644 --- a/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts +++ b/packages/twenty-front/src/testing/mock-data/remoteObjectDatabases.ts @@ -2,7 +2,7 @@ export const mockedRemoteObjectIntegrations = [ { id: '5b717911-dc75-4876-bf33-dfdc994c88cd', key: 'postgresql', - databases: [ + connections: [ { id: '67cbfd35-8dd4-4591-b9d4-c1906281a5da', key: 'twenty_postgres',