refactor (console): sub routes for managing gdc tables

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6546
GitOrigin-RevId: 3876c171558dbd2b72881b79b181c52e3a331b11
This commit is contained in:
Vijay Prasanna 2022-10-26 20:28:04 +05:30 committed by hasura-bot
parent a2e6e50e27
commit 374846b63b
11 changed files with 109 additions and 74 deletions

View File

@ -30,11 +30,12 @@ import ConnectDatabase from './DataSources/ConnectDatabase';
import { setDriver } from '../../../dataSources';
import { UPDATE_CURRENT_DATA_SOURCE } from './DataActions';
import { getSourcesFromMetadata } from '../../../metadata/selector';
import { ManageContainer } from '@/features/Data';
import { ManageDatabaseContainer } from '@/features/Data';
import { Connect } from '@/features/ConnectDB';
import { TableInsertItemContainer } from './TableInsertItem/TableInsertItemContainer';
import { ModifyTableContainer } from './TableModify/ModifyTableContainer';
import { TableEditItemContainer } from './TableEditItem/TableEditItemContainer';
import { ManageTable } from '@/features/Data/ManageTable';
const makeDataRouter = (
connect,
@ -54,7 +55,13 @@ const makeDataRouter = (
<IndexRedirect to="manage" />
<Route path="v2">
<Route path="manage" component={ManageContainer} />
<Route path="manage">
<Route path="table" component={ManageTable}>
<IndexRedirect to="modify" />
<Route path=":operation" component={ManageTable} />
</Route>
<Route path="database" component={ManageDatabaseContainer} />
</Route>
<Route path="edit" component={Connect.EditConnection} />
</Route>

View File

@ -31,15 +31,15 @@ export interface ConnectDatabaseFormProps {
export const connectionRadios = [
{
value: connectionTypes.ENV_VAR,
value: connectionTypes?.ENV_VAR,
title: 'Environment Variable',
},
{
value: connectionTypes.DATABASE_URL,
value: connectionTypes?.DATABASE_URL,
title: 'Database URL',
},
{
value: connectionTypes.CONNECTION_PARAMS,
value: connectionTypes?.CONNECTION_PARAMS,
title: 'Connection Parameters',
},
];

View File

@ -1,3 +1,4 @@
import { getRoute } from '@/features/Data';
import { exportMetadata } from '@/features/DataSource';
import { useHttpClient } from '@/features/Network';
import { Dispatch } from '@/types';
@ -29,17 +30,9 @@ export const useGDCTreeItemClick = (dispatch: Dispatch) => {
*/
const isTableClicked = Object.keys(rest?.table || {}).length !== 0;
if (isTableClicked) {
dispatch(
_push(
encodeURI(
`/data/v2/manage?database=${database}&table=${JSON.stringify(
rest.table
)}`
)
)
);
dispatch(_push(getRoute().table(database, rest.table)));
} else {
dispatch(_push(encodeURI(`/data/v2/manage?database=${database}`)));
dispatch(_push(getRoute().database(database)));
}
},
[dispatch, httpClient, isUnmounted]

View File

@ -1,7 +1,6 @@
import React from 'react';
import { useTableDefinition } from './hooks';
import { ManageDatabase } from './ManageDatabase/ManageDatabase';
import { ManageTable } from './ManageTable/ManageTable';
export const ManageContainer = () => {
const urlData = useTableDefinition(window.location);
@ -9,12 +8,10 @@ export const ManageContainer = () => {
if (urlData.querystringParseResult === 'error')
return <>Something went wrong while parsing the URL parameters</>;
const { database, table } = urlData.data;
const { database } = urlData.data;
/**
* If the url is only managing a database and not the table, then show the DB-management screen
*/
if (database && !table) return <ManageDatabase dataSourceName={database} />;
return <ManageTable table={table} dataSourceName={database} />;
return <ManageDatabase dataSourceName={database} />;
};

View File

@ -1,26 +0,0 @@
// Button.stories.ts|tsx
import React from 'react';
import { ReactQueryDecorator } from '@/storybook/decorators/react-query';
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { ManageTable } from './ManageTable';
const props = {
table: ['Customer'],
dataSourceName: 'sqlite-test',
tableName: 'Customer',
};
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Data / ManageTable',
component: ManageTable,
decorators: [ReactQueryDecorator()],
} as ComponentMeta<typeof ManageTable>;
export const Primary: ComponentStory<typeof ManageTable> = () => (
<ManageTable {...props} />
);

View File

@ -4,14 +4,19 @@ import { getTableName } from '@/features/DataSource';
import { Table } from '@/features/MetadataAPI';
import { IndicatorCard } from '@/new-components/IndicatorCard';
import { Tabs } from '@/new-components/Tabs';
import React, { useState } from 'react';
import { useDatabaseHierarchy } from '../hooks';
import { getRoute } from '@/features/Data';
import React from 'react';
import { useDispatch } from 'react-redux';
import { useDatabaseHierarchy, useTableDefinition } from '../hooks';
import { ModifyTable } from '../ModifyTable/ModifyTable';
import { Breadcrumbs, TableName } from './parts';
import _push from '../../../components/Services/Data/push';
type AllowedTabs = 'modify' | 'browse' | 'relationship' | 'permissions';
export interface ManageTableProps {
dataSourceName: string;
table: Table;
params: {
operation: AllowedTabs;
};
}
const FeatureNotImplemented = () => {
@ -24,39 +29,64 @@ const FeatureNotImplemented = () => {
);
};
const STARTING_TAB = 'Browse';
const availableTabs = (props: ManageTableProps, tableName: string) => [
const availableTabs = (
dataSourceName: string,
table: Table,
tableName: string
) => [
{
value: 'Browse',
value: 'browse',
label: 'Browse',
content: <BrowseRowsContainer {...props} />,
content: (
<BrowseRowsContainer dataSourceName={dataSourceName} table={table} />
),
},
{
value: 'Modify',
value: 'modify',
label: 'Modify',
content: <ModifyTable {...props} tableName={tableName} />,
content: (
<ModifyTable
dataSourceName={dataSourceName}
table={table}
tableName={tableName}
/>
),
},
{
value: 'Relationships',
value: 'relationships',
label: 'Relationships',
content: <DatabaseRelationshipsContainer {...props} />,
content: (
<DatabaseRelationshipsContainer
dataSourceName={dataSourceName}
table={table}
/>
),
},
{
value: 'Permissions',
value: 'permissions',
label: 'Permissions',
content: <FeatureNotImplemented />,
},
];
export const ManageTable: React.VFC<ManageTableProps> = props => {
const { table, dataSourceName } = props;
export const ManageTable: React.VFC<ManageTableProps> = (
props: ManageTableProps
) => {
const {
params: { operation },
} = props;
const urlData = useTableDefinition(window.location);
const dispatch = useDispatch();
if (urlData.querystringParseResult === 'error')
throw Error('Unable to render');
const { database: dataSourceName, table } = urlData.data;
const { data: databaseHierarchy, isLoading } =
useDatabaseHierarchy(dataSourceName);
const [tab, setTab] = useState(STARTING_TAB);
const tableName = databaseHierarchy
? getTableName(table, databaseHierarchy)
: '';
@ -76,9 +106,13 @@ export const ManageTable: React.VFC<ManageTableProps> = props => {
<Breadcrumbs dataSourceName={dataSourceName} tableName={tableName} />
<TableName dataSourceName={dataSourceName} tableName={tableName} />
<Tabs
value={tab}
onValueChange={setTab}
items={availableTabs(props, tableName)}
value={operation}
onValueChange={_operation => {
dispatch(
_push(getRoute().table(dataSourceName, table, _operation))
);
}}
items={availableTabs(dataSourceName, table, tableName)}
/>
</div>
</div>

View File

@ -1,9 +1,13 @@
import { Table } from '@/features/MetadataAPI';
import React from 'react';
import { ManageTableProps } from '../ManageTable/ManageTable';
import { TableColumns, TableComments, TableRootFields } from './components';
import { Section } from './parts';
export type ModifyTableProps = ManageTableProps & { tableName: string };
export type ModifyTableProps = {
dataSourceName: string;
table: Table;
tableName: string;
};
export const ModifyTable: React.VFC<ModifyTableProps> = props => {
return (

View File

@ -1,13 +1,13 @@
import { IndicatorCard } from '@/new-components/IndicatorCard';
import React, { useState } from 'react';
import Skeleton from 'react-loading-skeleton';
import { ManageTableProps } from '../../ManageTable';
import { useListAllTableColumns } from '../hooks/useListAllTableColumns';
import { ModifyTableColumn } from '../types';
import { EditTableColumnDialog } from './EditTableColumnDialog/EditTableColumnDialog';
import { TableColumnDescription } from './TableColumnDescription';
import { ModifyTableProps } from '../ModifyTable';
export const TableColumns: React.VFC<ManageTableProps> = props => {
export const TableColumns: React.VFC<ModifyTableProps> = props => {
const { data: columns, isLoading, isError } = useListAllTableColumns(props);
const [isEditColumnFormActive, setIsEditColumnFormActive] = useState(false);

View File

@ -4,12 +4,17 @@ import { Nullable } from '@/types';
import clsx from 'clsx';
import React, { useMemo } from 'react';
import TextareaAutosize from 'react-autosize-textarea';
import { Table } from '@/features/MetadataAPI';
import { FaEdit } from 'react-icons/fa';
import { ManageTableProps } from '../../ManageTable';
import { useMetadataForManageTable, getTableFromMetadata } from '../hooks';
import { useUpdateTableConfiguration } from '../hooks/useUpdateTableConfiguration';
export const TableComments: React.VFC<ManageTableProps> = props => {
export interface TableCommentsProps {
dataSourceName: string;
table: Table;
}
export const TableComments: React.VFC<TableCommentsProps> = props => {
const { dataSourceName, table } = props;
const { data, isLoading } = useMetadataForManageTable(dataSourceName);

View File

@ -1,6 +1,7 @@
export * from './ManageContainer';
export * from './ManageDatabaseContainer';
export * from './components';
export * from './hooks';
export { tablesQueryKey } from './TrackTables/hooks/useTables';
export { useTrackTable } from './TrackTables/hooks/useTrackTable';
export { useMetadataSource } from './TrackTables/hooks/useMetadataSource';
export * from './utils/getRoute';

View File

@ -0,0 +1,20 @@
import { Table } from '@/features/MetadataAPI';
export const getRoute = () => ({
database: (dataSourceName: string) =>
encodeURI(`/data/v2/manage/database?database=${dataSourceName}`),
table: (dataSourceName: string, table: Table, operation?: string) => {
if (operation)
return encodeURI(
`/data/v2/manage/table/${operation}?database=${dataSourceName}&table=${JSON.stringify(
table
)}`
);
return encodeURI(
`/data/v2/manage/table?database=${dataSourceName}&table=${JSON.stringify(
table
)}`
);
},
});