From 1d91f633c3d082ccad38d2b7e8f6b0d207574165 Mon Sep 17 00:00:00 2001 From: Matthew Goodwin <49927862+m4ttheweric@users.noreply.github.com> Date: Wed, 17 May 2023 12:12:16 -0500 Subject: [PATCH] console: fix data types issues in native queries forms PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9198 GitOrigin-RevId: 07932129503b4941c21e99bf11d5eac32ea6fa11 --- .../AddNativeQuery/AddNativeQuery.stories.tsx | 24 ++++----- .../AddNativeQuery/AddNativeQuery.tsx | 49 +++++++++++++++++-- .../components/ArgumentsField.tsx | 31 +++--------- .../LogicalModelWidget/LogicalModelWidget.tsx | 6 ++- .../LogicalModelWidget/parts/FieldsInput.tsx | 11 ++--- .../LogicalModelWidget/parts/TypeInput.tsx | 43 ---------------- .../components/ArgumentsInput.tsx | 2 +- .../parts => components}/BooleanInput.tsx | 5 +- 8 files changed, 76 insertions(+), 95 deletions(-) delete mode 100644 frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/TypeInput.tsx rename frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/{LogicalModelWidget/parts => components}/BooleanInput.tsx (82%) diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx index d54b3808641..43ee41b6138 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.stories.tsx @@ -34,8 +34,8 @@ const fillAndSubmitForm = async ({ * */ - userEvent.click(c.getByText('Add Parameter')); - userEvent.click(c.getByText('Save')); + await userEvent.click(c.getByText('Add Parameter')); + await userEvent.click(c.getByText('Save')); const errorMessages = [ 'Native Query Name is required', @@ -49,35 +49,35 @@ const fillAndSubmitForm = async ({ } // remove param added for error testing - userEvent.click(c.getByText('Remove')); + await userEvent.click(c.getByText('Remove')); - userEvent.type( + await userEvent.type( c.getByPlaceholderText('Name that exposes this model in GraphQL API'), 'my_native_query' ); - userEvent.type( + await userEvent.type( c.getByPlaceholderText('A description of this logical model'), 'a description' ); //select postgres from the database dropdown - userEvent.selectOptions( + await userEvent.selectOptions( await c.findByLabelText('Database', undefined, { timeout: 3000 }), await c.findByRole('option', { name: 'postgres' }) ); - userEvent.click(c.getByText('Add Parameter')); + await userEvent.click(await c.findByText('Add Parameter')); - userEvent.type(c.getByPlaceholderText('Parameter Name'), 'param1'); - userEvent.type(c.getByPlaceholderText('Default Value'), 'default'); - userEvent.click(c.getByTestId('required-switch')); + await userEvent.type(c.getByPlaceholderText('Parameter Name'), 'param1'); + await userEvent.type(c.getByPlaceholderText('Default Value'), 'default'); + await userEvent.click(c.getByTestId('required-switch')); - userEvent.selectOptions( + await userEvent.selectOptions( await c.findByLabelText('Query Return Type', undefined, { timeout: 3000 }), await c.findByRole('option', { name: 'hello_world' }) ); - userEvent.click(c.getByText('Save')); + await userEvent.click(c.getByText('Save')); }; export const HappyPath: ComponentStory = args => { diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx index 608e5885d1f..3b53f599ed8 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/AddNativeQuery.tsx @@ -8,17 +8,21 @@ import { useConsoleForm, } from '../../../../new-components/Form'; // import { FormDebugWindow } from '../../../../new-components/Form/dev-components/FormDebugWindow'; +import Skeleton from 'react-loading-skeleton'; +import { Driver, drivers } from '../../../../dataSources'; +import { IndicatorCard } from '../../../../new-components/IndicatorCard'; import { hasuraToast } from '../../../../new-components/Toasts'; +import { Feature } from '../../../DataSource'; import { useMetadata } from '../../../hasura-metadata-api'; +import { useSupportedDataTypes } from '../../hooks/useSupportedDataTypes'; import { useTrackNativeQuery } from '../../hooks/useTrackNativeQuery'; +import { LogicalModelWidget } from '../LogicalModelWidget/LogicalModelWidget'; import { ArgumentsField } from './components/ArgumentsField'; import { PageWrapper } from './components/PageWrapper'; import { SqlEditorField } from './components/SqlEditorField'; import { schema } from './schema'; import { NativeQueryForm } from './types'; import { transformFormOutputToMetadata } from './utils'; -import { LogicalModelWidget } from '../LogicalModelWidget/LogicalModelWidget'; -import { Driver, drivers } from '../../../../dataSources'; type AddNativeQueryProps = { defaultFormValues?: Partial; @@ -38,7 +42,11 @@ export const AddNativeQuery = ({ options: { defaultValues: defaultFormValues }, }); - const { data: sources, isLoading: isSourcesLoading } = useMetadata(s => { + const { + data: sources, + isLoading: isSourcesLoading, + error: sourcesError, + } = useMetadata(s => { return s.metadata.sources.filter(s => drivers.includes(s.kind as Driver)); }); @@ -94,6 +102,32 @@ export const AddNativeQuery = ({ } }; + /** + * Options for the data source types + */ + const { + data: typeOptions = [], + error: typeOptionError, + isLoading: isIntrospectionLoading, + } = useSupportedDataTypes({ + dataSourceName: selectedSource, + select: values => { + if (values === Feature.NotImplemented) return []; + return Object.values(values).flat(); + }, + options: { + enabled: !!selectedSource, + }, + }); + + if (sourcesError || typeOptionError) + return ( + +
{sourcesError}
+
{typeOptionError?.message}
+
+ ); + return (
@@ -123,7 +157,14 @@ export const AddNativeQuery = ({ placeholder="Select a database..." /> - + {isIntrospectionLoading ? ( +
+ + +
+ ) : ( + + )}
{/* Logical Model Dropdown */} diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/components/ArgumentsField.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/components/ArgumentsField.tsx index f7d9b62e9c6..fda2e93619e 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/components/ArgumentsField.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/AddNativeQuery/components/ArgumentsField.tsx @@ -5,23 +5,22 @@ import { } from '@tanstack/react-table'; import clsx from 'clsx'; import React, { useRef } from 'react'; -import { Controller, useFieldArray, useFormContext } from 'react-hook-form'; +import { useFieldArray, useFormContext } from 'react-hook-form'; import { FaPlusCircle } from 'react-icons/fa'; import { Button } from '../../../../../new-components/Button'; import { - FieldWrapper, GraphQLSanitizedInputField, InputField, Select, fieldLabelStyles, } from '../../../../../new-components/Form'; -import { Switch } from '../../../../../new-components/Switch'; +import { BooleanInput } from '../../components/BooleanInput'; import { useCardedTableFromReactTableWithRef } from '../../components/CardedTableFromReactTable'; import { NativeQueryArgumentNormalized, NativeQueryForm } from '../types'; const columnHelper = createColumnHelper(); -export const ArgumentsField = () => { +export const ArgumentsField = ({ types }: { types: string[] }) => { const { control } = useFormContext(); const { append, remove, fields } = useFieldArray({ @@ -53,10 +52,7 @@ export const ArgumentsField = () => { // saving prop for future upgrade //menuPortalTarget={tableRef.current} name={`arguments.${row.index}.type`} - options={[ - { value: 'string', label: 'string' }, - { value: 'int', label: 'int' }, - ]} + options={types.map(t => ({ label: t, value: t }))} /> ), header: 'Type', @@ -75,22 +71,7 @@ export const ArgumentsField = () => { columnHelper.accessor('required', { id: 'required', cell: ({ row }) => ( - ( - - - - )} - /> + ), header: 'Required', }), @@ -106,7 +87,7 @@ export const ArgumentsField = () => { ), }), ], - [control, remove] + [remove, types] ); const argumentsTable = useReactTable({ diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/LogicalModelWidget.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/LogicalModelWidget.tsx index 0e98c3bf5c4..a52594f3076 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/LogicalModelWidget.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/LogicalModelWidget.tsx @@ -47,6 +47,8 @@ export const LogicalModelWidget = (props: AddLogicalModelDialogProps) => { }, }); + const selectedDataSource = watch('dataSourceName'); + /** * Options for the data sources */ @@ -71,13 +73,13 @@ export const LogicalModelWidget = (props: AddLogicalModelDialogProps) => { error: typeOptionError, isLoading: isIntrospectionLoading, } = useSupportedDataTypes({ - dataSourceName: watch('dataSourceName'), + dataSourceName: selectedDataSource, select: values => { if (values === Feature.NotImplemented) return []; return Object.values(values).flat(); }, options: { - enabled: !!watch('dataSourceName'), + enabled: !!selectedDataSource, }, }); diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/FieldsInput.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/FieldsInput.tsx index c47cbc15f0a..2829e4b4809 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/FieldsInput.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/FieldsInput.tsx @@ -1,11 +1,10 @@ -import { useFieldArray, useFormContext } from 'react-hook-form'; import clsx from 'clsx'; -import { BooleanInput } from './BooleanInput'; -import { TypeInput } from './TypeInput'; +import { useFieldArray, useFormContext } from 'react-hook-form'; import { FiTrash2 } from 'react-icons/fi'; -import { CardedTable } from '../../../../../new-components/CardedTable'; -import { InputField } from '../../../../../new-components/Form'; import { Button } from '../../../../../new-components/Button'; +import { CardedTable } from '../../../../../new-components/CardedTable'; +import { InputField, Select } from '../../../../../new-components/Form'; +import { BooleanInput } from '../../components/BooleanInput'; export const FieldsInput = ({ name, @@ -52,7 +51,7 @@ export const FieldsInput = ({ /> - ({ label: t, value: t }))} diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/TypeInput.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/TypeInput.tsx deleted file mode 100644 index 3fa1cf25c96..00000000000 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/TypeInput.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Controller } from 'react-hook-form'; -import { - FieldWrapper, - FieldWrapperPassThroughProps, - MultiSelectItem, -} from '../../../../../new-components/Form'; - -type TypeInputProps = FieldWrapperPassThroughProps & { - name: string; - options: MultiSelectItem[]; - disabled?: boolean; -}; - -export const TypeInput = ({ - name, - options, - disabled, - ...wrapperProps -}: TypeInputProps) => { - return ( - ( - - - - )} - /> - ); -}; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/StoredProcedures/components/ArgumentsInput.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/StoredProcedures/components/ArgumentsInput.tsx index 36cdd09126e..5fbac88b93c 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/StoredProcedures/components/ArgumentsInput.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/StoredProcedures/components/ArgumentsInput.tsx @@ -2,7 +2,7 @@ import clsx from 'clsx'; import { CardedTable } from '../../../../../new-components/CardedTable'; import { InputField, Select } from '../../../../../new-components/Form'; import { useFieldArray, useFormContext } from 'react-hook-form'; -import { BooleanInput } from '../../LogicalModelWidget/parts/BooleanInput'; +import { BooleanInput } from '../../components/BooleanInput'; import { Button } from '../../../../../new-components/Button'; import { FiTrash2 } from 'react-icons/fi'; diff --git a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/BooleanInput.tsx b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/components/BooleanInput.tsx similarity index 82% rename from frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/BooleanInput.tsx rename to frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/components/BooleanInput.tsx index 93dc12899d9..1ef4d9a6d56 100644 --- a/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/LogicalModelWidget/parts/BooleanInput.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/features/Data/LogicalModels/components/BooleanInput.tsx @@ -1,8 +1,8 @@ import { FieldWrapper, FieldWrapperPassThroughProps, -} from '../../../../../new-components/Form'; -import { Switch } from '../../../../../new-components/Switch'; +} from '../../../../new-components/Form'; +import { Switch } from '../../../../new-components/Switch'; import { Controller } from 'react-hook-form'; type BooleanInputProps = FieldWrapperPassThroughProps & { @@ -21,6 +21,7 @@ export const BooleanInput = ({ render={({ field: { onChange, value }, fieldState }) => (