fix: Too many API calls fired from the suggested relationships component

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8708
GitOrigin-RevId: 9d917b9015053e5653d2277f3dcdf69168bd1eff
This commit is contained in:
Luca Restagno 2023-04-17 11:19:18 +02:00 committed by hasura-bot
parent 1ad1e08959
commit ed8be7dd69
12 changed files with 317 additions and 194 deletions

View File

@ -102,12 +102,12 @@ export const ManageTrackedRelationships: React.VFC<
</div>
) : (
<>
<Tabs.Content value="tracked" className="px-md">
<TrackedRelationshipsContainer dataSourceName={dataSourceName} />
</Tabs.Content>
<Tabs.Content value="untracked" className="px-md">
<UntrackedRelationships dataSourceName={dataSourceName} />
</Tabs.Content>
<Tabs.Content value="tracked" className="px-md">
<TrackedRelationshipsContainer dataSourceName={dataSourceName} />
</Tabs.Content>
</>
)}
</Tabs.Root>

View File

@ -1,4 +1,4 @@
import { useSuggestedRelationships } from '../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useSuggestedRelationships';
import { useAllSuggestedRelationships } from '../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useAllSuggestedRelationships';
import { useTrackedRelationships } from './hooks/useTrackedRelationships';
import { ManageTrackedRelationships } from './ManageTrackedRelationships';
@ -13,9 +13,9 @@ export const ManageTrackedRelationshipsContainer = ({
} = useTrackedRelationships(dataSourceName);
const { suggestedRelationships, isLoadingSuggestedRelationships } =
useSuggestedRelationships({
useAllSuggestedRelationships({
dataSourceName,
existingRelationships: [],
omitTracked: true,
isEnabled: true,
});

View File

@ -23,14 +23,13 @@ import {
generateDeleteLocalRelationshipRequest,
generateRemoteRelationshipDeleteRequest,
} from '../../../DatabaseRelationships/utils/generateRequest';
import { generateQueryKeys } from '../../../DatabaseRelationships/utils/queryClientUtils';
import { useQueryClient } from 'react-query';
import { exportMetadata } from '../../../DataSource';
import { useHttpClient } from '../../../Network';
import { IndicatorCard } from '../../../../new-components/IndicatorCard';
import { MetadataDataSource } from '../../../../metadata/types';
import Skeleton from 'react-loading-skeleton';
import { getSuggestedRelationshipsCacheQuery } from '../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useSuggestedRelationships';
import { generateQueryKeys } from '../../../DatabaseRelationships/utils/queryClientUtils';
import { useQueryClient } from 'react-query';
import { useCheckRows } from '../../../DatabaseRelationships/hooks/useCheckRows';
const getQueryFunction = (relationship: Relationship) => {
@ -59,7 +58,7 @@ interface TrackedRelationshipsProps {
dataSourceName: string;
driver?: MetadataDataSource['kind'];
isLoading: boolean;
onRefetchMetadata: () => void;
onUpdate: () => void;
relationships: Relationship[];
}
@ -67,12 +66,13 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
dataSourceName,
driver,
isLoading,
onRefetchMetadata,
onUpdate,
relationships,
}) => {
const httpClient = useHttpClient();
const { mutateAsync } = useMetadataMigration();
const queryClient = useQueryClient();
const [isTrackingSelectedRelationships, setTrackingSelectedRelationships] =
useState(false);
@ -118,50 +118,41 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
);
if (driver) {
for (let i = 0; i < selectedRelationships.length; i++) {
const selectedRelationship = selectedRelationships[i];
const mutationOptions = {
const recentMetadata = await exportMetadata({ httpClient });
const queries = selectedRelationships.map(relationship => {
const queryFunction = getQueryFunction(relationship);
const query = queryFunction
? queryFunction({
driver,
resource_version: recentMetadata.resource_version,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
relationship,
})
: {};
return query;
});
await mutateAsync(
{
query: {
type: 'bulk',
args: queries,
},
},
{
onSuccess: () => {
queryClient.invalidateQueries(generateQueryKeys.metadata());
queryClient.invalidateQueries(
generateQueryKeys.suggestedRelationships({
dataSourceName,
table: selectedRelationship.fromTable,
})
);
},
};
const queryFunction = getQueryFunction(selectedRelationship);
if (queryFunction) {
const recentMetadata = await exportMetadata({ httpClient });
await mutateAsync(
{
query: queryFunction({
driver,
resource_version: recentMetadata.resource_version,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
relationship: selectedRelationship,
}),
},
mutationOptions
);
queryClient.invalidateQueries(
getSuggestedRelationshipsCacheQuery(
dataSourceName,
selectedRelationship.fromTable
)
);
}
}
);
onRefetchMetadata();
onUpdate();
const relationshipLabel =
selectedRelationships.length > 1 ? 'Relationships' : 'Relationship';
const toastMessage = `${selectedRelationships.length} ${relationshipLabel} untracked`;
const plural = selectedRelationships.length > 1 ? 's' : '';
const toastMessage = `${selectedRelationships.length} relationship${plural} untracked`;
hasuraToast({
title: 'Success',
@ -170,6 +161,7 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
});
}
} catch (err) {
console.error(err);
setTrackingSelectedRelationships(false);
}
reset();
@ -200,6 +192,7 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
};
const onRelationshipActionSuccess = () => {
onUpdate();
if (mode)
fireNotification({
type: 'success',

View File

@ -47,10 +47,9 @@ export const TrackedRelationshipsContainer: React.VFC<
dataSourceName={dataSourceName}
isLoading={isLoadingRelationships || isLoadingMetadata}
relationships={relationships}
onRefetchMetadata={() => {
refetchMetadata().then(() => {
refetchRelationships();
});
onUpdate={async () => {
await refetchMetadata();
await refetchRelationships();
}}
driver={driver}
/>

View File

@ -9,27 +9,39 @@ import { DEFAULT_PAGE_NUMBER, DEFAULT_PAGE_SIZE } from '../constants';
import { paginate } from '../utils';
import { SearchBar } from './SearchBar';
import { Badge } from '../../../../new-components/Badge';
import {
SuggestedRelationshipWithName,
useSuggestedRelationships,
} from '../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useSuggestedRelationships';
import { SuggestedRelationshipWithName } from '../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useSuggestedRelationships';
import { RelationshipRow } from './RelationshipRow';
import { SuggestedRelationshipTrackModal } from '../../../DatabaseRelationships/components/SuggestedRelationshipTrackModal/SuggestedRelationshipTrackModal';
import { hasuraToast } from '../../../../new-components/Toasts';
import Skeleton from 'react-loading-skeleton';
import { useQueryClient } from 'react-query';
import { getTrackedRelationshipsCacheKey } from './hooks/useTrackedRelationships';
import {
AddSuggestedRelationship,
useAllSuggestedRelationships,
} from '../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useAllSuggestedRelationships';
import { useCheckRows } from '../../../DatabaseRelationships/hooks/useCheckRows';
interface UntrackedRelationshipsProps {
dataSourceName: string;
}
const adaptTrackRelationship = (
relationship: SuggestedRelationshipWithName
): AddSuggestedRelationship => {
const isObjectRelationship = !!relationship.from?.constraint_name;
return {
name: relationship.constraintName,
columnNames: isObjectRelationship
? relationship.from.columns
: relationship.to.columns,
relationshipType: isObjectRelationship ? 'object' : 'array',
toTable: isObjectRelationship ? undefined : relationship.to.table,
fromTable: relationship.from.table,
};
};
export const UntrackedRelationships: React.VFC<UntrackedRelationshipsProps> = ({
dataSourceName,
}) => {
const queryClient = useQueryClient();
const [pageNumber, setPageNumber] = useState(DEFAULT_PAGE_NUMBER);
const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
const [searchText, setSearchText] = useState('');
@ -41,12 +53,11 @@ export const UntrackedRelationships: React.VFC<UntrackedRelationshipsProps> = ({
const {
suggestedRelationships,
isLoadingSuggestedRelationships,
onAddSuggestedRelationship,
refetchSuggestedRelationships,
} = useSuggestedRelationships({
onAddMultipleSuggestedRelationships,
} = useAllSuggestedRelationships({
dataSourceName,
existingRelationships: [],
isEnabled: true,
omitTracked: true,
});
const checkboxRef = React.useRef<HTMLInputElement>(null);
@ -82,19 +93,9 @@ export const UntrackedRelationships: React.VFC<UntrackedRelationshipsProps> = ({
}, [inputStatus]);
const onTrackRelationship = (relationship: SuggestedRelationshipWithName) => {
const isObjectRelationship = !!relationship.from?.constraint_name;
return onAddSuggestedRelationship({
name: relationship.constraintName,
columnNames: isObjectRelationship
? relationship.from.columns
: relationship.to.columns,
relationshipType: isObjectRelationship ? 'object' : 'array',
toTable: isObjectRelationship ? undefined : relationship.to.table,
fromTable: relationship.from.table,
}).then(() => {
refetchSuggestedRelationships();
});
return onAddMultipleSuggestedRelationships([
adaptTrackRelationship(relationship),
]);
};
const [isTrackingSelectedRelationships, setTrackingSelectedRelationships] =
@ -106,24 +107,21 @@ export const UntrackedRelationships: React.VFC<UntrackedRelationshipsProps> = ({
checkedIds.includes(rel.constraintName)
);
for (const selectedRelationship of selectedRelationships) {
await onTrackRelationship(selectedRelationship);
}
const trackRelationships: AddSuggestedRelationship[] =
selectedRelationships.map(adaptTrackRelationship);
queryClient.invalidateQueries({
queryKey: getTrackedRelationshipsCacheKey(dataSourceName),
});
await onAddMultipleSuggestedRelationships(trackRelationships);
const plural = selectedRelationships.length > 1 ? 's' : '';
hasuraToast({
title: 'Success',
message: 'Relationships tracked',
message: `${selectedRelationships.length} relationship${plural} tracked`,
type: 'success',
});
} catch (err) {
setTrackingSelectedRelationships(false);
}
reset();
refetchSuggestedRelationships();
setTrackingSelectedRelationships(false);
};

View File

@ -1,10 +1,7 @@
import { useQuery } from 'react-query';
import { useAllSuggestedRelationships } from '../../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useAllSuggestedRelationships';
import { tableRelationships as getTableRelationships } from '../../../../DatabaseRelationships/utils/tableRelationships';
import { DataSource } from '../../../../DataSource';
import {
useMetadata,
MetadataSelectors,
} from '../../../../hasura-metadata-api';
import { exportMetadata } from '../../../../DataSource';
import { useHttpClient } from '../../../../Network';
export const getTrackedRelationshipsCacheKey = (dataSourceName: string) => [
@ -15,29 +12,28 @@ export const getTrackedRelationshipsCacheKey = (dataSourceName: string) => [
export const useTrackedRelationships = (dataSourceName: string) => {
const httpClient = useHttpClient();
const {
data: metadataTables,
isFetching: isMetadataPending,
isLoading: isMetadataLoading,
error: metadataError,
refetch: refetchMetadata,
} = useMetadata(MetadataSelectors.getTables(dataSourceName));
const { suggestedRelationships } = useAllSuggestedRelationships({
dataSourceName,
isEnabled: true,
omitTracked: false,
});
const fetchRelationships = async () => {
const _tableRelationships = [];
if (metadataTables && !isMetadataLoading) {
for (const metadataTable of metadataTables) {
const fkConstraints = await DataSource(
httpClient
).getTableFkRelationships({
dataSourceName,
table: metadataTable.table,
});
const { metadata } = await exportMetadata({ httpClient });
const currentMetadataSource = metadata.sources?.find(
source => source.name === dataSourceName
);
const metadataTables = currentMetadataSource?.tables || [];
const _tableRelationships = [];
if (metadataTables) {
for (const metadataTable of metadataTables) {
const tableRelationships = getTableRelationships(
metadataTable,
dataSourceName,
fkConstraints
suggestedRelationships
);
_tableRelationships.push(...tableRelationships);
}
@ -51,6 +47,7 @@ export const useTrackedRelationships = (dataSourceName: string) => {
isLoading: isLoadingRelationships,
isFetching: isFetchingRelationships,
refetch: refetchRelationships,
error,
} = useQuery({
queryFn: fetchRelationships,
queryKey: getTrackedRelationshipsCacheKey(dataSourceName),
@ -58,10 +55,9 @@ export const useTrackedRelationships = (dataSourceName: string) => {
return {
data: relationships || [],
isFetching: isMetadataPending || isFetchingRelationships,
isLoading: isMetadataLoading || isLoadingRelationships,
error: [metadataError],
isFetching: isFetchingRelationships,
isLoading: isLoadingRelationships,
error: [error],
refetchRelationships,
refetchMetadata,
};
};

View File

@ -0,0 +1,155 @@
import { useEffect } from 'react';
import { useQuery, useQueryClient } from 'react-query';
import { LocalRelationship } from '../../../types';
import { getDriverPrefix, runMetadataQuery } from '../../../../DataSource';
import { MetadataSelectors } from '../../../../hasura-metadata-api';
import { useMetadata } from '../../../../hasura-metadata-api/useMetadata';
import { useHttpClient } from '../../../../Network';
import {
addConstraintName,
SuggestedRelationshipsResponse,
} from './useSuggestedRelationships';
import { useMetadataMigration } from '../../../../MetadataAPI';
import { NamingConvention, Table } from '../../../../hasura-metadata-types';
import { getTrackedRelationshipsCacheKey } from '../../../../Data/TrackResources/components/hooks/useTrackedRelationships';
export type AddSuggestedRelationship = {
name: string;
columnNames: string[];
relationshipType: 'object' | 'array';
toTable?: Table;
fromTable?: Table;
};
type UseSuggestedRelationshipsArgs = {
dataSourceName: string;
existingRelationships?: LocalRelationship[];
isEnabled: boolean;
omitTracked: boolean;
};
export const getAllSuggestedRelationshipsCacheQuery = (
dataSourceName: string,
omitTracked: boolean
) => ['all_suggested_relationships', dataSourceName, omitTracked];
export const useAllSuggestedRelationships = ({
dataSourceName,
isEnabled,
omitTracked,
}: UseSuggestedRelationshipsArgs) => {
const { data: metadataSource, isFetching } = useMetadata(
MetadataSelectors.findSource(dataSourceName)
);
const dataSourcePrefix = metadataSource?.kind
? getDriverPrefix(metadataSource?.kind)
: undefined;
const namingConvention: NamingConvention =
metadataSource?.customization?.naming_convention || 'hasura-default';
const httpClient = useHttpClient();
const {
data,
refetch: refetchAllSuggestedRelationships,
isLoading: isLoadingAllSuggestedRelationships,
isFetching: isFetchingAllSuggestedRelationships,
...rest
} = useQuery({
queryKey: getAllSuggestedRelationshipsCacheQuery(
dataSourceName,
omitTracked
),
queryFn: async () => {
const body = {
type: `${dataSourcePrefix}_suggest_relationships`,
args: {
omit_tracked: omitTracked,
source: dataSourceName,
},
};
const result = await runMetadataQuery<SuggestedRelationshipsResponse>({
httpClient,
body,
});
return result;
},
enabled: isEnabled && !isFetching,
refetchOnWindowFocus: false,
});
useEffect(() => {
if (dataSourcePrefix) {
refetchAllSuggestedRelationships();
}
}, [dataSourcePrefix]);
const rawSuggestedRelationships = data?.relationships || [];
const metadataMutation = useMetadataMigration({});
const queryClient = useQueryClient();
const onAddMultipleSuggestedRelationships = async (
relationships: AddSuggestedRelationship[]
) => {
const queries = relationships.map(relationship => {
return {
type: `${dataSourcePrefix}_create_${relationship.relationshipType}_relationship`,
args: {
table: relationship.fromTable,
name: relationship.name,
source: dataSourceName,
using: {
foreign_key_constraint_on:
relationship.relationshipType === 'object'
? relationship.columnNames
: {
table: relationship.toTable,
columns: relationship.columnNames,
},
},
},
};
});
await metadataMutation.mutateAsync(
{
query: {
type: 'bulk',
args: queries,
},
},
{
onSettled: () => {
queryClient.invalidateQueries({
queryKey: getAllSuggestedRelationshipsCacheQuery(
dataSourceName,
omitTracked
),
});
queryClient.invalidateQueries({
queryKey: getTrackedRelationshipsCacheKey(dataSourceName),
});
},
}
);
};
const relationshipsWithConstraintName = addConstraintName(
rawSuggestedRelationships,
namingConvention
);
return {
suggestedRelationships: relationshipsWithConstraintName,
isLoadingSuggestedRelationships: isLoadingAllSuggestedRelationships,
isFetchingSuggestedRelationships: isFetchingAllSuggestedRelationships,
refetchSuggestedRelationships: refetchAllSuggestedRelationships,
onAddMultipleSuggestedRelationships,
...rest,
};
};

View File

@ -145,6 +145,14 @@ export const removeExistingRelationships = ({
return false;
});
type AddSuggestedRelationship = {
name: string;
columnNames: string[];
relationshipType: 'object' | 'array';
toTable?: Table;
fromTable?: Table;
};
export const getSuggestedRelationshipsCacheQuery = (
dataSourceName: string,
table: Table
@ -208,13 +216,7 @@ export const useSuggestedRelationships = ({
relationshipType,
toTable,
fromTable,
}: {
name: string;
columnNames: string[];
relationshipType: 'object' | 'array';
toTable?: Table;
fromTable?: Table;
}) => {
}: AddSuggestedRelationship) => {
setAddingSuggestedRelationship(true);
await metadataMutation.mutateAsync({

View File

@ -1,36 +1,7 @@
import { DataSource } from '../../DataSource';
import { Table } from '../../hasura-metadata-types';
import { useHttpClient } from '../../Network';
import { useQuery } from 'react-query';
import { useMetadata, MetadataSelectors } from '../../hasura-metadata-api';
import {
DEFAULT_STALE_TIME,
generateQueryKeys,
} from '../utils/queryClientUtils';
import { tableRelationships } from '../utils/tableRelationships';
const useFkConstraints = ({
dataSourceName,
table,
}: {
dataSourceName: string;
table: Table;
}) => {
const httpClient = useHttpClient();
return useQuery({
queryKey: generateQueryKeys.fkConstraints({ table, dataSourceName }),
queryFn: async () => {
const result = await DataSource(httpClient).getTableFkRelationships({
dataSourceName,
table,
});
return result;
},
refetchOnWindowFocus: false,
staleTime: DEFAULT_STALE_TIME,
});
};
import { useAllSuggestedRelationships } from '../components/SuggestedRelationships/hooks/useAllSuggestedRelationships';
export const useListAllDatabaseRelationships = ({
dataSourceName,
@ -47,16 +18,24 @@ export const useListAllDatabaseRelationships = ({
} = useMetadata(MetadataSelectors.findTable(dataSourceName, table));
const {
data: fkConstraints,
isFetching: isDALIntrospectionPending,
isLoading: isDALIntrospectionLoading,
error: dalError,
} = useFkConstraints({ dataSourceName, table });
suggestedRelationships,
isLoadingSuggestedRelationships,
isFetchingSuggestedRelationships,
error,
} = useAllSuggestedRelationships({
dataSourceName,
isEnabled: true,
omitTracked: false,
});
return {
data: tableRelationships(metadataTable, dataSourceName, fkConstraints),
isFetching: isMetadataPending || isDALIntrospectionPending,
isLoading: isMetadataLoading || isDALIntrospectionLoading,
error: [metadataError, dalError],
data: tableRelationships(
metadataTable,
dataSourceName,
suggestedRelationships
),
isFetching: isMetadataPending || isFetchingSuggestedRelationships,
isLoading: isMetadataLoading || isLoadingSuggestedRelationships,
error: [metadataError, error],
};
};

View File

@ -1,7 +1,4 @@
import {
isSameTableObjectRelationship,
TableFkRelationships,
} from '../../DataSource';
import { isSameTableObjectRelationship } from '../../DataSource';
import { areTablesEqual } from '../../hasura-metadata-api';
import {
Legacy_SourceToRemoteSchemaRelationship,
@ -19,6 +16,7 @@ import {
LocalRelationship,
RemoteDatabaseRelationship,
RemoteSchemaRelationship,
SuggestedRelationship,
} from '../types';
const getKeyValuePair = (arr1: string[], arr2: string[]) => {
@ -35,7 +33,7 @@ const getFkDefinition = (
| SameTableObjectRelationship
| LocalTableObjectRelationship
| LocalTableArrayRelationship,
fkConstraints: TableFkRelationships[]
suggestedRelationships: SuggestedRelationship[]
): { toTable: Table; mapping: Record<string, string> } => {
if (isSameTableObjectRelationship(relationship)) {
const fromTable = table;
@ -45,18 +43,18 @@ const getFkDefinition = (
? relationship.using.foreign_key_constraint_on
: [relationship.using.foreign_key_constraint_on];
const matchingFkConstraint = fkConstraints.find(
fkConstraint =>
areTablesEqual(fromTable, fkConstraint.from.table) &&
isEqual(fromColumns.sort(), fkConstraint.from.column)
const matchingFkConstraint = suggestedRelationships.find(
suggestedRelationship =>
areTablesEqual(fromTable, suggestedRelationship.from.table) &&
isEqual(fromColumns.sort(), suggestedRelationship.from.columns)
);
return {
toTable: matchingFkConstraint?.to.table,
mapping: matchingFkConstraint
? getKeyValuePair(
matchingFkConstraint.from.column,
matchingFkConstraint.to.column
matchingFkConstraint.from.columns,
matchingFkConstraint.to.columns
)
: {},
};
@ -68,17 +66,18 @@ const getFkDefinition = (
? [relationship.using.foreign_key_constraint_on.column]
: relationship.using.foreign_key_constraint_on.columns;
const matchingFkConstraint = fkConstraints.find(
fkConstraint =>
areTablesEqual(toTable, fkConstraint.to.table) &&
isEqual(toColumn.sort(), fkConstraint.to.column)
const matchingFkConstraint = suggestedRelationships.find(
suggestedRelationship =>
areTablesEqual(toTable, suggestedRelationship.to.table) &&
isEqual(toColumn.sort(), suggestedRelationship.to.columns)
);
return {
toTable: matchingFkConstraint?.from.table,
mapping: matchingFkConstraint
? getKeyValuePair(
matchingFkConstraint.to.column,
matchingFkConstraint.from.column
matchingFkConstraint.to.columns,
matchingFkConstraint.from.columns
)
: {},
};
@ -110,12 +109,12 @@ export const adaptLocalObjectRelationshipWithFkConstraint = ({
table,
dataSourceName,
relationship,
fkConstraints,
suggestedRelationships,
}: {
table: Table;
dataSourceName: string;
relationship: SameTableObjectRelationship | LocalTableObjectRelationship;
fkConstraints: TableFkRelationships[];
suggestedRelationships: SuggestedRelationship[];
}): LocalRelationship => {
return {
name: relationship.name,
@ -123,7 +122,7 @@ export const adaptLocalObjectRelationshipWithFkConstraint = ({
fromTable: table,
relationshipType: 'Object',
type: 'localRelationship',
definition: getFkDefinition(table, relationship, fkConstraints),
definition: getFkDefinition(table, relationship, suggestedRelationships),
};
};
@ -153,12 +152,12 @@ export const adaptLocalArrayRelationshipWithFkConstraint = ({
table,
dataSourceName,
relationship,
fkConstraints,
suggestedRelationships,
}: {
table: Table;
dataSourceName: string;
relationship: LocalTableArrayRelationship;
fkConstraints: TableFkRelationships[];
suggestedRelationships: SuggestedRelationship[];
}): LocalRelationship => {
return {
name: relationship.name,
@ -166,7 +165,7 @@ export const adaptLocalArrayRelationshipWithFkConstraint = ({
fromTable: table,
relationshipType: 'Array',
type: 'localRelationship',
definition: getFkDefinition(table, relationship, fkConstraints),
definition: getFkDefinition(table, relationship, suggestedRelationships),
};
};

View File

@ -3,7 +3,6 @@ import {
isManualArrayRelationship,
isManualObjectRelationship,
isRemoteSchemaRelationship,
TableFkRelationships,
} from '../../DataSource';
import { MetadataTable } from '../../hasura-metadata-types';
import {
@ -11,6 +10,7 @@ import {
Relationship,
RemoteDatabaseRelationship,
RemoteSchemaRelationship,
SuggestedRelationship,
} from '../types';
import {
adaptLegacyRemoteSchemaRelationship,
@ -25,7 +25,7 @@ import {
export function tableRelationships(
metadataTable: MetadataTable | undefined,
dataSourceName: string,
fkConstraints: TableFkRelationships[] | undefined
suggestedRelationships: SuggestedRelationship[]
): Relationship[] {
const table = metadataTable?.table;
// adapt local array relationships
@ -43,7 +43,7 @@ export function tableRelationships(
table,
dataSourceName,
relationship,
fkConstraints: fkConstraints ?? [],
suggestedRelationships,
});
});
@ -61,7 +61,7 @@ export function tableRelationships(
table,
dataSourceName,
relationship,
fkConstraints: fkConstraints ?? [],
suggestedRelationships,
});
});

View File

@ -1,9 +1,8 @@
import { areTablesEqual } from '../../../../../hasura-metadata-api';
import { tableRelationships } from '../../../../../DatabaseRelationships/utils/tableRelationships';
import { useTablesFkConstraints } from './useTablesFkConstraints';
import { useTablesWithColumns } from './useTablesWithColumns';
import { useSources } from '../../../../../MetadataAPI';
import { Tables } from '../components';
import { useAllSuggestedRelationships } from '../../../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useAllSuggestedRelationships';
export const usePermissionTables = ({
dataSourceName,
@ -14,23 +13,26 @@ export const usePermissionTables = ({
const { data: tables, isLoading: isLoadingTables } = useTablesWithColumns({
dataSourceName,
});
const { data: fkConstraints, isLoading: isDALIntrospectionLoading } =
useTablesFkConstraints({ dataSourceName, tables });
if (isLoadingTables || isDALIntrospectionLoading || isLoadingSources)
const { suggestedRelationships, isLoadingSuggestedRelationships } =
useAllSuggestedRelationships({
dataSourceName,
isEnabled: true,
omitTracked: false,
});
if (isLoadingTables || isLoadingSuggestedRelationships || isLoadingSources)
return [];
return (
tables?.map(({ metadataTable, columns }) => {
const relationships = fkConstraints?.find(({ table }) =>
areTablesEqual(table, metadataTable.table)
)?.relationships;
return {
table: metadataTable.table,
dataSource: sources?.find(source => source.name === dataSourceName),
relationships: tableRelationships(
metadataTable,
dataSourceName,
relationships
suggestedRelationships
),
columns,
};