From c021d4c13af943290ad8f11fc141771e3cca5f01 Mon Sep 17 00:00:00 2001 From: Nick Zelei <2420177+nickzelei@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:17:09 -0700 Subject: [PATCH] Nick/neos 1029 cloning a connection opens to the wrong tab (#1874) --- .../new/connection/mysql/MysqlForm.tsx | 127 +++++++------- .../new/connection/postgres/PostgresForm.tsx | 162 +++++++++--------- 2 files changed, 146 insertions(+), 143 deletions(-) diff --git a/frontend/apps/web/app/(mgmt)/[account]/new/connection/mysql/MysqlForm.tsx b/frontend/apps/web/app/(mgmt)/[account]/new/connection/mysql/MysqlForm.tsx index a3317c1ee..fd2a84a93 100644 --- a/frontend/apps/web/app/(mgmt)/[account]/new/connection/mysql/MysqlForm.tsx +++ b/frontend/apps/web/app/(mgmt)/[account]/new/connection/mysql/MysqlForm.tsx @@ -34,6 +34,7 @@ import { import { Textarea } from '@/components/ui/textarea'; import { toast } from '@/components/ui/use-toast'; import { useGetAccountOnboardingConfig } from '@/libs/hooks/useGetAccountOnboardingConfig'; +import { getConnection } from '@/libs/hooks/useGetConnection'; import { getErrorMessage } from '@/util/util'; import { MYSQL_CONNECTION_PROTOCOLS, @@ -63,7 +64,6 @@ import { import { useRouter, useSearchParams } from 'next/navigation'; import { ReactElement, useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; -import { getConnection } from '@/libs/hooks/useGetConnection'; export default function MysqlForm() { const { account } = useAccount(); @@ -192,71 +192,80 @@ the hook in the useEffect conditionally. This is used to retrieve the values for */ useEffect(() => { const fetchData = async () => { - if (sourceConnId && account?.id) { - setIsLoading(true); - try { - const connData = await getConnection(account.id, sourceConnId); - - if ( - connData && - connData.connection?.connectionConfig?.config.case === 'mysqlConfig' - ) { - const config = connData.connection?.connectionConfig?.config.value; + if (!sourceConnId || !account?.id) { + return; + } + setIsLoading(true); - let mysqlConfig: MysqlConnection = new MysqlConnection({}); + try { + const connData = await getConnection(account.id, sourceConnId); + if ( + connData.connection?.connectionConfig?.config.case !== 'mysqlConfig' + ) { + return; + } - if (config.connectionConfig.case == 'connection') { - mysqlConfig = config.connectionConfig.value; - } + const config = connData.connection?.connectionConfig?.config.value; + const mysqlConfig = config.connectionConfig.value; - let passPhrase = ''; - let privateKey = ''; + const dbConfig = { + host: '', + name: '', + user: '', + pass: '', + port: 3306, + protocol: 'tcp', + }; + if (typeof mysqlConfig !== 'string') { + dbConfig.host = mysqlConfig?.host ?? ''; + dbConfig.name = mysqlConfig?.name ?? ''; + dbConfig.user = mysqlConfig?.user ?? ''; + dbConfig.pass = mysqlConfig?.pass ?? ''; + dbConfig.port = mysqlConfig?.port ?? 3306; + dbConfig.protocol = mysqlConfig?.protocol ?? 'tcp'; + } - const authConfig = config.tunnel?.authentication?.authConfig; + let passPhrase = ''; + let privateKey = ''; - switch (authConfig?.case) { - case 'passphrase': - passPhrase = authConfig.value.value; - break; - case 'privateKey': - passPhrase = authConfig.value.passphrase ?? ''; - privateKey = authConfig.value.value; - break; - } + const authConfig = config.tunnel?.authentication?.authConfig; - /* reset the form with the new values and include the fallback values because of our validation schema requires a string and not undefined which is okay because it will tell the user that something is wrong instead of the user not realizing that it's undefined - */ - form.reset({ - ...form.getValues(), - connectionName: connData.connection?.name + '-copy', - db: { - host: mysqlConfig.host ?? '', - name: mysqlConfig.name ?? '', - user: mysqlConfig.user ?? '', - pass: mysqlConfig.pass ?? '', - port: mysqlConfig.port ?? 3306, - protocol: mysqlConfig.protocol ?? 'tcp', - }, - tunnel: { - host: config.tunnel?.host ?? '', - port: config.tunnel?.port ?? 22, - knownHostPublicKey: config.tunnel?.knownHostPublicKey ?? '', - user: config.tunnel?.user ?? '', - passphrase: passPhrase, - privateKey: privateKey, - }, - }); - } - } catch (error) { - console.error('Failed to fetch connection data:', error); - setIsLoading(false); - toast({ - title: 'Unable to clone connection!', - variant: 'destructive', - }); - } finally { - setIsLoading(false); + switch (authConfig?.case) { + case 'passphrase': + passPhrase = authConfig.value.value; + break; + case 'privateKey': + passPhrase = authConfig.value.passphrase ?? ''; + privateKey = authConfig.value.value; + break; } + + /* reset the form with the new values and include the fallback values because of our validation schema requires a string and not undefined which is okay because it will tell the user that something is wrong instead of the user not realizing that it's undefined + */ + form.reset({ + ...form.getValues(), + connectionName: connData.connection?.name + '-copy', + db: dbConfig, + // url: typeof mysqlConfig === 'string' ? mysqlConfig : '', + tunnel: { + host: config.tunnel?.host ?? '', + port: config.tunnel?.port ?? 22, + knownHostPublicKey: config.tunnel?.knownHostPublicKey ?? '', + user: config.tunnel?.user ?? '', + passphrase: passPhrase, + privateKey: privateKey, + }, + }); + } catch (error) { + console.error('Failed to fetch connection data:', error); + setIsLoading(false); + toast({ + title: 'Unable to retrieve connection data for clone!', + description: getErrorMessage(error), + variant: 'destructive', + }); + } finally { + setIsLoading(false); } }; diff --git a/frontend/apps/web/app/(mgmt)/[account]/new/connection/postgres/PostgresForm.tsx b/frontend/apps/web/app/(mgmt)/[account]/new/connection/postgres/PostgresForm.tsx index e421f774d..980e76404 100644 --- a/frontend/apps/web/app/(mgmt)/[account]/new/connection/postgres/PostgresForm.tsx +++ b/frontend/apps/web/app/(mgmt)/[account]/new/connection/postgres/PostgresForm.tsx @@ -65,6 +65,8 @@ import { useRouter, useSearchParams } from 'next/navigation'; import { ReactElement, useEffect, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; +type ActiveTab = 'host' | 'url'; + export default function PostgresForm() { const searchParams = useSearchParams(); const { account } = useAccount(); @@ -74,7 +76,7 @@ export default function PostgresForm() { account?.id ?? '' ); // used to know which tab - host or url that the user is on when we submit the form - const [activeTab, setActiveTab] = useState('url'); + const [activeTab, setActiveTab] = useState('url'); const form = useForm({ resolver: yupResolver(POSTGRES_FORM_SCHEMA), @@ -217,92 +219,84 @@ the hook in the useEffect conditionally. This is used to retrieve the values for */ useEffect(() => { const fetchData = async () => { - if (sourceConnId && account?.id) { - setIsLoading(true); - try { - const connData = await getConnection(account.id, sourceConnId); - - if ( - connData && - connData.connection?.connectionConfig?.config.case === 'pgConfig' - ) { - const config = connData.connection?.connectionConfig?.config.value; - - let pgConfig: PostgresConnection | string | undefined; - - if (config.connectionConfig.case == 'connection') { - pgConfig = config.connectionConfig.value; - } else if (config.connectionConfig.case == 'url') { - pgConfig = config.connectionConfig.value; - } + if (!sourceConnId || !account?.id) { + return; + } + setIsLoading(true); + try { + const connData = await getConnection(account.id, sourceConnId); + if (connData.connection?.connectionConfig?.config.case !== 'pgConfig') { + return; + } - const defaultDb = { - host: '', - name: '', - user: '', - pass: '', - port: 5432, - sslMode: 'disable', - }; - - let dbConfig = defaultDb; - if (typeof pgConfig !== 'string') { - dbConfig = { - host: pgConfig?.host ?? '', - name: pgConfig?.name ?? '', - user: pgConfig?.user ?? '', - pass: pgConfig?.pass ?? '', - port: pgConfig?.port ?? 5432, - sslMode: pgConfig?.sslMode ?? 'disable', - }; - } + const config = connData.connection?.connectionConfig?.config.value; + const pgConfig = config.connectionConfig.value; + + const dbConfig = { + host: '', + name: '', + user: '', + pass: '', + port: 5432, + sslMode: 'disable', + }; + if (typeof pgConfig !== 'string') { + dbConfig.host = pgConfig?.host ?? ''; + dbConfig.name = pgConfig?.name ?? ''; + dbConfig.user = pgConfig?.user ?? ''; + dbConfig.pass = pgConfig?.pass ?? ''; + dbConfig.port = pgConfig?.port ?? 5432; + dbConfig.sslMode = pgConfig?.sslMode ?? 'disable'; + } - /* reset the form with the new values and include the fallback values because of our validation schema requires a string and not undefined which is okay because it will tell the user that something is wrong instead of the user not realizing that it's undefined - */ - let passPhrase = ''; - let privateKey = ''; - - const authConfig = config.tunnel?.authentication?.authConfig; - - switch (authConfig?.case) { - case 'passphrase': - passPhrase = authConfig.value.value; - break; - case 'privateKey': - passPhrase = authConfig.value.passphrase ?? ''; - privateKey = authConfig.value.value; - break; - } + /* reset the form with the new values and include the fallback values because of our validation schema requires a string and not undefined which is okay because it will tell the user that something is wrong instead of the user not realizing that it's undefined + */ + let passPhrase = ''; + let privateKey = ''; + + const authConfig = config.tunnel?.authentication?.authConfig; + switch (authConfig?.case) { + case 'passphrase': + passPhrase = authConfig.value.value; + break; + case 'privateKey': + passPhrase = authConfig.value.passphrase ?? ''; + privateKey = authConfig.value.value; + break; + } - form.reset({ - ...form.getValues(), - connectionName: connData.connection?.name + '-copy', - db: dbConfig, - url: typeof pgConfig === 'string' ? pgConfig : '', - options: { - maxConnectionLimit: - config.connectionOptions?.maxConnectionLimit ?? 80, - }, - tunnel: { - host: config.tunnel?.host ?? '', - port: config.tunnel?.port ?? 22, - knownHostPublicKey: config.tunnel?.knownHostPublicKey ?? '', - user: config.tunnel?.user ?? '', - passphrase: passPhrase, - privateKey: privateKey, - }, - }); - } - } catch (error) { - console.error('Failed to fetch connection data:', error); - setIsLoading(false); - toast({ - title: 'Unable to clone connection!', - variant: 'destructive', - }); - } finally { - setIsLoading(false); + form.reset({ + ...form.getValues(), + connectionName: connData.connection?.name + '-copy', + db: dbConfig, + url: typeof pgConfig === 'string' ? pgConfig : '', + options: { + maxConnectionLimit: + config.connectionOptions?.maxConnectionLimit ?? 80, + }, + tunnel: { + host: config.tunnel?.host ?? '', + port: config.tunnel?.port ?? 22, + knownHostPublicKey: config.tunnel?.knownHostPublicKey ?? '', + user: config.tunnel?.user ?? '', + passphrase: passPhrase, + privateKey: privateKey, + }, + }); + if (config.connectionConfig.case === 'url') { + setActiveTab('url'); + } else if (config.connectionConfig.case === 'connection') { + setActiveTab('host'); } + } catch (error) { + console.error('Failed to fetch connection data:', error); + toast({ + title: 'Unable to retrieve connection data for clone!', + description: getErrorMessage(error), + variant: 'destructive', + }); + } finally { + setIsLoading(false); } }; @@ -350,7 +344,7 @@ the hook in the useEffect conditionally. This is used to retrieve the values for setActiveTab(e)} + onValueChange={(value) => setActiveTab(value as ActiveTab)} value={activeTab} >