Files
twenty/packages/twenty-front/src/pages/settings/integrations/SettingsIntegrationNewDatabaseConnection.tsx
gitstart-app[bot] b09ecfbb8c Migrate to twenty-ui - display (#8004)
This PR was created by [GitStart](https://gitstart.com/) to address the
requirements from this ticket:
[TWNTY-6871](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-6871).

 --- 

### Description

Migrate:

- Info display component
- Status display component
- SeparatorLineText display component

### Demo

###### SeparatorLineText In Storybook


![](https://assets-service.gitstart.com/4814/c0a2cd49-e545-469a-b3d3-c02eb462b60d.png)

Info Component on Storybook


![](https://assets-service.gitstart.com/4814/6f3019c5-99e0-4365-a81e-241294887f9e.png)

Status Component on Storybook


![](https://assets-service.gitstart.com/4814/29b5142a-468f-4d7e-88ff-4f3bfdd5abda.png)

###### Fixes twentyhq/private-issues#95

---------

Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2024-10-24 17:50:14 +02:00

179 lines
5.9 KiB
TypeScript

import { zodResolver } from '@hookform/resolvers/zod';
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom';
import { z } from 'zod';
import { useCreateOneDatabaseConnection } from '@/databases/hooks/useCreateOneDatabaseConnection';
import { getForeignDataWrapperType } from '@/databases/utils/getForeignDataWrapperType';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import {
SettingsIntegrationDatabaseConnectionForm,
settingsIntegrationPostgreSQLConnectionFormSchema,
settingsIntegrationStripeConnectionFormSchema,
} from '@/settings/integrations/database-connection/components/SettingsIntegrationDatabaseConnectionForm';
import { useIsSettingsIntegrationEnabled } from '@/settings/integrations/hooks/useIsSettingsIntegrationEnabled';
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
import { AppPath } from '@/types/AppPath';
import { SettingsPath } from '@/types/SettingsPath';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section';
import { H2Title } from 'twenty-ui';
import { CreateRemoteServerInput } from '~/generated-metadata/graphql';
const createRemoteServerInputPostgresSchema =
settingsIntegrationPostgreSQLConnectionFormSchema.transform<CreateRemoteServerInput>(
(values) => ({
foreignDataWrapperType: 'postgres_fdw',
foreignDataWrapperOptions: {
dbname: values.dbname,
host: values.host,
port: values.port,
},
userMappingOptions: {
password: values.password,
user: values.user,
},
schema: values.schema,
label: values.label,
}),
);
type SettingsIntegrationNewConnectionPostgresFormValues = z.infer<
typeof createRemoteServerInputPostgresSchema
>;
const createRemoteServerInputStripeSchema =
settingsIntegrationStripeConnectionFormSchema.transform<CreateRemoteServerInput>(
(values) => ({
foreignDataWrapperType: 'stripe_fdw',
foreignDataWrapperOptions: {
api_key: values.api_key,
},
label: values.label,
}),
);
type SettingsIntegrationNewConnectionStripeFormValues = z.infer<
typeof createRemoteServerInputStripeSchema
>;
type SettingsIntegrationNewConnectionFormValues =
| SettingsIntegrationNewConnectionPostgresFormValues
| SettingsIntegrationNewConnectionStripeFormValues;
export const SettingsIntegrationNewDatabaseConnection = () => {
const { databaseKey = '' } = useParams();
const navigate = useNavigate();
const [integrationCategoryAll] = useSettingsIntegrationCategories();
const integration = integrationCategoryAll.integrations.find(
({ from: { key } }) => key === databaseKey,
);
const { createOneDatabaseConnection } = useCreateOneDatabaseConnection();
const { enqueueSnackBar } = useSnackBar();
const isIntegrationEnabled = useIsSettingsIntegrationEnabled(databaseKey);
const isIntegrationAvailable = !!integration && isIntegrationEnabled;
useEffect(() => {
if (!isIntegrationAvailable) {
navigate(AppPath.NotFound);
}
}, [integration, databaseKey, navigate, isIntegrationAvailable]);
const newConnectionSchema =
databaseKey === 'postgresql'
? createRemoteServerInputPostgresSchema
: createRemoteServerInputStripeSchema;
const formConfig = useForm<SettingsIntegrationNewConnectionFormValues>({
mode: 'onTouched',
resolver: zodResolver(newConnectionSchema),
});
if (!isIntegrationAvailable) return null;
const settingsIntegrationsPagePath = getSettingsPagePath(
SettingsPath.Integrations,
);
const canSave = formConfig.formState.isValid;
const handleSave = async () => {
const formValues = formConfig.getValues();
try {
const createdConnection = await createOneDatabaseConnection(
newConnectionSchema.parse({
...formValues,
foreignDataWrapperType: getForeignDataWrapperType(databaseKey),
}),
);
const connectionId = createdConnection.data?.createOneRemoteServer.id;
navigate(
`${settingsIntegrationsPagePath}/${databaseKey}/${connectionId}`,
);
} catch (error) {
enqueueSnackBar((error as Error).message, {
variant: SnackBarVariant.Error,
});
}
};
return (
<SubMenuTopBarContainer
title="New"
links={[
{
children: 'Workspace',
href: getSettingsPagePath(SettingsPath.Workspace),
},
{
children: 'Integrations',
href: settingsIntegrationsPagePath,
},
{
children: integration.text,
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
},
{ children: 'New' },
]}
actionButton={
<SaveAndCancelButtons
isSaveDisabled={!canSave}
onCancel={() =>
navigate(`${settingsIntegrationsPagePath}/${databaseKey}`)
}
onSave={handleSave}
/>
}
>
<SettingsPageContainer>
<FormProvider
// eslint-disable-next-line react/jsx-props-no-spreading
{...formConfig}
>
<Section>
<H2Title
title="Connect a new database"
description="Provide the information to connect your database"
/>
<SettingsIntegrationDatabaseConnectionForm
databaseKey={databaseKey}
/>
</Section>
</FormProvider>
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
};