Add stripe connection option (#5372)

- Refactor creation and edition form so it handles stripe integration
and not only postgres
- Add a hook `useIsSettingsIntegrationEnabled` to avoid checking feature
flags everywhere
- Add zod schema for stripe

<img width="250" alt="Capture d’écran 2024-05-13 à 12 41 52"
src="https://github.com/twentyhq/twenty/assets/22936103/a77e7278-5d79-4f95-bddb-ae9ddd1426eb">
<img width="250" alt="Capture d’écran 2024-05-13 à 12 41 59"
src="https://github.com/twentyhq/twenty/assets/22936103/d617dc6a-31a4-43c8-8192-dbfb7157de1c">
<img width="250" alt="Capture d’écran 2024-05-13 à 12 42 08"
src="https://github.com/twentyhq/twenty/assets/22936103/c4e2d0e4-f826-436d-89be-4d1679a27861">

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
Thomas Trompette
2024-05-13 18:00:13 +02:00
committed by GitHub
parent b9154f315e
commit de438b0171
19 changed files with 251 additions and 100 deletions

View File

@ -11,9 +11,11 @@ import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import {
SettingsIntegrationPostgreSQLConnectionForm,
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';
@ -23,33 +25,47 @@ 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 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,
}),
);
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.user,
},
schema: values.schema,
}));
type SettingsIntegrationNewConnectionFormValues = z.infer<
typeof newConnectionSchema
type SettingsIntegrationNewConnectionPostgresFormValues = z.infer<
typeof createRemoteServerInputPostgresSchema
>;
const createRemoteServerInputStripeSchema =
settingsIntegrationStripeConnectionFormSchema.transform<CreateRemoteServerInput>(
(values) => ({
foreignDataWrapperType: 'stripe_fdw',
foreignDataWrapperOptions: {
api_key: values.api_key,
},
}),
);
type SettingsIntegrationNewConnectionStripeFormValues = z.infer<
typeof createRemoteServerInputStripeSchema
>;
type SettingsIntegrationNewConnectionFormValues =
| SettingsIntegrationNewConnectionPostgresFormValues
| SettingsIntegrationNewConnectionStripeFormValues;
export const SettingsIntegrationNewDatabaseConnection = () => {
const { databaseKey = '' } = useParams();
const navigate = useNavigate();
@ -62,16 +78,9 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
const { createOneDatabaseConnection } = useCreateOneDatabaseConnection();
const { enqueueSnackBar } = useSnackBar();
const isAirtableIntegrationEnabled = useIsFeatureEnabled(
'IS_AIRTABLE_INTEGRATION_ENABLED',
);
const isPostgresqlIntegrationEnabled = useIsFeatureEnabled(
'IS_POSTGRESQL_INTEGRATION_ENABLED',
);
const isIntegrationAvailable =
!!integration &&
((databaseKey === 'airtable' && isAirtableIntegrationEnabled) ||
(databaseKey === 'postgresql' && isPostgresqlIntegrationEnabled));
const isIntegrationEnabled = useIsSettingsIntegrationEnabled(databaseKey);
const isIntegrationAvailable = !!integration && isIntegrationEnabled;
useEffect(() => {
if (!isIntegrationAvailable) {
@ -79,6 +88,11 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
}
}, [integration, databaseKey, navigate, isIntegrationAvailable]);
const newConnectionSchema =
databaseKey === 'postgresql'
? createRemoteServerInputPostgresSchema
: createRemoteServerInputStripeSchema;
const formConfig = useForm<SettingsIntegrationNewConnectionFormValues>({
mode: 'onTouched',
resolver: zodResolver(newConnectionSchema),
@ -97,7 +111,7 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
try {
const createdConnection = await createOneDatabaseConnection(
createRemoteServerInputSchema.parse({
newConnectionSchema.parse({
...formValues,
foreignDataWrapperType: getForeignDataWrapperType(databaseKey),
}),
@ -144,15 +158,15 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
onSave={handleSave}
/>
</SettingsHeaderContainer>
{databaseKey === 'postgresql' ? (
<Section>
<H2Title
title="Connect a new database"
description="Provide the information to connect your PostgreSQL database"
/>
<SettingsIntegrationPostgreSQLConnectionForm />
</Section>
) : null}
<Section>
<H2Title
title="Connect a new database"
description="Provide the information to connect your database"
/>
<SettingsIntegrationDatabaseConnectionForm
databaseKey={databaseKey}
/>
</Section>
</FormProvider>
</SettingsPageContainer>
</SubMenuTopBarContainer>