Add function customization for GDC data sources

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9770
GitOrigin-RevId: b27d37f02f2abbe7ec08256a5dc812c3b62e35db
This commit is contained in:
Luca Restagno 2023-07-07 15:35:58 +02:00 committed by hasura-bot
parent 0151e25e8b
commit f2b46f677e
3 changed files with 71 additions and 18 deletions

View File

@ -1,17 +1,21 @@
import { useState } from 'react';
import { Driver } from '../../../../../../dataSources';
import omit from 'lodash/omit';
import { RootField } from '../../../../../../features/Data/ModifyTable/components/TableRootFields';
import { isGDCTable } from '../../../../../../features/DataSource/utils';
import {
MetadataSelectors,
useMetadata,
} from '../../../../../../features/hasura-metadata-api';
import { QualifiedFunction } from '../../../../../../features/hasura-metadata-types';
import {
QualifiedFunction,
SupportedDrivers,
} from '../../../../../../features/hasura-metadata-types';
import { Button } from '../../../../../../new-components/Button';
import { Dialog } from '../../../../../../new-components/Dialog';
import { LearnMoreLink } from '../../../../../../new-components/LearnMoreLink';
import { hasuraToast } from '../../../../../../new-components/Toasts';
import { IconTooltip } from '../../../../../../new-components/Tooltip';
import { isObject } from '../../../../../Common/utils/jsUtils';
import { isArray, isObject } from '../../../../../Common/utils/jsUtils';
import {
CustomFunctionFieldsForm,
CustomFunctionFieldsFormValues,
@ -19,7 +23,7 @@ import {
import { useSetFunctionCustomization } from './hooks/useSetFunctionCustomization';
export type FunctionGraphQLCustomizationProps = {
driver: Driver;
driver: SupportedDrivers;
dataSourceName: string;
qualifiedFunction: QualifiedFunction;
};
@ -29,6 +33,10 @@ const getFunctionName = (fn: QualifiedFunction) => {
return fn.name as string;
}
if (isArray(fn)) {
return fn.join('.');
}
return '';
};
@ -55,8 +63,8 @@ export const FunctionGraphQLCustomization = ({
const isCustomized =
metadataFunction?.configuration?.custom_name ||
(metadataFunction?.configuration?.custom_root_fields &&
Object.keys(metadataFunction?.configuration?.custom_root_fields)
.length === 0);
Object.keys(metadataFunction?.configuration?.custom_root_fields).length >
0);
const functionName = getFunctionName(metadataFunction?.function);
@ -90,18 +98,28 @@ export const FunctionGraphQLCustomization = ({
: {}),
};
const configuration = {
const newFieldsConfiguration = {
...(data.custom_name ? { custom_name: data.custom_name } : {}),
...(areCustomRootFieldsDefined
? { custom_root_fields: customRootFields }
: {}),
};
const previousConfiguration = omit(
metadataFunction?.configuration ? metadataFunction.configuration : {},
['custom_name', 'custom_root_fields']
);
return onSetFunctionCustomization({
driver,
dataSourceName,
functionName,
configuration,
functionName: isGDCTable(qualifiedFunction)
? qualifiedFunction
: functionName,
configuration: {
...previousConfiguration,
...newFieldsConfiguration,
},
});
};

View File

@ -1,5 +1,10 @@
import { Driver } from '../../../../../../../dataSources';
import { getDriverPrefix } from '../../../../../../../features/DataSource';
import { useInvalidateMetadata } from '../../../../../../../features/hasura-metadata-api';
import {
QualifiedFunction,
SupportedDrivers,
Table,
} from '../../../../../../../features/hasura-metadata-types';
import {
allowedMetadataTypes,
useMetadataMigration,
@ -13,12 +18,17 @@ type Configuration = {
function?: string;
};
custom_name?: string;
response?: {
table: Table;
type: string;
};
};
type OnSetFunctionCustomizationArgs = {
driver: Driver;
driver: SupportedDrivers;
dataSourceName: string;
functionName: string;
// the plain function name is used by native databases, the qualified function by GDC data sources
functionName: string | QualifiedFunction;
configuration: Configuration;
};
@ -29,8 +39,12 @@ type Props = {
export const useSetFunctionCustomization = ({ onSuccess, onError }: Props) => {
const dispatch = useAppDispatch();
const invalidateMetadata = useInvalidateMetadata();
const mutation = useMetadataMigration({
onSuccess: () => {
invalidateMetadata();
dispatch(updateSchemaInfo()).then(() => {
if (onSuccess) {
onSuccess();

View File

@ -1,10 +1,16 @@
import { useState } from 'react';
import { Button } from '../../../../new-components/Button';
import { QualifiedFunction } from '../../../hasura-metadata-types';
import {
QualifiedFunction,
SupportedDrivers,
} from '../../../hasura-metadata-types';
import { ModifyFunctionConfiguration } from './ModifyFunctionConfiguration';
import { IconTooltip } from '../../../../new-components/Tooltip';
import { FaEdit, FaQuestionCircle } from 'react-icons/fa';
import { FaEdit } from 'react-icons/fa';
import { DisplayConfigurationDetails } from './DisplayConfigurationDetails';
import { FunctionGraphQLCustomization } from '../../../../components/Services/Data/Function/Modify/GraphQLCustomization/FunctionGraphQLCustomization';
import { useMetadata } from '../../../hasura-metadata-api';
import Skeleton from 'react-loading-skeleton';
export type ModifyProps = {
dataSourceName: string;
@ -12,6 +18,12 @@ export type ModifyProps = {
};
export const Modify = (props: ModifyProps) => {
const { data: driverName, isFetching: isFetchingMetadata } = useMetadata(
m =>
m.metadata.sources.find(source => source.name === props.dataSourceName)
?.kind
);
const [isEditConfigurationModalOpen, setIsEditConfigurationModalOpen] =
useState(false);
@ -20,10 +32,7 @@ export const Modify = (props: ModifyProps) => {
<div className="w-full bg-white p-4 rounded-sm border my-2">
<div className="flex gap-2 mb-sm items-center">
<div className="font-semibold text-2xl">Configuration</div>
<IconTooltip
message="allows you to customize any given function with a custom name and custom root fields of an already tracked function. This will replace the already present customization."
icon={<FaQuestionCircle />}
/>
<IconTooltip message="allows you to customize any given function with a custom name and custom root fields of an already tracked function. This will replace the already present customization." />
</div>
<DisplayConfigurationDetails {...props} />
@ -42,6 +51,18 @@ export const Modify = (props: ModifyProps) => {
onClose={() => setIsEditConfigurationModalOpen(false)}
/>
)}
{isFetchingMetadata && <Skeleton width={80} height={60} />}
{!isFetchingMetadata && (
<div>
<FunctionGraphQLCustomization
driver={driverName as SupportedDrivers}
dataSourceName={props.dataSourceName}
qualifiedFunction={props.qualifiedFunction}
/>
</div>
)}
</div>
</div>
);