mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 17:31:56 +03:00
console: Suggested relationship foreign key constraint on
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7880 GitOrigin-RevId: 24d2af47d308399ce489cda5bcf888b9d8a80fc5
This commit is contained in:
parent
01db431943
commit
2b4acb11e7
@ -1,10 +1,10 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
import Endpoints from '@/Endpoints';
|
import Endpoints from '@/Endpoints';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable';
|
|
||||||
import { useHttpClient } from '@/features/Network';
|
import { useHttpClient } from '@/features/Network';
|
||||||
import { useQuery, UseQueryResult } from 'react-query';
|
import { useQuery, UseQueryResult } from 'react-query';
|
||||||
import { useTablesForeignKeys } from './useTableForeignKeys';
|
import { useTablesForeignKeys } from './useTableForeignKeys';
|
||||||
import { TableObject, ForeignKeyMapping } from '../types';
|
import { TableObject, ForeignKeyMapping } from '../types';
|
||||||
|
import { areTablesEqual } from '@/features/hasura-metadata-api';
|
||||||
|
|
||||||
export type UseTableEnumOptionsProps = {
|
export type UseTableEnumOptionsProps = {
|
||||||
tables: TableObject[];
|
tables: TableObject[];
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
} from '@/features/FeatureFlags';
|
} from '@/features/FeatureFlags';
|
||||||
import { DatabaseRelationshipsTab } from '@/features/DatabaseRelationships';
|
import { DatabaseRelationshipsTab } from '@/features/DatabaseRelationships';
|
||||||
import { Button } from '@/new-components/Button';
|
import { Button } from '@/new-components/Button';
|
||||||
|
import { areTablesEqual } from '@/features/hasura-metadata-api';
|
||||||
import { LearnMoreLink } from '@/new-components/LearnMoreLink';
|
import { LearnMoreLink } from '@/new-components/LearnMoreLink';
|
||||||
import TableHeader from '../TableCommon/TableHeader';
|
import TableHeader from '../TableCommon/TableHeader';
|
||||||
import {
|
import {
|
||||||
@ -43,7 +44,6 @@ import { getRemoteSchemasSelector } from '../../../../metadata/selector';
|
|||||||
import { RightContainer } from '../../../Common/Layout/RightContainer';
|
import { RightContainer } from '../../../Common/Layout/RightContainer';
|
||||||
import FeatureDisabled from '../FeatureDisabled';
|
import FeatureDisabled from '../FeatureDisabled';
|
||||||
import { RemoteDbRelationships } from './RemoteDbRelationships/RemoteDbRelationships';
|
import { RemoteDbRelationships } from './RemoteDbRelationships/RemoteDbRelationships';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable/utils';
|
|
||||||
|
|
||||||
const addRelationshipCellView = (
|
const addRelationshipCellView = (
|
||||||
dispatch,
|
dispatch,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* eslint-disable no-underscore-dangle */
|
/* eslint-disable no-underscore-dangle */
|
||||||
import { getScalarType, getTypeName } from '@/features/GraphQLUtils';
|
import { getScalarType, getTypeName } from '@/features/GraphQLUtils';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable';
|
|
||||||
import { GraphQLType } from 'graphql';
|
import { GraphQLType } from 'graphql';
|
||||||
import { GDCTable } from '..';
|
import { GDCTable } from '..';
|
||||||
import {
|
import {
|
||||||
@ -11,6 +10,7 @@ import {
|
|||||||
import { GetTableColumnsProps, TableColumn } from '../../types';
|
import { GetTableColumnsProps, TableColumn } from '../../types';
|
||||||
import { adaptAgentDataType } from './utils';
|
import { adaptAgentDataType } from './utils';
|
||||||
import { GetTableInfoResponse } from './types';
|
import { GetTableInfoResponse } from './types';
|
||||||
|
import { areTablesEqual } from '@/features/hasura-metadata-api';
|
||||||
|
|
||||||
export const getTableColumns = async (props: GetTableColumnsProps) => {
|
export const getTableColumns = async (props: GetTableColumnsProps) => {
|
||||||
const { httpClient, dataSourceName, table } = props;
|
const { httpClient, dataSourceName, table } = props;
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
FaArrowRight,
|
FaArrowRight,
|
||||||
FaColumns,
|
FaColumns,
|
||||||
FaFont,
|
FaFont,
|
||||||
FaExclamationTriangle,
|
|
||||||
FaPlug,
|
FaPlug,
|
||||||
FaTable,
|
FaTable,
|
||||||
} from 'react-icons/fa';
|
} from 'react-icons/fa';
|
||||||
@ -21,16 +20,14 @@ const Columns = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const isMappingPresent = Object.entries(mapping)?.length ?? undefined;
|
const isMappingPresent = Object.entries(mapping)?.length ?? undefined;
|
||||||
|
|
||||||
return isMappingPresent ? (
|
if (!isMappingPresent) {
|
||||||
<>
|
return <></>;
|
||||||
{type === 'from'
|
}
|
||||||
? Object.keys(mapping).join(',')
|
|
||||||
: Object.values(mapping).join(',')}
|
return type === 'from' ? (
|
||||||
</>
|
<>{Object.keys(mapping).join(',')}</>
|
||||||
) : (
|
) : (
|
||||||
<Tooltip tooltipContentChildren="Unable to retrieve any column info. Please check if your datasource is reachable.">
|
<>{Object.values(mapping).join(',')}</>
|
||||||
<FaExclamationTriangle className="text-red-600" />
|
|
||||||
</Tooltip>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,6 +36,15 @@ export const RelationshipMapping = ({
|
|||||||
}: {
|
}: {
|
||||||
relationship: Relationship;
|
relationship: Relationship;
|
||||||
}) => {
|
}) => {
|
||||||
|
if (relationship.type !== 'remoteSchemaRelationship') {
|
||||||
|
const isMappingPresent =
|
||||||
|
Object.entries(relationship.definition?.mapping)?.length ?? undefined;
|
||||||
|
|
||||||
|
if (!isMappingPresent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-6">
|
<div className="flex items-center gap-6">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
@ -3,7 +3,7 @@ import { capitaliseFirstLetter } from '@/components/Common/ConfigureTransformati
|
|||||||
import { Table } from '@/features/hasura-metadata-types';
|
import { Table } from '@/features/hasura-metadata-types';
|
||||||
import { Button } from '@/new-components/Button';
|
import { Button } from '@/new-components/Button';
|
||||||
import { CardedTable } from '@/new-components/CardedTable';
|
import { CardedTable } from '@/new-components/CardedTable';
|
||||||
import { useFireNotification } from '@/new-components/Notifications';
|
import { hasuraToast } from '@/new-components/Toasts';
|
||||||
import {
|
import {
|
||||||
FaArrowRight,
|
FaArrowRight,
|
||||||
FaColumns,
|
FaColumns,
|
||||||
@ -14,13 +14,11 @@ import {
|
|||||||
import { MetadataSelectors, useMetadata } from '@/features/hasura-metadata-api';
|
import { MetadataSelectors, useMetadata } from '@/features/hasura-metadata-api';
|
||||||
import { getSupportsForeignKeys } from '@/features/hasura-metadata-api/utils';
|
import { getSupportsForeignKeys } from '@/features/hasura-metadata-api/utils';
|
||||||
import { useListAllDatabaseRelationships } from '../../hooks/useListAllDatabaseRelationships';
|
import { useListAllDatabaseRelationships } from '../../hooks/useListAllDatabaseRelationships';
|
||||||
import { useManageLocalRelationship } from '../../hooks/useManageLocalRelationship';
|
|
||||||
import { getTableDisplayName } from '../../utils/helpers';
|
import { getTableDisplayName } from '../../utils/helpers';
|
||||||
import {
|
import {
|
||||||
SuggestedRelationshipWithName,
|
SuggestedRelationshipWithName,
|
||||||
useSuggestedRelationships,
|
useSuggestedRelationships,
|
||||||
} from './hooks/useSuggestedRelationships';
|
} from './hooks/useSuggestedRelationships';
|
||||||
import { convertSuggestedRelationShipToLocalRelationship } from './SuggestedRelationships.utils';
|
|
||||||
import type { LocalRelationship } from '../../types';
|
import type { LocalRelationship } from '../../types';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
import Skeleton from 'react-loading-skeleton';
|
||||||
|
|
||||||
@ -37,7 +35,6 @@ export const SuggestedRelationships = ({
|
|||||||
dataSourceName,
|
dataSourceName,
|
||||||
table,
|
table,
|
||||||
});
|
});
|
||||||
|
|
||||||
const localRelationships = existingRelationships.filter(rel => {
|
const localRelationships = existingRelationships.filter(rel => {
|
||||||
if (rel.type === 'localRelationship') {
|
if (rel.type === 'localRelationship') {
|
||||||
return true;
|
return true;
|
||||||
@ -55,6 +52,8 @@ export const SuggestedRelationships = ({
|
|||||||
suggestedRelationships,
|
suggestedRelationships,
|
||||||
isLoadingSuggestedRelationships,
|
isLoadingSuggestedRelationships,
|
||||||
refetchSuggestedRelationships,
|
refetchSuggestedRelationships,
|
||||||
|
onAddSuggestedRelationship,
|
||||||
|
isAddingSuggestedRelationship,
|
||||||
} = useSuggestedRelationships({
|
} = useSuggestedRelationships({
|
||||||
dataSourceName,
|
dataSourceName,
|
||||||
table,
|
table,
|
||||||
@ -62,40 +61,35 @@ export const SuggestedRelationships = ({
|
|||||||
isEnabled: supportsForeignKeys,
|
isEnabled: supportsForeignKeys,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { fireNotification } = useFireNotification();
|
|
||||||
|
|
||||||
const { createRelationship, isLoading: isCreatingRelationship } =
|
|
||||||
useManageLocalRelationship({
|
|
||||||
dataSourceName,
|
|
||||||
table,
|
|
||||||
onSuccess: () => {
|
|
||||||
fireNotification({
|
|
||||||
title: 'Success',
|
|
||||||
message: 'Relationship tracked',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
refetchSuggestedRelationships();
|
|
||||||
},
|
|
||||||
onError: () => {
|
|
||||||
fireNotification({
|
|
||||||
title: 'Error',
|
|
||||||
message: 'An error occurred',
|
|
||||||
type: 'error',
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const [updatedRelationship, setUpdatedRelationship] = useState<string | null>(
|
const [updatedRelationship, setUpdatedRelationship] = useState<string | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const onCreate = (relationship: SuggestedRelationshipWithName) => {
|
const onCreate = async (relationship: SuggestedRelationshipWithName) => {
|
||||||
setUpdatedRelationship(relationship.constraintName);
|
setUpdatedRelationship(relationship.constraintName);
|
||||||
createRelationship(
|
try {
|
||||||
convertSuggestedRelationShipToLocalRelationship(
|
const isObjectRelationship = !!relationship.from?.constraint_name;
|
||||||
dataSourceName,
|
|
||||||
relationship
|
await onAddSuggestedRelationship({
|
||||||
)
|
name: relationship.constraintName,
|
||||||
);
|
columnNames: isObjectRelationship
|
||||||
|
? relationship.from.columns
|
||||||
|
: relationship.to.columns,
|
||||||
|
relationshipType: isObjectRelationship ? 'object' : 'array',
|
||||||
|
toTable: isObjectRelationship ? undefined : relationship.to.table,
|
||||||
|
});
|
||||||
|
hasuraToast({
|
||||||
|
title: 'Success',
|
||||||
|
message: 'Relationship tracked',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
refetchSuggestedRelationships();
|
||||||
|
} catch (err) {
|
||||||
|
hasuraToast({
|
||||||
|
title: 'Error',
|
||||||
|
message: 'An error occurred',
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isLoadingSuggestedRelationships)
|
if (isLoadingSuggestedRelationships)
|
||||||
@ -125,7 +119,7 @@ export const SuggestedRelationships = ({
|
|||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => onCreate(relationship)}
|
onClick={() => onCreate(relationship)}
|
||||||
isLoading={
|
isLoading={
|
||||||
isCreatingRelationship &&
|
isAddingSuggestedRelationship &&
|
||||||
updatedRelationship === relationship.constraintName
|
updatedRelationship === relationship.constraintName
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
@ -5,52 +5,18 @@ import {
|
|||||||
SuggestedRelationship,
|
SuggestedRelationship,
|
||||||
} from '@/features/DatabaseRelationships/types';
|
} from '@/features/DatabaseRelationships/types';
|
||||||
import { getTableDisplayName } from '@/features/DatabaseRelationships/utils/helpers';
|
import { getTableDisplayName } from '@/features/DatabaseRelationships/utils/helpers';
|
||||||
import { getDriverPrefix, NetworkArgs } from '@/features/DataSource';
|
import { getDriverPrefix, runMetadataQuery } from '@/features/DataSource';
|
||||||
import {
|
import {
|
||||||
areTablesEqual,
|
areTablesEqual,
|
||||||
MetadataSelectors,
|
MetadataSelectors,
|
||||||
} from '@/features/hasura-metadata-api';
|
} from '@/features/hasura-metadata-api';
|
||||||
import {
|
import { useMetadata } from '@/features/hasura-metadata-api/useMetadata';
|
||||||
DEFAULT_STALE_TIME,
|
|
||||||
useMetadata,
|
|
||||||
} from '@/features/hasura-metadata-api/useMetadata';
|
|
||||||
import { Table } from '@/features/hasura-metadata-types';
|
import { Table } from '@/features/hasura-metadata-types';
|
||||||
import { useHttpClient } from '@/features/Network';
|
import { useHttpClient } from '@/features/Network';
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery, useQueryClient } from 'react-query';
|
||||||
|
import { generateQueryKeys } from '@/features/DatabaseRelationships/utils/queryClientUtils';
|
||||||
type FetchSuggestedRelationshipsArgs = NetworkArgs & {
|
import { useMetadataMigration } from '@/features/MetadataAPI';
|
||||||
dataSourceName: string;
|
|
||||||
table: Table;
|
|
||||||
driverPrefix?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const emptyResponse: SuggestedRelationshipsResponse = { relationships: [] };
|
|
||||||
|
|
||||||
const fetchSuggestedRelationships = async ({
|
|
||||||
httpClient,
|
|
||||||
dataSourceName,
|
|
||||||
table,
|
|
||||||
driverPrefix,
|
|
||||||
}: FetchSuggestedRelationshipsArgs) => {
|
|
||||||
if (!driverPrefix) {
|
|
||||||
return Promise.resolve(emptyResponse);
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
await httpClient.post<any, { data: SuggestedRelationshipsResponse }>(
|
|
||||||
'/v1/metadata',
|
|
||||||
{
|
|
||||||
type: `${driverPrefix}_suggest_relationships`,
|
|
||||||
version: 1,
|
|
||||||
args: {
|
|
||||||
omit_tracked: true,
|
|
||||||
tables: [table],
|
|
||||||
source: dataSourceName,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
).data;
|
|
||||||
};
|
|
||||||
|
|
||||||
type UseSuggestedRelationshipsArgs = {
|
type UseSuggestedRelationshipsArgs = {
|
||||||
dataSourceName: string;
|
dataSourceName: string;
|
||||||
@ -59,7 +25,7 @@ type UseSuggestedRelationshipsArgs = {
|
|||||||
isEnabled: boolean;
|
isEnabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SuggestedRelationshipsResponse = {
|
export type SuggestedRelationshipsResponse = {
|
||||||
relationships: SuggestedRelationship[];
|
relationships: SuggestedRelationship[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,35 +153,86 @@ export const useSuggestedRelationships = ({
|
|||||||
MetadataSelectors.findSource(dataSourceName)
|
MetadataSelectors.findSource(dataSourceName)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const metadataMutation = useMetadataMigration({});
|
||||||
|
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const dataSourcePrefix = metadataSource?.kind
|
const dataSourcePrefix = metadataSource?.kind
|
||||||
? getDriverPrefix(metadataSource?.kind)
|
? getDriverPrefix(metadataSource?.kind)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const httpClient = useHttpClient();
|
const httpClient = useHttpClient();
|
||||||
const { data, refetch, isLoading } = useQuery<SuggestedRelationshipsResponse>(
|
|
||||||
{
|
|
||||||
queryKey: ['suggested_relationships', dataSourceName, table],
|
|
||||||
queryFn: async () => {
|
|
||||||
if (!isEnabled) {
|
|
||||||
return Promise.resolve(emptyResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await fetchSuggestedRelationships({
|
const {
|
||||||
httpClient,
|
data,
|
||||||
dataSourceName,
|
refetch: refetchSuggestedRelationships,
|
||||||
|
isLoading: isLoadingSuggestedRelationships,
|
||||||
|
} = useQuery({
|
||||||
|
queryKey: ['suggested_relationships', dataSourceName, table],
|
||||||
|
queryFn: async () => {
|
||||||
|
const body = {
|
||||||
|
type: `${dataSourcePrefix}_suggest_relationships`,
|
||||||
|
args: {
|
||||||
|
omit_tracked: true,
|
||||||
|
tables: [table],
|
||||||
|
source: dataSourceName,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = await runMetadataQuery<SuggestedRelationshipsResponse>({
|
||||||
|
httpClient,
|
||||||
|
body,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
enabled: isEnabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
const [isAddingSuggestedRelationship, setAddingSuggestedRelationship] =
|
||||||
|
useState(false);
|
||||||
|
|
||||||
|
const onAddSuggestedRelationship = async ({
|
||||||
|
name,
|
||||||
|
columnNames,
|
||||||
|
relationshipType,
|
||||||
|
toTable,
|
||||||
|
}: {
|
||||||
|
name: string;
|
||||||
|
columnNames: string[];
|
||||||
|
relationshipType: 'object' | 'array';
|
||||||
|
toTable?: Table;
|
||||||
|
}) => {
|
||||||
|
setAddingSuggestedRelationship(true);
|
||||||
|
|
||||||
|
await metadataMutation.mutateAsync({
|
||||||
|
query: {
|
||||||
|
type: `${dataSourcePrefix}_create_${relationshipType}_relationship`,
|
||||||
|
args: {
|
||||||
table,
|
table,
|
||||||
driverPrefix: dataSourcePrefix,
|
name,
|
||||||
});
|
source: dataSourceName,
|
||||||
return result;
|
using: {
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
relationshipType === 'object'
|
||||||
|
? columnNames
|
||||||
|
: {
|
||||||
|
table: toTable,
|
||||||
|
columns: columnNames,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
refetchOnWindowFocus: false,
|
});
|
||||||
staleTime: DEFAULT_STALE_TIME,
|
setAddingSuggestedRelationship(false);
|
||||||
}
|
|
||||||
);
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: generateQueryKeys.metadata(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (dataSourcePrefix) {
|
if (dataSourcePrefix) {
|
||||||
refetch();
|
refetchSuggestedRelationships();
|
||||||
}
|
}
|
||||||
}, [dataSourcePrefix]);
|
}, [dataSourcePrefix]);
|
||||||
|
|
||||||
@ -238,7 +255,9 @@ export const useSuggestedRelationships = ({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
suggestedRelationships: relationshipsWithConstraintName,
|
suggestedRelationships: relationshipsWithConstraintName,
|
||||||
isLoadingSuggestedRelationships: isLoading,
|
isLoadingSuggestedRelationships,
|
||||||
refetchSuggestedRelationships: refetch,
|
refetchSuggestedRelationships,
|
||||||
|
onAddSuggestedRelationship,
|
||||||
|
isAddingSuggestedRelationship,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@ import {
|
|||||||
isSameTableObjectRelationship,
|
isSameTableObjectRelationship,
|
||||||
TableFkRelationships,
|
TableFkRelationships,
|
||||||
} from '@/features/DataSource';
|
} from '@/features/DataSource';
|
||||||
|
import { areTablesEqual } from '@/features/hasura-metadata-api';
|
||||||
import {
|
import {
|
||||||
Legacy_SourceToRemoteSchemaRelationship,
|
Legacy_SourceToRemoteSchemaRelationship,
|
||||||
LocalTableArrayRelationship,
|
LocalTableArrayRelationship,
|
||||||
@ -13,7 +14,6 @@ import {
|
|||||||
SourceToSourceRelationship,
|
SourceToSourceRelationship,
|
||||||
Table,
|
Table,
|
||||||
} from '@/features/hasura-metadata-types';
|
} from '@/features/hasura-metadata-types';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable';
|
|
||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
import {
|
import {
|
||||||
LocalRelationship,
|
LocalRelationship,
|
||||||
|
@ -5,7 +5,7 @@ import { Table } from '@/features/hasura-metadata-types';
|
|||||||
import { useHttpClient } from '@/features/Network';
|
import { useHttpClient } from '@/features/Network';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { DataSource, exportMetadata, Operator } from '@/features/DataSource';
|
import { DataSource, exportMetadata, Operator } from '@/features/DataSource';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable';
|
import { areTablesEqual } from '@/features/hasura-metadata-api';
|
||||||
import { getTypeName } from '@/features/GraphQLUtils';
|
import { getTypeName } from '@/features/GraphQLUtils';
|
||||||
import { InputField } from '@/new-components/Form';
|
import { InputField } from '@/new-components/Form';
|
||||||
import { IconTooltip } from '@/new-components/Tooltip';
|
import { IconTooltip } from '@/new-components/Tooltip';
|
||||||
|
@ -4,8 +4,8 @@ import { useHttpClient } from '@/features/Network';
|
|||||||
import { exportMetadata, runIntrospectionQuery } from '@/features/DataSource';
|
import { exportMetadata, runIntrospectionQuery } from '@/features/DataSource';
|
||||||
import { Table } from '@/features/hasura-metadata-types';
|
import { Table } from '@/features/hasura-metadata-types';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable';
|
|
||||||
import { getAllColumnsAndOperators } from '../utils';
|
import { getAllColumnsAndOperators } from '../utils';
|
||||||
|
import { areTablesEqual } from '@/features/hasura-metadata-api';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
export type { ExistingRelationshipMeta } from './RemoteSchemaRelationshipsTable';
|
export type { ExistingRelationshipMeta } from './RemoteSchemaRelationshipsTable';
|
||||||
export { RemoteSchemaRelationshipTable } from './RemoteSchemaRelationshipsTable';
|
export { RemoteSchemaRelationshipTable } from './RemoteSchemaRelationshipsTable';
|
||||||
export { getRemoteFieldPath } from './utils';
|
export { getRemoteFieldPath } from './utils';
|
||||||
export { areTablesEqual } from './utils';
|
|
||||||
|
@ -2,6 +2,7 @@ import { RemoteRelationshipFieldServer } from '@/components/Services/Data/TableR
|
|||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
import { Table } from '@/features/hasura-metadata-types';
|
import { Table } from '@/features/hasura-metadata-types';
|
||||||
import { RelationshipSourceType, RelationshipType } from './types';
|
import { RelationshipSourceType, RelationshipType } from './types';
|
||||||
|
import { isArray, isObject } from '@/components/Common/utils/jsUtils';
|
||||||
|
|
||||||
export const getRemoteRelationType = (
|
export const getRemoteRelationType = (
|
||||||
relation: RelationshipType
|
relation: RelationshipType
|
||||||
@ -62,10 +63,3 @@ export const getRemoteSchemaRelationType = (
|
|||||||
'Remote Schema',
|
'Remote Schema',
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const areTablesEqual = (table1: Table, table2: Table) => {
|
|
||||||
const values1 = Object.values(table1 as any).sort();
|
|
||||||
const values2 = Object.values(table2 as any).sort();
|
|
||||||
|
|
||||||
return isEqual(values1, values2);
|
|
||||||
};
|
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
import { areTablesEqual } from './areTablesEqual';
|
||||||
|
|
||||||
|
describe('areTablesEqual', () => {
|
||||||
|
it.each`
|
||||||
|
table1 | table2 | expected
|
||||||
|
${undefined} | ${undefined} | ${true}
|
||||||
|
${null} | ${undefined} | ${false}
|
||||||
|
${1} | ${2} | ${false}
|
||||||
|
${['Album']} | ${['Album']} | ${true}
|
||||||
|
${{ name: 'Album', schema: 'public' }} | ${{ name: 'Artist', schema: 'public' }} | ${false}
|
||||||
|
${{ name: 'Album', schema: 'public' }} | ${{ name: 'Album', schema: 'public' }} | ${true}
|
||||||
|
`(
|
||||||
|
'returns $expected when table1 is $table1 and table2 is $table2',
|
||||||
|
({ table1, table2, expected }) => {
|
||||||
|
expect(areTablesEqual(table1, table2)).toEqual(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
@ -1,11 +1,17 @@
|
|||||||
|
import { isArray, isObject } from '@/components/Common/utils/jsUtils';
|
||||||
import { Table } from '@/features/hasura-metadata-types';
|
import { Table } from '@/features/hasura-metadata-types';
|
||||||
import isEqual from 'lodash.isequal';
|
import isEqual from 'lodash.isequal';
|
||||||
|
|
||||||
// giving this it's own module so it doesn't get mixed up with utils
|
const isObjectOrArray = (table: Table) => isObject(table) || isArray(table);
|
||||||
|
|
||||||
export const areTablesEqual = (table1: Table, table2: Table) => {
|
export const areTablesEqual = (table1: Table, table2: Table) => {
|
||||||
const values1 = Object.values(table1 as any).sort();
|
const values1 = isObjectOrArray(table1)
|
||||||
const values2 = Object.values(table2 as any).sort();
|
? Object.values(table1 as any).sort()
|
||||||
|
: table1;
|
||||||
|
|
||||||
|
const values2 = isObjectOrArray(table2)
|
||||||
|
? Object.values(table2 as any).sort()
|
||||||
|
: table2;
|
||||||
|
|
||||||
return isEqual(values1, values2);
|
return isEqual(values1, values2);
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@ import { useQuery } from 'react-query';
|
|||||||
import { exportMetadata } from '@/features/DataSource';
|
import { exportMetadata } from '@/features/DataSource';
|
||||||
import { Table } from '@/features/hasura-metadata-types';
|
import { Table } from '@/features/hasura-metadata-types';
|
||||||
import { useHttpClient } from '@/features/Network';
|
import { useHttpClient } from '@/features/Network';
|
||||||
import { areTablesEqual } from '@/features/RelationshipsTable';
|
|
||||||
import { DEFAULT_STALE_TIME } from '../DatabaseRelationships';
|
import { DEFAULT_STALE_TIME } from '../DatabaseRelationships';
|
||||||
|
import { areTablesEqual } from './areTablesEqual';
|
||||||
|
|
||||||
export const useMetadata = () => {
|
export const useMetadata = () => {
|
||||||
const httpClient = useHttpClient();
|
const httpClient = useHttpClient();
|
||||||
|
@ -102,6 +102,7 @@ export const metadataQueryTypes = [
|
|||||||
'drop_host_from_tls_allowlist',
|
'drop_host_from_tls_allowlist',
|
||||||
'dc_add_agent',
|
'dc_add_agent',
|
||||||
'dc_delete_agent',
|
'dc_delete_agent',
|
||||||
|
'suggest_relationships',
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type MetadataQueryType = (typeof metadataQueryTypes)[number];
|
export type MetadataQueryType = (typeof metadataQueryTypes)[number];
|
||||||
|
Loading…
Reference in New Issue
Block a user