console: create a hook to fetch table definition from URL

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5007
GitOrigin-RevId: f3232d966bd97e7cc6e249c40a753fa5072265b5
This commit is contained in:
Sooraj 2022-07-26 17:36:10 +05:30 committed by hasura-bot
parent 83882bf558
commit e243fccc62
4 changed files with 115 additions and 0 deletions

View File

@ -0,0 +1,51 @@
import { renderHook } from '@testing-library/react-hooks';
import { useTableDefinition } from '../useTableDefinition';
// TYPES
type QueryStringParseResult =
| {
querystringParseResult: 'success';
data: TableDefinition;
}
| {
querystringParseResult: 'error';
errorType: 'invalidTableDefinition' | 'invalidDatabaseDefinition';
};
// TODO better types once GDC kicks in
type TableDefinition = { database: string; table?: Record<string, any> };
global.window = Object.create(window);
describe('useTableDefinition', () => {
it('should give error when there is no table definition in the URL', async () => {
const { result } = renderHook(() => useTableDefinition());
expect(result.current?.querystringParseResult).toBe('error');
});
it('should parse correct table definition from window object', async () => {
// mock window.location
const url = new URL(
'http://localhost:3000/console/data/v2?database=gdc_demo_database&table=%7B%22schema%22:%22baz%22,%22anotherSchema%22:%22bar%22,%22name%22:%22Employee%22%7D'
);
Object.defineProperty(window, 'location', {
value: {
href: url.href,
search: url.search,
},
});
const { result } = renderHook(() => useTableDefinition());
const data: QueryStringParseResult | undefined = result.current;
expect(data).toStrictEqual({
querystringParseResult: 'success',
data: {
database: 'gdc_demo_database',
table: {
anotherSchema: 'bar',
name: 'Employee',
schema: 'baz',
},
},
});
});
});

View File

@ -0,0 +1 @@
export { useTableDefinition } from './useTableDefinition';

View File

@ -0,0 +1,62 @@
import { useMemo } from 'react';
// TYPES
type QueryStringParseResult =
| {
querystringParseResult: 'success';
data: TableDefinition;
}
| {
querystringParseResult: 'error';
errorType: 'invalidTableDefinition' | 'invalidDatabaseDefinition';
};
// TODO better types once GDC kicks in
type TableDefinition = { database: string; table?: Record<string, any> };
// CONSTANTS
const TABLE_DEFINITION_SEARCH_KEY = 'table';
const DATASOURCE_DEFINITION_SEARCH_KEY = 'database';
const invalidTableDefinitionResult: QueryStringParseResult = {
querystringParseResult: 'error',
errorType: 'invalidTableDefinition',
};
const invalidDatabaseDefinitionResult: QueryStringParseResult = {
querystringParseResult: 'error',
errorType: 'invalidDatabaseDefinition',
};
// FUNCTION
const getTableDefinition = (location: Location): QueryStringParseResult => {
if (!location.search) return invalidTableDefinitionResult;
// if tableDefinition is present in query params;
// Idea is to use query params for GDC tables
const params = new URLSearchParams(location.search);
const table = params.get(TABLE_DEFINITION_SEARCH_KEY);
const database = params.get(DATASOURCE_DEFINITION_SEARCH_KEY);
if (!database) {
return invalidDatabaseDefinitionResult;
}
if (!table) {
return { querystringParseResult: 'success', data: { database } };
}
try {
return {
querystringParseResult: 'success',
data: { database, table: JSON.parse(table) },
};
} catch (error) {
console.error('Unable to parse the table definition', error);
}
return invalidTableDefinitionResult;
};
export const useTableDefinition = (location = window.location) => {
return useMemo(() => getTableDefinition(location), [location]);
};

View File

@ -1 +1,2 @@
export * from './components';
export * from './hooks';