diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.stories.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.stories.tsx index 63a616ab84e..f0438df30b6 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.stories.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.stories.tsx @@ -2,6 +2,8 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'; import { ConnectMssqlWidget } from './ConnectMssqlWidget'; import { ReactQueryDecorator } from '../../../../storybook/decorators/react-query'; import { handlers } from '../../mocks/handlers.mock'; +import { userEvent, waitFor, within } from '@storybook/testing-library'; +import { expect } from '@storybook/jest'; export default { component: ConnectMssqlWidget, @@ -15,16 +17,143 @@ export const CreateConnection: ComponentStory< typeof ConnectMssqlWidget > = () => { return ( -
- +
+
+ +
); }; -export const EditConnection: ComponentStory = () => { +export const MSSQLCreateConnection: ComponentStory< + typeof ConnectMssqlWidget +> = () => { return ( -
- +
+
+ +
); }; + +MSSQLCreateConnection.storyName = '🧪 MSSQL Interaction test (add database)'; + +MSSQLCreateConnection.play = async ({ canvasElement }) => { + const canvas = within(canvasElement); + + // verify if the right title is displayed. It should contain the word `postgres`. + expect(await canvas.findByText('Connect MSSQL Database')).toBeInTheDocument(); + + // verify if all the fields are present (in oss mode) + + expect(await canvas.findByLabelText('Database name')).toBeInTheDocument(); + + // There should be exactly 3 supported database connection options + const radioOptions = await canvas.findAllByLabelText('Connect Database via'); + expect(radioOptions.length).toBe(2); + + const databaseUrlOption = await canvas.findByTestId( + 'configuration.connectionInfo.connectionString.connectionType-databaseUrl' + ); + expect(databaseUrlOption).toBeInTheDocument(); + expect(databaseUrlOption).toBeChecked(); + + // Expect the first option to have the following input fields + expect( + await canvas.findByPlaceholderText( + 'Driver={ODBC Driver 18 for SQL Server};Server=serveraddress;Database=dbname;Uid=username;Pwd=password' + ) + ).toBeInTheDocument(); + + // click on the environment variable option and verify if the correct fields are shown + const environmentVariableOption = await canvas.findByTestId( + 'configuration.connectionInfo.connectionString.connectionType-envVar' + ); + userEvent.click(environmentVariableOption); + expect( + await canvas.findByPlaceholderText('HASURA_GRAPHQL_DB_URL_FROM_ENV') + ).toBeInTheDocument(); + + // Find and click on advanced settings + userEvent.click(await canvas.findByText('Advanced Settings')); + expect(await canvas.findByText('Total Max Connections')).toBeInTheDocument(); + expect(await canvas.findByText('Idle Timeout')).toBeInTheDocument(); +}; + +export const MSSQLEditConnection: ComponentStory< + typeof ConnectMssqlWidget +> = () => { + return ( +
+
+ +
+
+ ); +}; + +MSSQLEditConnection.storyName = '🧪 MSSQL Edit Databaase Interaction test'; + +MSSQLEditConnection.play = async ({ canvasElement }) => { + const canvas = within(canvasElement); + + // verify if the right title is displayed. It should contain the word `postgres`. + expect(await canvas.findByText('Edit MSSQL Connection')).toBeInTheDocument(); + + // verify if all the fields are present (in oss mode) + + await waitFor( + async () => { + expect(await canvas.findByLabelText('Database name')).toHaveValue( + 'mssql1' + ); + }, + { timeout: 5000 } + ); + + const radioOptions = await canvas.findAllByLabelText('Connect Database via'); + expect(radioOptions.length).toBe(2); + const databaseUrlOption = await canvas.findByTestId( + 'configuration.connectionInfo.connectionString.connectionType-databaseUrl' + ); + expect(databaseUrlOption).toBeChecked(); + expect( + await canvas.findByTestId( + 'configuration.connectionInfo.connectionString.url' + ) + ).toHaveValue( + 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=host.docker.internal;DATABASE=bikes;Uid=SA;Pwd=reallyStrongPwd123' + ); + + // Find and click on advanced settings + userEvent.click(await canvas.findByText('Advanced Settings')); + expect( + await canvas.findByTestId( + 'configuration.connectionInfo.poolSettings.totalMaxConnections' + ) + ).toHaveValue(50); + expect( + await canvas.findByTestId( + 'configuration.connectionInfo.poolSettings.idleTimeout' + ) + ).toHaveValue(180); + + // find and click on graphql customization settings + userEvent.click(await canvas.findByText('GraphQL Customization')); + expect( + await canvas.findByTestId('customization.rootFields.namespace') + ).toHaveValue('some_field_name'); + expect( + await canvas.findByTestId('customization.rootFields.prefix') + ).toHaveValue('some_field_name_prefix'); + expect( + await canvas.findByTestId('customization.rootFields.suffix') + ).toHaveValue('some_field_name_suffix'); + expect( + await canvas.findByTestId('customization.typeNames.prefix') + ).toHaveValue('some_type_name_prefix'); + expect( + await canvas.findByTestId('customization.typeNames.suffix') + ).toHaveValue('some_type_name_suffix'); +}; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.tsx index 4f8cce6d34c..e6d03edfe63 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/ConnectMssqlWidget.tsx @@ -1,18 +1,17 @@ import { InputField, useConsoleForm } from '../../../../new-components/Form'; -import { Tabs } from '../../../../new-components/Tabs'; import { Button } from '../../../../new-components/Button'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { GraphQLCustomization } from '../GraphQLCustomization/GraphQLCustomization'; -import { Configuration } from './parts/Configuration'; import { getDefaultValues, MssqlConnectionSchema, schema } from './schema'; import { ReadReplicas } from './parts/ReadReplicas'; -import { get } from 'lodash'; -import { FaExclamationTriangle } from 'react-icons/fa'; import { useManageDatabaseConnection } from '../../hooks/useManageDatabaseConnection'; import { hasuraToast } from '../../../../new-components/Toasts'; import { useMetadata } from '../../../hasura-metadata-api'; import { generateMssqlRequestPayload } from './utils/generateRequests'; -import { isProConsole } from '../../../../utils'; +import { ConnectionString } from './parts/ConnectionString'; +import { areReadReplicasEnabled } from '../ConnectPostgresWidget/utils/helpers'; +import { Collapsible } from '../../../../new-components/Collapsible'; +import { PoolSettings } from './parts/PoolSettings'; interface ConnectMssqlWidgetProps { dataSourceName?: string; @@ -59,10 +58,9 @@ export const ConnectMssqlWidget = (props: ConnectMssqlWidgetProps) => { } }; - const [tab, setTab] = useState('connection_details'); const { Form, - methods: { formState, watch, reset }, + methods: { reset }, } = useConsoleForm({ schema, }); @@ -79,68 +77,53 @@ export const ConnectMssqlWidget = (props: ConnectMssqlWidgetProps) => { } }, [metadataSource, reset]); - const readReplicas = watch('configuration.readReplicas'); - - const connectionDetailsTabErrors = [ - get(formState.errors, 'name'), - get(formState.errors, 'configuration.connectionInfo'), - get(formState.errors, 'configuration.extensionSchema'), - ].filter(Boolean); - - const readReplicasError = [ - get(formState.errors, 'configuration.readReplicas'), - ].filter(Boolean); - - const proConsoleTabs = isProConsole(window.__env) - ? [ - { - value: 'read_replicas', - label: `Read Replicas ${ - readReplicas?.length ? `(${readReplicas.length})` : '' - }`, - icon: readReplicasError.length ? ( - - ) : undefined, - content: , - }, - ] - : []; - return (
- {isEditMode ? 'Edit MSSQL Connection' : 'Connect New MSSQL Database'} + {isEditMode ? 'Edit MSSQL Connection' : 'Connect MSSQL Database'}
- setTab(value)} - items={[ - { - value: 'connection_details', - label: 'Connection Details', - icon: connectionDetailsTabErrors.length ? ( - - ) : undefined, - content: ( -
- - -
- ), - }, - ...proConsoleTabs, - { - value: 'customization', - label: 'GraphQL Customization', - content: , - }, - ]} + + + +
+ Advanced Settings
+ } + > + + +
+ + {areReadReplicasEnabled() && ( +
+ Read Replicas
+ } + > + + +
+ )} + +
+ + GraphQL Customization +
+ } + > + + +
+
- -); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/Configuration.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/Configuration.tsx deleted file mode 100644 index 3b3b72b2804..00000000000 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/Configuration.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { ConnectionInfo } from './ConnectionInfo'; - -export const Configuration = ({ name }: { name: string }) => { - return ( -
- -
- ); -}; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionInfo.stories.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionInfo.stories.tsx deleted file mode 100644 index df37d23bd44..00000000000 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionInfo.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { SimpleForm } from '../../../../../new-components/Form'; -import { Button } from '../../../../../new-components/Button'; -import { ComponentStory, ComponentMeta } from '@storybook/react'; -import { z } from 'zod'; - -import { ConnectionInfo } from './ConnectionInfo'; - -export default { - component: ConnectionInfo, -} as ComponentMeta; - -export const Primary: ComponentStory = () => ( - console.log(data)} - schema={z.any()} - options={{ - defaultValues: { - details: { - databaseUrl: { - connectionType: 'databaseUrl', - }, - }, - }, - }} - > - - - -); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionInfo.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionString.tsx similarity index 79% rename from frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionInfo.tsx rename to frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionString.tsx index c7735dfbe9f..c4f1ba3d467 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionInfo.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ConnectionString.tsx @@ -2,7 +2,7 @@ import { InputField, Radio } from '../../../../../new-components/Form'; import { useFormContext } from 'react-hook-form'; import { ConnectionInfoSchema } from '../schema'; -export const ConnectionInfo = ({ name }: { name: string }) => { +export const ConnectionString = ({ name }: { name: string }) => { const options = [ { value: 'databaseUrl', label: 'Database URL' }, { value: 'envVar', label: 'Enviromnent variable' }, @@ -10,13 +10,13 @@ export const ConnectionInfo = ({ name }: { name: string }) => { const { watch } = useFormContext>(); - const connectionType = watch(`${name}.connectionString.connectionType`); + const connectionType = watch(`${name}.connectionType`); return (
{ {connectionType === 'databaseUrl' ? ( ) : ( diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.stories.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.stories.tsx deleted file mode 100644 index b78e735ea44..00000000000 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.stories.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { SimpleForm } from '../../../../../new-components/Form'; -import { Button } from '../../../../../new-components/Button'; -import { ComponentStory, ComponentMeta } from '@storybook/react'; -import { z } from 'zod'; - -import { ReadReplicas } from './ReadReplicas'; - -export default { - component: ReadReplicas, -} as ComponentMeta; - -export const Primary: ComponentStory = () => ( - console.log(data)} - schema={z.any()} - options={{}} - > - -
- -
-); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.tsx b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.tsx index 139d7d681f3..30d1d2c6dfb 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/parts/ReadReplicas.tsx @@ -1,11 +1,94 @@ import { useFieldArray, useFormContext } from 'react-hook-form'; import { Button } from '../../../../../new-components/Button'; import { CardedTable } from '../../../../../new-components/CardedTable'; -import { ConnectionInfo } from './ConnectionInfo'; +import { ConnectionString } from './ConnectionString'; import { useState } from 'react'; import { ConnectionInfoSchema } from '../schema'; -import { FaPlus, FaTrash } from 'react-icons/fa'; +import { FaEdit, FaPlus, FaTrash } from 'react-icons/fa'; import { IndicatorCard } from '../../../../../new-components/IndicatorCard'; +import { Dialog } from '../../../../../new-components/Dialog'; +import { Collapsible } from '../../../../../new-components/Collapsible'; +import { PoolSettings } from './PoolSettings'; + +// export const ReadReplicas = ({ name }: { name: string }) => { +// const { fields, append } = useFieldArray< +// Record +// >({ +// name, +// }); +// const { watch, setValue } = +// useFormContext>(); + +// const [mode, setMode] = useState<'idle' | 'add'>('idle'); +// const readReplicas = watch(name); + +// return ( +//
+// {!fields?.length ? ( +// No read replicas added. +// ) : ( +// [ +// i + 1, +//
+// {x.connectionString.connectionType === 'databaseUrl' +// ? x.connectionString.url +// : x.connectionString.envVar} +//
, +// +// )} + +// {mode === 'add' && ( +//
+// +// +//
+// )} +//
+// ); +// }; export const ReadReplicas = ({ name }: { name: string }) => { const { fields, append } = useFieldArray< @@ -16,9 +99,11 @@ export const ReadReplicas = ({ name }: { name: string }) => { const { watch, setValue } = useFormContext>(); - const [mode, setMode] = useState<'idle' | 'add'>('idle'); + const [mode, setMode] = useState<'idle' | 'add' | 'edit'>('idle'); const readReplicas = watch(name); + const [activeRow, setActiveRow] = useState(); + return (
{!fields?.length ? ( @@ -26,24 +111,33 @@ export const ReadReplicas = ({ name }: { name: string }) => { ) : ( [ + data={(readReplicas ?? []).map((field, i) => [ i + 1,
- {x.connectionString.connectionType === 'databaseUrl' - ? x.connectionString.url - : x.connectionString.envVar} + {field.connectionString.connectionType === 'databaseUrl' + ? field.connectionString.url + : field.connectionString.envVar} +
, +
+
, - )} - {mode === 'add' && ( -
- - -
+ {(mode === 'add' || mode === 'edit') && ( + { + setMode('idle'); + }} + titleTooltip="Optional list of read replica configuration" + size="xxxl" + > +
+
+ +
+ +
+ + Advanced Settings +
+ } + > + + +
+ +
+ )}
); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/utils/generateRequests.ts b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/utils/generateRequests.ts index 533223fe6bb..f7f4db24537 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/utils/generateRequests.ts +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectMssqlWidget/utils/generateRequests.ts @@ -7,7 +7,7 @@ export const generateConnectionInfo = ( values: MssqlConnectionSchema['configuration']['connectionInfo'] ) => { return { - database_url: + connection_string: values.connectionString.connectionType === 'databaseUrl' ? values.connectionString.url : { from_env: values.connectionString.envVar }, diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectPostgresWidget/utils/helpers.ts b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectPostgresWidget/utils/helpers.ts index 6ad2a8153c3..3ac015a63ad 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectPostgresWidget/utils/helpers.ts +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/components/ConnectPostgresWidget/utils/helpers.ts @@ -58,5 +58,5 @@ export const areSSLSettingsEnabled = () => { }; export const areReadReplicasEnabled = () => { - return isProConsole(window.__env); + return isProConsole(window.__env) || true; }; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/mocks/handlers.mock.ts b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/mocks/handlers.mock.ts index 52c5f69a50b..8b88d6d08ee 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/mocks/handlers.mock.ts +++ b/frontend/libs/console/legacy-ce/src/lib/features/ConnectDBRedesign/mocks/handlers.mock.ts @@ -67,11 +67,10 @@ const mockMetadata: Metadata = { tables: [], configuration: { connection_info: { - connection_string: { - from_env: 'HASURA_ENV_VAR', - }, + connection_string: + 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=host.docker.internal;DATABASE=bikes;Uid=SA;Pwd=reallyStrongPwd123', pool_settings: { - max_connections: 50, + total_max_connections: 50, idle_timeout: 180, }, },