console (bugfix): Native Query detail page does not show associated logical model

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9492
GitOrigin-RevId: 5cf8b6b61dad29d7deaa218cac66b487ac2c8914
This commit is contained in:
Matthew Goodwin 2023-06-13 16:29:05 -05:00 committed by hasura-bot
parent 35d9c059db
commit 86b602edb5
3 changed files with 83 additions and 5 deletions

View File

@ -1,11 +1,13 @@
import { expect } from '@storybook/jest'; import { expect } from '@storybook/jest';
import { Meta, StoryObj } from '@storybook/react'; import { Meta, StoryObj } from '@storybook/react';
import { screen, userEvent, within } from '@storybook/testing-library'; import { screen, userEvent, waitFor, within } from '@storybook/testing-library';
import { ReactQueryDecorator } from '../../../../storybook/decorators/react-query'; import { ReactQueryDecorator } from '../../../../storybook/decorators/react-query';
import { dismissToast } from '../../../../utils/StoryUtils'; import { dismissToast } from '../../../../utils/StoryUtils';
import { NativeQuery } from '../../../hasura-metadata-types';
import { RouteWrapper } from '../components/RouteWrapper';
import { AddNativeQuery } from './AddNativeQuery'; import { AddNativeQuery } from './AddNativeQuery';
import { nativeQueryHandlers } from './mocks'; import { nativeQueryHandlers } from './mocks';
import { RouteWrapper } from '../components/RouteWrapper'; import { normalizeArguments } from './utils';
type Story = StoryObj<typeof AddNativeQuery>; type Story = StoryObj<typeof AddNativeQuery>;
@ -206,3 +208,69 @@ export const ErrorDisabled: Story = {
await dismissToast(); await dismissToast();
}, },
}; };
const existingNativeQuery: Required<NativeQuery> = {
arguments: {
query: {
nullable: false,
type: 'varchar',
description: 'a nice description',
},
},
type: 'query',
comment: 'a very nice comment',
code: "select\n AlbumId,\n a.ArtistId,\n Title [AlbumTitle],\n a.Name [Artist],\n (\n select\n count(*)\n from\n Track t\n where\n t.AlbumId = b.AlbumId\n ) [TrackCount]\n from\n album b\n join artist a on a.ArtistId = b.ArtistId\n \n \n -- search option for later: \n WHERE\n b.Title like '%' + {{query}} + '%'",
returns: 'hello_world',
root_field_name: 'AlbumDetail',
};
export const Update: Story = {
...Basic,
name: '💾 Update/view existing',
parameters: {
msw: nativeQueryHandlers({
metadataOptions: { postgres: { models: true, queries: true } },
}),
},
args: {
mode: 'update',
defaultFormValues: {
...existingNativeQuery,
source: 'postgres',
arguments: normalizeArguments(existingNativeQuery.arguments ?? {}),
},
},
play: async ({ canvasElement }) => {
const c = within(canvasElement);
const q = existingNativeQuery;
// this just validates that the above object's properties are rendered in the UI correctly:
await expect(await c.findByTestId('root_field_name')).toHaveValue(
q.root_field_name
);
await expect(await c.findByTestId('comment')).toHaveValue(q.comment);
// make sure this element is findable before we try to wait for the value via getBy
await c.findByTestId('returns');
// we need this bc the value takes a second to get set
await waitFor(() =>
expect(c.getByTestId('returns')).toHaveValue(q.returns)
);
await expect(await c.findByTestId('arguments.0.name')).toHaveValue(
Object.keys(q.arguments)[0]
);
await expect(await c.findByTestId('arguments.0.type')).toHaveValue(
q.arguments.query.type
);
await expect(await c.findByTestId('arguments.0.description')).toHaveValue(
q.arguments.query.description
);
await expect(await c.findByTestId('nullable-switch')).toHaveAttribute(
'data-state',
'unchecked'
);
},
};

View File

@ -54,9 +54,15 @@ export const AddNativeQuery = ({
const selectedSource = watch('source'); const selectedSource = watch('source');
React.useEffect(() => { React.useEffect(() => {
// if source changes, reset value for logical model since any previously selected value would be invalid because it's not a diff database const subscription = watch((value, { name, type }) => {
setValue('returns', ''); if (name === 'source' && type === 'change') {
}, [selectedSource]); // onChange fired for the source field
// reset the "returns" value if the source changes
setValue('returns', '');
}
});
return () => subscription.unsubscribe();
}, [watch]);
const logicalModels = sources?.find( const logicalModels = sources?.find(
s => s.name === selectedSource s => s.name === selectedSource

View File

@ -73,6 +73,10 @@ export const Select: React.VFC<SelectProps> = ({
data-test={dataTest} data-test={dataTest}
data-testid={wrapperProps.dataTestId || name} data-testid={wrapperProps.dataTestId || name}
{...register(name)} {...register(name)}
// onChange={e => {
// register(name).onChange(e);
// }}
> >
{placeholder ? ( {placeholder ? (
<option value="" data-default-selected hidden> <option value="" data-default-selected hidden>