Add new database connection (#4837)
Closes https://github.com/twentyhq/twenty/issues/4555 <img width="593" alt="Capture d’écran 2024-04-05 à 11 54 28" src="https://github.com/twentyhq/twenty/assets/22936103/e6021417-bc78-460b-adf6-834330bbd894"> Connect the existing for with the backend so we can now create database connections. --------- Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
@ -5,6 +5,10 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useCreateOneDatabaseConnection } from '@/databases/hooks/useCreateOneDatabaseConnection';
|
||||
import { getForeignDataWrapperType } from '@/databases/utils/getForeignDataWrapperType';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import {
|
||||
SettingsIntegrationPostgreSQLConnectionForm,
|
||||
@ -15,13 +19,32 @@ import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { H2Title } from '@/ui/display/typography/components/H2Title';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { CreateRemoteServerInput } from '~/generated-metadata/graphql';
|
||||
|
||||
const newConnectionSchema = settingsIntegrationPostgreSQLConnectionFormSchema;
|
||||
|
||||
const createRemoteServerInputSchema = newConnectionSchema
|
||||
.extend({
|
||||
foreignDataWrapperType: z.string().min(1),
|
||||
})
|
||||
.transform<CreateRemoteServerInput>((values) => ({
|
||||
foreignDataWrapperType: values.foreignDataWrapperType,
|
||||
foreignDataWrapperOptions: {
|
||||
dbname: values.dbname,
|
||||
host: values.host,
|
||||
port: values.port,
|
||||
},
|
||||
userMappingOptions: {
|
||||
password: values.password,
|
||||
user: values.username,
|
||||
},
|
||||
}));
|
||||
|
||||
type SettingsIntegrationNewConnectionFormValues = z.infer<
|
||||
typeof newConnectionSchema
|
||||
>;
|
||||
@ -35,6 +58,9 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
|
||||
({ from: { key } }) => key === databaseKey,
|
||||
);
|
||||
|
||||
const { createOneDatabaseConnection } = useCreateOneDatabaseConnection();
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
const isAirtableIntegrationEnabled = useIsFeatureEnabled(
|
||||
'IS_AIRTABLE_INTEGRATION_ENABLED',
|
||||
);
|
||||
@ -63,24 +89,54 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
|
||||
SettingsPath.Integrations,
|
||||
);
|
||||
|
||||
const canSave = formConfig.formState.isValid;
|
||||
|
||||
const handleSave = async () => {
|
||||
const formValues = formConfig.getValues();
|
||||
|
||||
try {
|
||||
await createOneDatabaseConnection(
|
||||
createRemoteServerInputSchema.parse({
|
||||
...formValues,
|
||||
foreignDataWrapperType: getForeignDataWrapperType(databaseKey),
|
||||
}),
|
||||
);
|
||||
|
||||
navigate(`${settingsIntegrationsPagePath}/${databaseKey}`);
|
||||
} catch (error) {
|
||||
enqueueSnackBar((error as Error).message, {
|
||||
variant: 'error',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<FormProvider {...formConfig}>
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Integrations',
|
||||
href: settingsIntegrationsPagePath,
|
||||
},
|
||||
{
|
||||
children: integration.text,
|
||||
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
|
||||
},
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Integrations',
|
||||
href: settingsIntegrationsPagePath,
|
||||
},
|
||||
{
|
||||
children: integration.text,
|
||||
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
|
||||
},
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() =>
|
||||
navigate(`${settingsIntegrationsPagePath}/${databaseKey}`)
|
||||
}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
{databaseKey === 'postgresql' ? (
|
||||
<Section>
|
||||
<H2Title
|
||||
|
||||
Reference in New Issue
Block a user