mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 08:02:15 +03:00
console (refactor): remove redundant metadata invalidations
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9675 GitOrigin-RevId: 4a34f9f4ba09e8437824573dd3522fb4737a89d6
This commit is contained in:
parent
216f6a8f30
commit
f238e7a28a
@ -177,6 +177,6 @@ export {
|
||||
removeLSItem,
|
||||
} from './lib/utils/localStorage';
|
||||
|
||||
export { listenForStoreMetadataChanges } from './lib/store.utils';
|
||||
export { reduxStoreListener } from './lib/store/utils/';
|
||||
|
||||
export { default as App } from './lib/components/App/App';
|
||||
|
@ -1,14 +1,17 @@
|
||||
import { Dispatch } from '../../../../../../types';
|
||||
import {
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../../../../../features/hasura-metadata-api';
|
||||
import { reactQueryClient } from '../../../../../../lib/reactQuery';
|
||||
import { Dispatch } from '../../../../../../types';
|
||||
import _push from '../../../push';
|
||||
import { NeonBanner } from './components/Neon/NeonBanner';
|
||||
import { FETCH_NEON_PROJECTS_BY_PROJECTID_QUERYKEY } from './components/NeonDashboardLink';
|
||||
import { useNeonIntegration } from './useNeonIntegration';
|
||||
import {
|
||||
getNeonDBName,
|
||||
transformNeonIntegrationStatusToNeonBannerProps,
|
||||
} from './utils';
|
||||
import { useNeonIntegration } from './useNeonIntegration';
|
||||
import _push from '../../../push';
|
||||
import { FETCH_NEON_PROJECTS_BY_PROJECTID_QUERYKEY } from './components/NeonDashboardLink';
|
||||
import { useMetadata } from '../../../../../../features/hasura-metadata-api';
|
||||
|
||||
type NeonConnectProps = {
|
||||
dispatch: Dispatch;
|
||||
@ -19,7 +22,8 @@ export function NeonConnect({
|
||||
dispatch,
|
||||
connectDbUrl = '/data/manage/connect',
|
||||
}: NeonConnectProps) {
|
||||
const { data, invalidateMetadata } = useMetadata();
|
||||
const { data } = useMetadata();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
const allDatabases = data?.metadata.sources.map(source => source.name) ?? [];
|
||||
|
||||
// success callback
|
||||
@ -29,7 +33,10 @@ export function NeonConnect({
|
||||
reactQueryClient.refetchQueries(FETCH_NEON_PROJECTS_BY_PROJECTID_QUERYKEY);
|
||||
|
||||
// invalidate react query metadata on success
|
||||
invalidateMetadata();
|
||||
invalidateMetadata({
|
||||
componentName: 'NeonConnect',
|
||||
reasons: ['Successfully adding neon source.'],
|
||||
});
|
||||
|
||||
dispatch(_push(`/data/${dataSourceName}/schema/public`));
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { getDriverPrefix } from '../../../../../../../features/DataSource';
|
||||
import { useInvalidateMetadata } from '../../../../../../../features/hasura-metadata-api';
|
||||
import {
|
||||
QualifiedFunction,
|
||||
SupportedDrivers,
|
||||
@ -40,11 +39,8 @@ 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();
|
||||
|
@ -1,11 +1,10 @@
|
||||
import React from 'react';
|
||||
import { FaExclamationTriangle } from 'react-icons/fa';
|
||||
import { Source } from '../../../../../features/hasura-metadata-types';
|
||||
import { exportMetadata } from '../../../../../metadata/actions';
|
||||
import { Button } from '../../../../../new-components/Button';
|
||||
import { Tooltip } from '../../../../../new-components/Tooltip';
|
||||
import { Dispatch } from '../../../../../types';
|
||||
import React from 'react';
|
||||
import { FaExclamationTriangle } from 'react-icons/fa';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import _push from '../../push';
|
||||
import { isInconsistentSource } from '../../utils';
|
||||
import { useDropSource } from '../hooks/useDropSource';
|
||||
@ -17,16 +16,15 @@ type GDCDatabaseListItemItemProps = {
|
||||
dispatch: Dispatch;
|
||||
};
|
||||
|
||||
// This appears to be dead code that's not referenced or implemented anywhere:
|
||||
export const GDCDatabaseListItem: React.FC<GDCDatabaseListItemItemProps> = ({
|
||||
dataSource,
|
||||
inconsistentObjects,
|
||||
dispatch,
|
||||
}) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { dropSource, isLoading: isDropSourceInProgress } = useDropSource({
|
||||
customOnSuccess: () => {
|
||||
dispatch(exportMetadata());
|
||||
queryClient.invalidateQueries(['export_metadata']);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
import React, { useReducer } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { RemoteDBRelationship } from '../../../../../metadata/types';
|
||||
import { useReducer } from 'react';
|
||||
import { NormalizedTable } from '../../../../../dataSources/types';
|
||||
import { useInvalidateMetadata } from '../../../../../features/hasura-metadata-api';
|
||||
import { RemoteDBRelationship } from '../../../../../metadata/types';
|
||||
import { Dispatch } from '../../../../../types';
|
||||
import ExpandableEditor from '../../../../Common/Layout/ExpandableEditor/Editor';
|
||||
import { ordinalColSort } from '../../utils';
|
||||
import { addDbToDbRelationship, dropDbToDbRelationship } from '../Actions';
|
||||
import {
|
||||
relResetState,
|
||||
dbToDbRelDefaultState,
|
||||
dbToDbRelReducer,
|
||||
} from './state';
|
||||
import ExpandableEditor from '../../../../Common/Layout/ExpandableEditor/Editor';
|
||||
import ManualRelationshipSelector from './ManualRelationshipSelector';
|
||||
import { RemoteRelCollapsedLabel } from './RemoteRelCollapsedLabel';
|
||||
import {
|
||||
dbToDbRelDefaultState,
|
||||
dbToDbRelReducer,
|
||||
relResetState,
|
||||
} from './state';
|
||||
import { parseDbToDbRemoteRel } from './utils';
|
||||
|
||||
const AddManualRelationship = ({
|
||||
@ -32,7 +32,7 @@ const AddManualRelationship = ({
|
||||
);
|
||||
const columns = tableSchema.columns.sort(ordinalColSort);
|
||||
const isNew = relationship === null;
|
||||
const queryClient = useQueryClient();
|
||||
const invalidate = useInvalidateMetadata();
|
||||
|
||||
// columns in the right order with their indices
|
||||
const orderedColumns = columns.map((c, i) => ({
|
||||
@ -51,7 +51,10 @@ const AddManualRelationship = ({
|
||||
reduxDispatch(
|
||||
dropDbToDbRelationship(state, tableSchema, () => {
|
||||
toggleEditor();
|
||||
queryClient.refetchQueries(['metadata'], { active: true });
|
||||
invalidate({
|
||||
componentName: 'AddManualRelationship',
|
||||
reasons: ['Dropped db-to-db relationship'],
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -60,10 +63,12 @@ const AddManualRelationship = ({
|
||||
const saveFk = (toggleEditor: unknown) => {
|
||||
reduxDispatch(
|
||||
addDbToDbRelationship(state, tableSchema, toggleEditor, isNew, () => {
|
||||
queryClient.refetchQueries(['metadata'], { active: true });
|
||||
invalidate({
|
||||
componentName: 'AddManualRelationship',
|
||||
reasons: ['Added db-to-db relationship'],
|
||||
});
|
||||
})
|
||||
);
|
||||
// queryClient.refetchQueries(['metadata'], { active: true });
|
||||
};
|
||||
|
||||
const expandedContent = () => (
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { useDispatch, useStore } from 'react-redux';
|
||||
import { Link } from 'react-router';
|
||||
import {
|
||||
createActionMigration,
|
||||
deleteAction,
|
||||
executeActionCreation,
|
||||
} from '../../../../components/Services/Actions/ServerIO';
|
||||
import { Link } from 'react-router';
|
||||
import { useMetadata } from '../../../MetadataAPI';
|
||||
import { useDispatch, useStore } from 'react-redux';
|
||||
import { GeneratedAction } from './types';
|
||||
import { parseCustomTypes } from '../../../../shared/utils/hasuraCustomTypeUtils';
|
||||
import { useMetadata } from '../../../MetadataAPI';
|
||||
import { generatedActionToHasuraAction } from '../OASGenerator/utils';
|
||||
import { GeneratedAction } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import { FaAngleRight, FaFileImport, FaHome } from 'react-icons/fa';
|
||||
import { z } from 'zod';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { SimpleForm } from '../../../../new-components/Form';
|
||||
import { OasGeneratorForm } from './OASGeneratorForm';
|
||||
import React from 'react';
|
||||
import { useLocalStorage } from '../../../../hooks';
|
||||
import { SimpleForm } from '../../../../new-components/Form';
|
||||
import { useInvalidateMetadata } from '../../../hasura-metadata-api';
|
||||
import { OasGeneratorForm } from './OASGeneratorForm';
|
||||
|
||||
export const formSchema = z.object({
|
||||
oas: z.string(),
|
||||
@ -49,7 +49,7 @@ export const Breadcrumbs = () => (
|
||||
export const OASGeneratorPage = () => {
|
||||
const dispatch = useDispatch();
|
||||
const store = useStore();
|
||||
const queryClient = useQueryClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const [savedOas, setSavedOas] = useLocalStorage<string>('oas', '');
|
||||
|
||||
@ -77,7 +77,10 @@ export const OASGeneratorPage = () => {
|
||||
state,
|
||||
false,
|
||||
() => {
|
||||
queryClient.invalidateQueries(['metadata']);
|
||||
invalidateMetadata({
|
||||
componentName: 'OASGeneratorPage',
|
||||
reasons: ['onGenerate action migration occurred'],
|
||||
});
|
||||
setBusy(false);
|
||||
},
|
||||
() => {
|
||||
@ -99,7 +102,10 @@ export const OASGeneratorPage = () => {
|
||||
store.getState,
|
||||
false,
|
||||
() => {
|
||||
queryClient.invalidateQueries(['metadata']);
|
||||
invalidateMetadata({
|
||||
componentName: 'OASGeneratorPage',
|
||||
reasons: ['onDelete delete action occurred'],
|
||||
});
|
||||
setBusy(false);
|
||||
},
|
||||
() => {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { push } from 'react-router-redux';
|
||||
import { SupportedDrivers } from '../../hasura-metadata-types';
|
||||
import { allowedMetadataTypes, useMetadataMigration } from '../../MetadataAPI';
|
||||
import { APIError } from '../../../hooks/error';
|
||||
import { exportMetadata } from '../../../metadata/actions';
|
||||
import { useFireNotification } from '../../../new-components/Notifications';
|
||||
import { getDriverPrefix } from '../../DataSource';
|
||||
import { exportMetadata } from '../../../metadata/actions';
|
||||
import { allowedMetadataTypes, useMetadataMigration } from '../../MetadataAPI';
|
||||
import { SupportedDrivers } from '../../hasura-metadata-types';
|
||||
import { useAvailableDrivers } from './useAvailableDrivers';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
type UseRedirectArgs = {
|
||||
redirectWithLatencyCheck: boolean;
|
||||
@ -48,7 +48,6 @@ export const useSubmit = () => {
|
||||
const drivers = useAvailableDrivers();
|
||||
const { fireNotification } = useFireNotification();
|
||||
const redirect = useRedirect({ redirectWithLatencyCheck: false });
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
onError: (error: APIError) => {
|
||||
@ -59,8 +58,6 @@ export const useSubmit = () => {
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(['export_metadata']);
|
||||
|
||||
fireNotification({
|
||||
type: 'success',
|
||||
title: 'Success',
|
||||
|
@ -6,7 +6,6 @@ import Skeleton from 'react-loading-skeleton';
|
||||
import globals from '../../../../Globals';
|
||||
import _push from '../../../../components/Services/Data/push';
|
||||
import { exportMetadata } from '../../../../metadata/actions';
|
||||
import { MetadataDataSource } from '../../../../metadata/types';
|
||||
import { useDestructiveAlert } from '../../../../new-components/Alert';
|
||||
import { Button } from '../../../../new-components/Button';
|
||||
import { CardedTable } from '../../../../new-components/CardedTable';
|
||||
@ -14,7 +13,9 @@ import { IndicatorCard } from '../../../../new-components/IndicatorCard';
|
||||
import { hasuraToast } from '../../../../new-components/Toasts';
|
||||
import { useAppDispatch } from '../../../../storeHooks';
|
||||
import { getProjectId, isCloudConsole } from '../../../../utils/cloudConsole';
|
||||
import { useMetadata } from '../../../MetadataAPI';
|
||||
|
||||
import { useMetadata } from '../../../hasura-metadata-api';
|
||||
import { Source } from '../../../hasura-metadata-types';
|
||||
import { useDatabaseLatencyCheck } from '../../hooks/useDatabaseLatencyCheck';
|
||||
import { useDatabaseVersion } from '../../hooks/useDatabaseVersion';
|
||||
import { useDropSource } from '../../hooks/useDropSource';
|
||||
@ -25,8 +26,8 @@ import { Latency } from '../../types';
|
||||
import { AccelerateProject, Details, LatencyBadge } from './parts';
|
||||
|
||||
type DatabaseItem = {
|
||||
dataSourceName: MetadataDataSource['name'];
|
||||
driver: MetadataDataSource['kind'];
|
||||
dataSourceName: Source['name'];
|
||||
driver: Source['kind'];
|
||||
};
|
||||
|
||||
export const ListConnectedDatabases = (props?: { className?: string }) => {
|
||||
@ -88,7 +89,10 @@ export const ListConnectedDatabases = (props?: { className?: string }) => {
|
||||
!isFetching
|
||||
);
|
||||
|
||||
const isCurrentRow = (rowIndex: number) => rowIndex === activeRow;
|
||||
const isCurrentRow = React.useCallback(
|
||||
(rowIndex: number) => rowIndex === activeRow,
|
||||
[activeRow]
|
||||
);
|
||||
|
||||
const columns = ['database', 'driver', '', ''];
|
||||
|
||||
@ -128,7 +132,7 @@ export const ListConnectedDatabases = (props?: { className?: string }) => {
|
||||
},
|
||||
});
|
||||
},
|
||||
[dropSource]
|
||||
[destructivePrompt, dropSource]
|
||||
);
|
||||
|
||||
const rowData = React.useMemo(
|
||||
@ -193,6 +197,8 @@ export const ListConnectedDatabases = (props?: { className?: string }) => {
|
||||
[
|
||||
databaseList,
|
||||
databaseVersions,
|
||||
handleEdit,
|
||||
handleRemove,
|
||||
inconsistentSources,
|
||||
isCurrentRow,
|
||||
isDatabaseVersionLoading,
|
||||
@ -209,29 +215,32 @@ export const ListConnectedDatabases = (props?: { className?: string }) => {
|
||||
// isLoading: isUpdatingProjectRegion,
|
||||
} = useUpdateProjectRegion();
|
||||
|
||||
const openUpdateProjectRegionPage = React.useCallback((_rowId?: string) => {
|
||||
if (!_rowId) {
|
||||
hasuraToast({
|
||||
type: 'error',
|
||||
title: 'Could not fetch row Id to update!',
|
||||
message: 'Something went wrong',
|
||||
});
|
||||
return;
|
||||
}
|
||||
const openUpdateProjectRegionPage = React.useCallback(
|
||||
(_rowId?: string) => {
|
||||
if (!_rowId) {
|
||||
hasuraToast({
|
||||
type: 'error',
|
||||
title: 'Could not fetch row Id to update!',
|
||||
message: 'Something went wrong',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// update project region for the row Id
|
||||
updateProjectRegionForRowId(_rowId);
|
||||
// update project region for the row Id
|
||||
updateProjectRegionForRowId(_rowId);
|
||||
|
||||
// redirect to the cloud "change region for project page"
|
||||
// redirect to the cloud "change region for project page"
|
||||
|
||||
const projectId = getProjectId(globals);
|
||||
if (!projectId) {
|
||||
return;
|
||||
}
|
||||
const cloudDetailsPage = `${window.location.protocol}//${window.location.host}/project/${projectId}/details?open_update_region_drawer=true`;
|
||||
const projectId = getProjectId(globals);
|
||||
if (!projectId) {
|
||||
return;
|
||||
}
|
||||
const cloudDetailsPage = `${window.location.protocol}//${window.location.host}/project/${projectId}/details?open_update_region_drawer=true`;
|
||||
|
||||
window.open(cloudDetailsPage, '_blank');
|
||||
}, []);
|
||||
window.open(cloudDetailsPage, '_blank');
|
||||
},
|
||||
[updateProjectRegionForRowId]
|
||||
);
|
||||
|
||||
if (isLoading) return <>Loading...</>;
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
import { useInvalidateMetadata } from '../../hasura-metadata-api';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { hasuraToast } from '../../../new-components/Toasts';
|
||||
import { useCallback } from 'react';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { useAppDispatch } from '../../../storeHooks';
|
||||
import { UPDATE_CURRENT_DATA_SOURCE } from '../../../components/Services/Data/DataActions';
|
||||
import { hasuraToast } from '../../../new-components/Toasts';
|
||||
import { useAppDispatch } from '../../../storeHooks';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
|
||||
export const useDropSource = (props?: MetadataMigrationOptions) => {
|
||||
const { ...globalMutateOptions } = props;
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
onSuccess: (data, variables, ctx) => {
|
||||
hasuraToast({ type: 'success', title: 'Source dropped from metadata!' });
|
||||
invalidateMetadata();
|
||||
dispatch({
|
||||
type: UPDATE_CURRENT_DATA_SOURCE,
|
||||
source: '',
|
||||
|
@ -1,18 +1,16 @@
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { Driver } from '../../../dataSources';
|
||||
import { exportMetadata } from '../../../metadata/actions';
|
||||
import { useAppDispatch } from '../../../storeHooks';
|
||||
import { generateQueryKeys } from '../../DatabaseRelationships/utils/queryClientUtils';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useHttpClient } from '../../Network';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import { DatabaseConnection } from '../types';
|
||||
import { usePushRoute } from './usePushRoute';
|
||||
import {
|
||||
sendConnectDatabaseTelemetryEvent,
|
||||
transformErrorResponse,
|
||||
} from '../utils';
|
||||
import { useHttpClient } from '../../Network';
|
||||
import { Driver } from '../../../dataSources';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import { usePushRoute } from './usePushRoute';
|
||||
|
||||
export const useManageDatabaseConnection = ({
|
||||
onSuccess,
|
||||
@ -21,7 +19,6 @@ export const useManageDatabaseConnection = ({
|
||||
onSuccess?: () => void;
|
||||
onError?: (err: Error) => void;
|
||||
}) => {
|
||||
const queryClient = useQueryClient();
|
||||
const { mutateAsync, ...rest } = useMetadataMigration({
|
||||
errorTransform: transformErrorResponse,
|
||||
});
|
||||
@ -33,7 +30,6 @@ export const useManageDatabaseConnection = ({
|
||||
const mutationOptions = useMemo(
|
||||
() => ({
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(generateQueryKeys.metadata());
|
||||
onSuccess?.();
|
||||
|
||||
// this code is only for the demo
|
||||
@ -45,7 +41,7 @@ export const useManageDatabaseConnection = ({
|
||||
onError?.(err);
|
||||
},
|
||||
}),
|
||||
[dispatch, onError, onSuccess, push, queryClient]
|
||||
[dispatch, onError, onSuccess, push]
|
||||
);
|
||||
|
||||
const createConnection = useCallback(
|
||||
|
@ -1,15 +1,11 @@
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useInvalidateMetadata } from '../../hasura-metadata-api';
|
||||
import { hasuraToast } from '../../../new-components/Toasts';
|
||||
import { useCallback } from 'react';
|
||||
import { hasuraToast } from '../../../new-components/Toasts';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
|
||||
export const useReloadSource = () => {
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
onSuccess: () => {
|
||||
hasuraToast({ type: 'success', title: 'Reload successful!' });
|
||||
invalidateMetadata();
|
||||
},
|
||||
onError: () => {
|
||||
hasuraToast({ type: 'error', title: 'Failed to reload source.' });
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { InjectedRouter, Link, withRouter } from 'react-router';
|
||||
import { useDestructiveAlert } from '../../../../new-components/Alert';
|
||||
import { Button } from '../../../../new-components/Button';
|
||||
@ -8,22 +8,20 @@ import {
|
||||
useEnvironmentState,
|
||||
usePushRoute,
|
||||
} from '../../../ConnectDBRedesign/hooks';
|
||||
import {
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../../hasura-metadata-api';
|
||||
import { useMetadata } from '../../../hasura-metadata-api';
|
||||
import { useTrackLogicalModel } from '../../hooks/useTrackLogicalModel';
|
||||
import { useTrackNativeQuery } from '../../hooks/useTrackNativeQuery';
|
||||
import { LogicalModelWidget } from '../LogicalModelWidget/LogicalModelWidget';
|
||||
|
||||
import { LimitedFeatureWrapper } from '../../../ConnectDBRedesign/components/LimitedFeatureWrapper/LimitedFeatureWrapper';
|
||||
import { extractModelsAndQueriesFromMetadata } from '../../../hasura-metadata-api/selectors';
|
||||
import { useSyncResourceVersionOnMount } from '../../../hasura-metadata-api';
|
||||
import { RouteWrapper } from '../components/RouteWrapper';
|
||||
import { NATIVE_QUERY_ROUTES } from '../constants';
|
||||
import { LogicalModelWithSource, NativeQueryWithSource } from '../types';
|
||||
import { ListLogicalModels } from './components/ListLogicalModels';
|
||||
import { ListNativeQueries } from './components/ListNativeQueries';
|
||||
import { ListStoredProcedures } from './components/ListStoredProcedures';
|
||||
import { NATIVE_QUERY_ROUTES } from '../constants';
|
||||
import { extractModelsAndQueriesFromMetadata } from '../../../hasura-metadata-api/selectors';
|
||||
import { RouteWrapper } from '../components/RouteWrapper';
|
||||
import { LimitedFeatureWrapper } from '../../../ConnectDBRedesign/components/LimitedFeatureWrapper/LimitedFeatureWrapper';
|
||||
|
||||
export const LandingPage = ({ pathname }: { pathname: string }) => {
|
||||
const push = usePushRoute();
|
||||
@ -41,15 +39,7 @@ export const LandingPage = ({ pathname }: { pathname: string }) => {
|
||||
.flat()
|
||||
);
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
useEffect(() => {
|
||||
/**
|
||||
* Workaround to avoid that a metadata migration that happened in the legacy part of the Console (i.e. Run SQL)
|
||||
* might affect the metadata migrations in the child components of this page,
|
||||
* resulting in the error "metadata resource version referenced (x) did not match current version"
|
||||
*/
|
||||
invalidateMetadata();
|
||||
}, []);
|
||||
useSyncResourceVersionOnMount({ componentName: 'LandingPage' });
|
||||
|
||||
const nativeQueries = data?.queries ?? [];
|
||||
const logicalModels = data?.models ?? [];
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useMetadataMigration } from '../../../../MetadataAPI';
|
||||
import { exportMetadata } from '../../../../DataSource';
|
||||
import { useHttpClient } from '../../../../Network';
|
||||
import { getCreateLogicalModelBody } from './utils/getCreateLogicalModelBody';
|
||||
import { LogicalModel, Source } from '../../../../hasura-metadata-types';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useFireNotification } from '../../../../../new-components/Notifications/index';
|
||||
import { METADATA_QUERY_KEY } from '../../../../hasura-metadata-api/useMetadata';
|
||||
import { exportMetadata } from '../../../../DataSource';
|
||||
import { useMetadataMigration } from '../../../../MetadataAPI';
|
||||
import { useHttpClient } from '../../../../Network';
|
||||
import { LogicalModel, Source } from '../../../../hasura-metadata-types';
|
||||
import { errorTransform } from './utils/errorTransform';
|
||||
import { getCreateLogicalModelBody } from './utils/getCreateLogicalModelBody';
|
||||
|
||||
const useCreateLogicalModelsPermissions = ({
|
||||
logicalModels,
|
||||
@ -21,7 +19,6 @@ const useCreateLogicalModelsPermissions = ({
|
||||
});
|
||||
const { fireNotification } = useFireNotification();
|
||||
const httpClient = useHttpClient();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const create = useCallback(
|
||||
async ({ permission, logicalModelName, onSuccess }) => {
|
||||
@ -60,7 +57,6 @@ const useCreateLogicalModelsPermissions = ({
|
||||
});
|
||||
},
|
||||
onSettled: async () => {
|
||||
await queryClient.invalidateQueries([METADATA_QUERY_KEY]);
|
||||
onSuccess?.();
|
||||
},
|
||||
}
|
||||
|
@ -1,13 +1,11 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useMetadataMigration } from '../../../../MetadataAPI';
|
||||
import { useFireNotification } from '../../../../../new-components/Notifications/index';
|
||||
import { exportMetadata } from '../../../../DataSource';
|
||||
import { useMetadataMigration } from '../../../../MetadataAPI';
|
||||
import { useHttpClient } from '../../../../Network';
|
||||
import { LogicalModel, Source } from '../../../../hasura-metadata-types';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useFireNotification } from '../../../../../new-components/Notifications/index';
|
||||
import { METADATA_QUERY_KEY } from '../../../../hasura-metadata-api/useMetadata';
|
||||
import { errorTransform } from './utils/errorTransform';
|
||||
import { Permission } from '../components/types';
|
||||
import { errorTransform } from './utils/errorTransform';
|
||||
import { getDeleteLogicalModelBody } from './utils/getDeleteLogicalModelBody';
|
||||
|
||||
const useRemoveLogicalModelsPermissions = ({
|
||||
@ -22,7 +20,6 @@ const useRemoveLogicalModelsPermissions = ({
|
||||
});
|
||||
const { fireNotification } = useFireNotification();
|
||||
const httpClient = useHttpClient();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const remove = useCallback(
|
||||
async ({
|
||||
@ -68,7 +65,6 @@ const useRemoveLogicalModelsPermissions = ({
|
||||
});
|
||||
},
|
||||
onSettled: async () => {
|
||||
await queryClient.invalidateQueries([METADATA_QUERY_KEY]);
|
||||
onSuccess?.();
|
||||
},
|
||||
}
|
||||
|
@ -1,17 +1,13 @@
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../../hasura-metadata-api';
|
||||
import { Table } from '../../../hasura-metadata-types';
|
||||
import { useMetadataMigration } from '../../../MetadataAPI';
|
||||
import { useMetadata } from '../../../hasura-metadata-api';
|
||||
import { Table } from '../../../hasura-metadata-types';
|
||||
|
||||
export const useUntrackTable = (props?: {
|
||||
onSuccess?: () => void;
|
||||
onError?: (err: Error) => void;
|
||||
}) => {
|
||||
const { mutate, ...rest } = useMetadataMigration();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { onSuccess, onError } = props ?? {};
|
||||
|
||||
@ -37,7 +33,6 @@ export const useUntrackTable = (props?: {
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
invalidateMetadata();
|
||||
onSuccess?.();
|
||||
},
|
||||
onError: err => {
|
||||
|
@ -1,12 +1,8 @@
|
||||
import {
|
||||
MetadataUtils,
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../../hasura-metadata-api';
|
||||
import { MetadataTable } from '../../../hasura-metadata-types';
|
||||
import { useMetadataMigration } from '../../../MetadataAPI';
|
||||
import { useFireNotification } from '../../../../new-components/Notifications';
|
||||
import { useCallback } from 'react';
|
||||
import { useFireNotification } from '../../../../new-components/Notifications';
|
||||
import { useMetadataMigration } from '../../../MetadataAPI';
|
||||
import { MetadataUtils, useMetadata } from '../../../hasura-metadata-api';
|
||||
import { MetadataTable } from '../../../hasura-metadata-types';
|
||||
|
||||
export const useUpdateTableConfiguration = (
|
||||
dataSourceName: string,
|
||||
@ -16,8 +12,6 @@ export const useUpdateTableConfiguration = (
|
||||
|
||||
const { fireNotification } = useFireNotification();
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { data } = useMetadata(m => ({
|
||||
source: MetadataUtils.findMetadataSource(dataSourceName, m),
|
||||
resource_version: m.resource_version,
|
||||
@ -52,8 +46,6 @@ export const useUpdateTableConfiguration = (
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
invalidateMetadata();
|
||||
|
||||
fireNotification({
|
||||
type: 'success',
|
||||
title: 'Success!',
|
||||
@ -77,7 +69,6 @@ export const useUpdateTableConfiguration = (
|
||||
dataSourceName,
|
||||
fireNotification,
|
||||
mutate,
|
||||
invalidateMetadata,
|
||||
metadataTable,
|
||||
resource_version,
|
||||
source,
|
||||
|
@ -118,7 +118,14 @@ export const TrackedFunctions = (props: TrackedFunctionsProps) => {
|
||||
[
|
||||
<span
|
||||
className="py-2"
|
||||
onClick={() => invalidateMetadata()}
|
||||
onClick={() =>
|
||||
invalidateMetadata({
|
||||
componentName: 'TrackedFunctions',
|
||||
reasons: [
|
||||
'Refreshing tracked functions on dropdown menu item click.',
|
||||
],
|
||||
})
|
||||
}
|
||||
>
|
||||
Refresh
|
||||
</span>,
|
||||
|
@ -163,7 +163,14 @@ export const UntrackedFunctions = (props: UntrackedFunctionsProps) => {
|
||||
[
|
||||
<span
|
||||
className="py-2"
|
||||
onClick={() => invalidateMetadata()}
|
||||
onClick={() =>
|
||||
invalidateMetadata({
|
||||
componentName: 'UntrackedFunctions',
|
||||
reasons: [
|
||||
'Refreshing untracked functions on Dropdown Menu item click.',
|
||||
],
|
||||
})
|
||||
}
|
||||
>
|
||||
Refresh
|
||||
</span>,
|
||||
|
@ -1,38 +1,35 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
||||
import Skeleton from 'react-loading-skeleton';
|
||||
import { APIError } from '../../../../hooks/error';
|
||||
import { Badge } from '../../../../new-components/Badge';
|
||||
import { Button } from '../../../../new-components/Button';
|
||||
import { CardedTable } from '../../../../new-components/CardedTable';
|
||||
import { IndicatorCard } from '../../../../new-components/IndicatorCard';
|
||||
import { useFireNotification } from '../../../../new-components/Notifications';
|
||||
import { hasuraToast } from '../../../../new-components/Toasts';
|
||||
import { exportMetadata } from '../../../DataSource';
|
||||
import { RelationshipMapping } from '../../../DatabaseRelationships/components/AvailableRelationshipsList/parts/RelationshipMapping';
|
||||
import { RowActions } from '../../../DatabaseRelationships/components/AvailableRelationshipsList/parts/RowActions';
|
||||
import { TargetName } from '../../../DatabaseRelationships/components/AvailableRelationshipsList/parts/TargetName';
|
||||
import { RenderWidget } from '../../../DatabaseRelationships/components/RenderWidget/RenderWidget';
|
||||
import { NOTIFICATIONS } from '../../../DatabaseRelationships/components/constants';
|
||||
import { useCheckRows } from '../../../DatabaseRelationships/hooks/useCheckRows';
|
||||
import { MODE, Relationship } from '../../../DatabaseRelationships/types';
|
||||
import {
|
||||
generateDeleteLocalRelationshipRequest,
|
||||
generateRemoteRelationshipDeleteRequest,
|
||||
} from '../../../DatabaseRelationships/utils/generateRequest';
|
||||
import { useMetadataMigration } from '../../../MetadataAPI';
|
||||
import { useHttpClient } from '../../../Network';
|
||||
import { BulkKeepGoingResponse, Source } from '../../../hasura-metadata-types';
|
||||
import {
|
||||
DEFAULT_PAGE_NUMBER,
|
||||
DEFAULT_PAGE_SIZE,
|
||||
DEFAULT_PAGE_SIZES,
|
||||
} from '../constants';
|
||||
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
|
||||
import { paginate } from '../utils';
|
||||
import { SearchBar } from './SearchBar';
|
||||
import { Badge } from '../../../../new-components/Badge';
|
||||
import { hasuraToast } from '../../../../new-components/Toasts';
|
||||
import { TargetName } from '../../../DatabaseRelationships/components/AvailableRelationshipsList/parts/TargetName';
|
||||
import { RelationshipMapping } from '../../../DatabaseRelationships/components/AvailableRelationshipsList/parts/RelationshipMapping';
|
||||
import { RowActions } from '../../../DatabaseRelationships/components/AvailableRelationshipsList/parts/RowActions';
|
||||
import { MODE, Relationship } from '../../../DatabaseRelationships/types';
|
||||
import { RenderWidget } from '../../../DatabaseRelationships/components/RenderWidget/RenderWidget';
|
||||
import { NOTIFICATIONS } from '../../../DatabaseRelationships/components/constants';
|
||||
import { useFireNotification } from '../../../../new-components/Notifications';
|
||||
import { useMetadataMigration } from '../../../MetadataAPI';
|
||||
import {
|
||||
generateDeleteLocalRelationshipRequest,
|
||||
generateRemoteRelationshipDeleteRequest,
|
||||
} from '../../../DatabaseRelationships/utils/generateRequest';
|
||||
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 { generateQueryKeys } from '../../../DatabaseRelationships/utils/queryClientUtils';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useCheckRows } from '../../../DatabaseRelationships/hooks/useCheckRows';
|
||||
import { APIError } from '../../../../hooks/error';
|
||||
import { BulkKeepGoingResponse } from '../../../hasura-metadata-types';
|
||||
|
||||
const getQueryFunction = (relationship: Relationship) => {
|
||||
if (relationship.type === 'localRelationship') {
|
||||
@ -58,7 +55,7 @@ type RelationshipAction = {
|
||||
|
||||
interface TrackedRelationshipsProps {
|
||||
dataSourceName: string;
|
||||
driver?: MetadataDataSource['kind'];
|
||||
driver?: Source['kind'];
|
||||
isLoading: boolean;
|
||||
onUpdate: () => void;
|
||||
relationships: Relationship[];
|
||||
@ -73,7 +70,6 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
|
||||
}) => {
|
||||
const httpClient = useHttpClient();
|
||||
const { mutateAsync } = useMetadataMigration<BulkKeepGoingResponse>();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [isTrackingSelectedRelationships, setTrackingSelectedRelationships] =
|
||||
useState(false);
|
||||
@ -161,6 +157,8 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
|
||||
).length;
|
||||
const plural = successfullyTrackedCounter > 1 ? 's' : '';
|
||||
|
||||
onUpdate();
|
||||
|
||||
hasuraToast({
|
||||
type: 'success',
|
||||
title: 'Successfully untracked',
|
||||
@ -174,13 +172,8 @@ export const TrackedRelationships: React.VFC<TrackedRelationshipsProps> = ({
|
||||
message: (err as APIError).message,
|
||||
});
|
||||
},
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries(generateQueryKeys.metadata());
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
onUpdate();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
@ -1,18 +1,12 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTrackedRelationships } from './hooks/useTrackedRelationships';
|
||||
import { useInvalidateMetadata } from '../../../hasura-metadata-api';
|
||||
import { useMetadata } from '../../../MetadataAPI';
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
MetadataSelectors,
|
||||
useMetadata,
|
||||
useSyncResourceVersionOnMount,
|
||||
} from '../../../hasura-metadata-api';
|
||||
import { TrackedRelationships } from './TrackedRelationships';
|
||||
|
||||
const useInvalidateMetadataOnLoad = () => {
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
// just invalidate metadata when this screen loads for the first time
|
||||
// why? because the user might be coming from a redux based paged and the resource_version might gone out of sync
|
||||
useEffect(() => {
|
||||
invalidateMetadata();
|
||||
}, [invalidateMetadata]);
|
||||
};
|
||||
import { useTrackedRelationships } from './hooks/useTrackedRelationships';
|
||||
|
||||
interface TrackedRelationshipsContainerProps {
|
||||
dataSourceName: string;
|
||||
@ -21,7 +15,9 @@ interface TrackedRelationshipsContainerProps {
|
||||
export const TrackedRelationshipsContainer: React.VFC<
|
||||
TrackedRelationshipsContainerProps
|
||||
> = ({ dataSourceName }) => {
|
||||
useInvalidateMetadataOnLoad();
|
||||
useSyncResourceVersionOnMount({
|
||||
componentName: 'TrackedRelationshipsContainer',
|
||||
});
|
||||
|
||||
const {
|
||||
data: relationships,
|
||||
@ -29,18 +25,9 @@ export const TrackedRelationshipsContainer: React.VFC<
|
||||
refetchRelationships,
|
||||
} = useTrackedRelationships(dataSourceName);
|
||||
|
||||
const {
|
||||
data: metadataDataSource,
|
||||
refetch: refetchMetadata,
|
||||
isLoading: isLoadingMetadata,
|
||||
} = useMetadata(m => {
|
||||
return {
|
||||
resource_version: m.resource_version,
|
||||
source: m.metadata.sources.find(s => s.name === dataSourceName),
|
||||
};
|
||||
});
|
||||
const metadataSource = metadataDataSource?.source;
|
||||
const driver = metadataSource?.kind;
|
||||
const { data: metadataSource, isLoading: isLoadingMetadata } = useMetadata(
|
||||
MetadataSelectors.findSource(dataSourceName)
|
||||
);
|
||||
|
||||
return (
|
||||
<TrackedRelationships
|
||||
@ -49,9 +36,8 @@ export const TrackedRelationshipsContainer: React.VFC<
|
||||
relationships={relationships}
|
||||
onUpdate={async () => {
|
||||
await refetchRelationships();
|
||||
await refetchMetadata();
|
||||
}}
|
||||
driver={driver}
|
||||
driver={metadataSource?.kind}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { useQuery } from 'react-query';
|
||||
import { useAllSuggestedRelationships } from '../../../../DatabaseRelationships/components/SuggestedRelationships/hooks/useAllSuggestedRelationships';
|
||||
import { getTableLocalRelationships } from '../../../../DatabaseRelationships/utils/tableRelationships';
|
||||
import { exportMetadata } from '../../../../hasura-metadata-api';
|
||||
import { useHttpClient } from '../../../../Network';
|
||||
import {
|
||||
MetadataSelectors,
|
||||
useMetadata,
|
||||
} from '../../../../hasura-metadata-api';
|
||||
|
||||
export const getTrackedRelationshipsCacheKey = (dataSourceName: string) => [
|
||||
'tracked_relationships',
|
||||
@ -10,21 +12,16 @@ export const getTrackedRelationshipsCacheKey = (dataSourceName: string) => [
|
||||
];
|
||||
|
||||
export const useTrackedRelationships = (dataSourceName: string) => {
|
||||
const httpClient = useHttpClient();
|
||||
const { suggestedRelationships } = useAllSuggestedRelationships({
|
||||
dataSourceName,
|
||||
isEnabled: true,
|
||||
omitTracked: false,
|
||||
});
|
||||
const { data: currentMetadataSource } = useMetadata(
|
||||
MetadataSelectors.findSource(dataSourceName)
|
||||
);
|
||||
|
||||
const fetchLocalRelationships = async () => {
|
||||
const { metadata } = await exportMetadata({
|
||||
httpClient,
|
||||
});
|
||||
const currentMetadataSource = metadata?.sources?.find(
|
||||
source => source.name === dataSourceName
|
||||
);
|
||||
|
||||
const metadataTables = currentMetadataSource?.tables || [];
|
||||
|
||||
const _tableRelationships = [];
|
||||
|
@ -1,3 +1,2 @@
|
||||
export { useCheckRows } from './useCheckRows';
|
||||
export { useMetadataSource } from './useMetadataSource';
|
||||
export { usePaginatedSearchableList } from './usePaginatedSearchableList';
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { exportMetadata } from '../../../DataSource';
|
||||
import { useHttpClient } from '../../../Network';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
export const useMetadataSource = (dataSourceName: string) => {
|
||||
const httpClient = useHttpClient();
|
||||
return useQuery(
|
||||
['export_metadata', 'trackTables', 'metadataSource'],
|
||||
async () => {
|
||||
const result = await exportMetadata({ httpClient });
|
||||
|
||||
if (!result) throw Error('useMetadataSource: cannot export metadata');
|
||||
|
||||
const driver = result.metadata.sources.find(
|
||||
source => source.name === dataSourceName
|
||||
)?.kind;
|
||||
|
||||
if (!driver)
|
||||
throw Error('useMetadataSource: cannot find source in metadata');
|
||||
|
||||
return { metadata: result, driver };
|
||||
}
|
||||
);
|
||||
};
|
@ -1,8 +1,4 @@
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
MetadataFunction,
|
||||
QualifiedFunction,
|
||||
} from '../../hasura-metadata-types';
|
||||
import {
|
||||
MetadataMigrationOptions,
|
||||
useMetadataMigration,
|
||||
@ -10,9 +6,12 @@ import {
|
||||
import {
|
||||
MetadataSelectors,
|
||||
areTablesEqual,
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../hasura-metadata-api';
|
||||
import {
|
||||
MetadataFunction,
|
||||
QualifiedFunction,
|
||||
} from '../../hasura-metadata-types';
|
||||
import { transformErrorResponse } from '../errorUtils';
|
||||
|
||||
export type MetadataFunctionPayload = {
|
||||
@ -26,12 +25,9 @@ export const useSetFunctionConfiguration = ({
|
||||
dataSourceName,
|
||||
...globalMutateOptions
|
||||
}: { dataSourceName: string } & MetadataMigrationOptions) => {
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
...globalMutateOptions,
|
||||
onSuccess: (data, variables, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variables, ctx);
|
||||
},
|
||||
errorTransform: transformErrorResponse,
|
||||
|
@ -1,17 +1,13 @@
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
MetadataFunction,
|
||||
QualifiedFunction,
|
||||
} from '../../hasura-metadata-types';
|
||||
import {
|
||||
MetadataMigrationOptions,
|
||||
useMetadataMigration,
|
||||
} from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { MetadataSelectors, useMetadata } from '../../hasura-metadata-api';
|
||||
import {
|
||||
MetadataSelectors,
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../hasura-metadata-api';
|
||||
MetadataFunction,
|
||||
QualifiedFunction,
|
||||
} from '../../hasura-metadata-types';
|
||||
import { transformErrorResponse } from '../errorUtils';
|
||||
|
||||
export type MetadataFunctionPayload = {
|
||||
@ -25,12 +21,9 @@ export const useTrackFunction = ({
|
||||
dataSourceName,
|
||||
...globalMutateOptions
|
||||
}: { dataSourceName: string } & MetadataMigrationOptions) => {
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
...globalMutateOptions,
|
||||
onSuccess: (data, variables, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variables, ctx);
|
||||
},
|
||||
errorTransform: transformErrorResponse,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { transformErrorResponse } from '../../ConnectDBRedesign/utils';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { useInvalidateMetadata, useMetadata } from '../../hasura-metadata-api';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import { LogicalModel } from '../../hasura-metadata-types';
|
||||
import { getSourceDriver } from './utils';
|
||||
|
||||
@ -20,13 +20,10 @@ export const useTrackLogicalModel = (
|
||||
resource_version: m.resource_version,
|
||||
}));
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
...globalMutateOptions,
|
||||
errorTransform: transformErrorResponse,
|
||||
onSuccess: (data, variable, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variable, ctx);
|
||||
},
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { transformErrorResponse } from '../../ConnectDBRedesign/utils';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { useInvalidateMetadata, useMetadata } from '../../hasura-metadata-api';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import { NativeQuery, Source } from '../../hasura-metadata-types';
|
||||
import { getSourceDriver } from './utils';
|
||||
|
||||
@ -25,13 +25,10 @@ export const useTrackNativeQuery = (
|
||||
resource_version: m.resource_version,
|
||||
}));
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
...globalMutateOptions,
|
||||
errorTransform: transformErrorResponse,
|
||||
onSuccess: (data, variable, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variable, ctx);
|
||||
},
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { transformErrorResponse } from '../../ConnectDBRedesign/utils';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { useInvalidateMetadata, useMetadata } from '../../hasura-metadata-api';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import {
|
||||
QualifiedStoredProcedure,
|
||||
StoredProcedure,
|
||||
@ -23,13 +23,10 @@ export const useTrackStoredProcedure = (
|
||||
resource_version: m.resource_version,
|
||||
}));
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration({
|
||||
...globalMutateOptions,
|
||||
errorTransform: transformErrorResponse,
|
||||
onSuccess: (data, variable, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variable, ctx);
|
||||
},
|
||||
});
|
||||
|
@ -1,14 +1,10 @@
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
MetadataSelectors,
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../hasura-metadata-api';
|
||||
import type { TrackableTable } from '../TrackResources/types';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { transformErrorResponse } from '../../ConnectDBRedesign/utils';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { MetadataMigrationOptions } from '../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import { MetadataSelectors, useMetadata } from '../../hasura-metadata-api';
|
||||
import { BulkKeepGoingResponse } from '../../hasura-metadata-types';
|
||||
import type { TrackableTable } from '../TrackResources/types';
|
||||
|
||||
export const useTrackTables = ({
|
||||
dataSourceName,
|
||||
@ -19,12 +15,9 @@ export const useTrackTables = ({
|
||||
resource_version: m.resource_version,
|
||||
}));
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { mutate, ...rest } = useMetadataMigration<BulkKeepGoingResponse>({
|
||||
...globalMutateOptions,
|
||||
onSuccess: (data, variables, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variables, ctx);
|
||||
},
|
||||
errorTransform: transformErrorResponse,
|
||||
|
@ -2,7 +2,6 @@ export * from './ManageDatabase/ManageDatabase.Route';
|
||||
export * from './components';
|
||||
export * from './hooks';
|
||||
export { useTrackTables } from './hooks/useTrackTables';
|
||||
export { useMetadataSource } from './TrackResources/hooks/useMetadataSource';
|
||||
export * from './CustomFieldNames';
|
||||
export * from '../../utils/getDataRoute';
|
||||
export * from './mocks/metadata.mocks';
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Table } from '../hasura-metadata-types';
|
||||
import { useState } from 'react';
|
||||
import { FaPlusCircle } from 'react-icons/fa';
|
||||
import { Button } from '../../new-components/Button';
|
||||
import { useFireNotification } from '../../new-components/Notifications';
|
||||
import { FaPlusCircle } from 'react-icons/fa';
|
||||
import Legend from './components/Legend';
|
||||
import { SuggestedRelationships } from './components/SuggestedRelationships/SuggestedRelationships';
|
||||
import { MODE, Relationship } from './types';
|
||||
import { useSyncResourceVersionOnMount } from '../hasura-metadata-api';
|
||||
import { Table } from '../hasura-metadata-types';
|
||||
import { AvailableRelationshipsList } from './components/AvailableRelationshipsList/AvailableRelationshipsList';
|
||||
import { NOTIFICATIONS } from './components/constants';
|
||||
import Legend from './components/Legend';
|
||||
import { RenderWidget } from './components/RenderWidget/RenderWidget';
|
||||
import { useInvalidateMetadata } from '../hasura-metadata-api';
|
||||
import { SuggestedRelationships } from './components/SuggestedRelationships/SuggestedRelationships';
|
||||
import { NOTIFICATIONS } from './components/constants';
|
||||
import { MODE, Relationship } from './types';
|
||||
|
||||
export interface DatabaseRelationshipsProps {
|
||||
dataSourceName: string;
|
||||
@ -29,8 +29,6 @@ export const DatabaseRelationships = ({
|
||||
});
|
||||
const { fireNotification } = useFireNotification();
|
||||
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const onCancel = () => {
|
||||
setTabState({
|
||||
mode: undefined,
|
||||
@ -38,11 +36,9 @@ export const DatabaseRelationships = ({
|
||||
});
|
||||
};
|
||||
|
||||
// just invalidate metadata when this screen loads for the first time
|
||||
// why? because the user might be coming from a redux based paged and the resource_version might gone out of sync
|
||||
useEffect(() => {
|
||||
invalidateMetadata();
|
||||
}, [invalidateMetadata]);
|
||||
useSyncResourceVersionOnMount({
|
||||
componentName: 'DatabaseRelationships',
|
||||
});
|
||||
|
||||
const onError = (err: Error) => {
|
||||
if (mode)
|
||||
|
@ -1,13 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Table } from '../../../hasura-metadata-types';
|
||||
import { CardedTable } from '../../../../new-components/CardedTable';
|
||||
import { IndicatorCard } from '../../../../new-components/IndicatorCard';
|
||||
import { FiRefreshCcw } from 'react-icons/fi';
|
||||
import Skeleton from 'react-loading-skeleton';
|
||||
import { QueryClient, useQueryClient } from 'react-query';
|
||||
import { CardedTable } from '../../../../new-components/CardedTable';
|
||||
import { IndicatorCard } from '../../../../new-components/IndicatorCard';
|
||||
import { useInvalidateMetadata } from '../../../hasura-metadata-api';
|
||||
import { Table } from '../../../hasura-metadata-types';
|
||||
import { useListAllDatabaseRelationships } from '../../hooks/useListAllDatabaseRelationships';
|
||||
import { MODE, Relationship } from '../../types';
|
||||
import { generateQueryKeys } from '../../utils/queryClientUtils';
|
||||
import { RelationshipMapping } from './parts/RelationshipMapping';
|
||||
import { RowActions } from './parts/RowActions';
|
||||
import { TargetName } from './parts/TargetName';
|
||||
@ -18,10 +16,6 @@ export interface AvailableRelationshipsListProps {
|
||||
table: Table;
|
||||
}
|
||||
|
||||
const refreshMetadata = (client: QueryClient) => {
|
||||
client.invalidateQueries(generateQueryKeys.metadata());
|
||||
};
|
||||
|
||||
export const AvailableRelationshipsList = ({
|
||||
dataSourceName,
|
||||
onAction,
|
||||
@ -32,7 +26,14 @@ export const AvailableRelationshipsList = ({
|
||||
table,
|
||||
});
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const refreshMetadata = () => {
|
||||
invalidateMetadata({
|
||||
componentName: 'AvailableRelationshipList',
|
||||
reasons: ['User clicked button to refresh metadata.'],
|
||||
});
|
||||
};
|
||||
|
||||
if (!relationships) return <Skeleton count={7} height={30} />;
|
||||
|
||||
@ -55,7 +56,7 @@ export const AvailableRelationshipsList = ({
|
||||
'TYPE',
|
||||
'RELATIONSHIP',
|
||||
<div className="flex justify-end hidden">
|
||||
<FiRefreshCcw onClick={() => refreshMetadata(queryClient)} />
|
||||
<FiRefreshCcw onClick={() => refreshMetadata()} />
|
||||
</div>,
|
||||
]}
|
||||
/>
|
||||
|
@ -5,19 +5,12 @@ import { transformErrorResponse } from '../../../Data/errorUtils';
|
||||
// useAllDriverCapabilities,
|
||||
// useDriverCapabilities,
|
||||
// } from '../../../Data/hooks/useDriverCapabilities';
|
||||
import { useAllDriverCapabilities } from '../../../Data/hooks/useAllDriverCapabilities';
|
||||
import { Feature } from '../../../DataSource';
|
||||
import { useMetadataMigration } from '../../../MetadataAPI';
|
||||
import { MetadataMigrationOptions } from '../../../MetadataAPI/hooks/useMetadataMigration';
|
||||
import {
|
||||
areTablesEqual,
|
||||
useInvalidateMetadata,
|
||||
useMetadata,
|
||||
} from '../../../hasura-metadata-api';
|
||||
import {
|
||||
createTableRelationshipRequestBody,
|
||||
deleteTableRelationshipRequestBody,
|
||||
renameRelationshipRequestBody,
|
||||
} from './utils';
|
||||
import { areTablesEqual, useMetadata } from '../../../hasura-metadata-api';
|
||||
import { Table } from '../../../hasura-metadata-types';
|
||||
import {
|
||||
DeleteRelationshipProps,
|
||||
LocalTableRelationshipDefinition,
|
||||
@ -26,8 +19,11 @@ import {
|
||||
RenameRelationshipProps,
|
||||
TableRelationshipBasicDetails,
|
||||
} from './types';
|
||||
import { Table } from '../../../hasura-metadata-types';
|
||||
import { useAllDriverCapabilities } from '../../../Data/hooks/useAllDriverCapabilities';
|
||||
import {
|
||||
createTableRelationshipRequestBody,
|
||||
deleteTableRelationshipRequestBody,
|
||||
renameRelationshipRequestBody,
|
||||
} from './utils';
|
||||
|
||||
type AllowedRelationshipDefinitions =
|
||||
| Omit<LocalTableRelationshipDefinition, 'capabilities'>
|
||||
@ -66,8 +62,6 @@ export const useCreateTableRelationships = (
|
||||
dataSourceName: string,
|
||||
globalMutateOptions?: MetadataMigrationOptions
|
||||
) => {
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
// get these capabilities
|
||||
|
||||
const { data: driverCapabilties = [] } = useAllDriverCapabilities({
|
||||
@ -152,7 +146,6 @@ export const useCreateTableRelationships = (
|
||||
...globalMutateOptions,
|
||||
errorTransform: transformErrorResponse,
|
||||
onSuccess: (data, variable, ctx) => {
|
||||
invalidateMetadata();
|
||||
globalMutateOptions?.onSuccess?.(data, variable, ctx);
|
||||
},
|
||||
});
|
||||
|
@ -34,8 +34,6 @@ export const useManageLocalRelationship = ({
|
||||
const mutationOptions = useMemo(
|
||||
() => ({
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(generateQueryKeys.metadata());
|
||||
|
||||
queryClient.invalidateQueries(
|
||||
generateQueryKeys.suggestedRelationships({ dataSourceName, table })
|
||||
);
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import { RemoteDatabaseRelationship } from '../types';
|
||||
import {
|
||||
generateRemoteRelationshipCreateRequest,
|
||||
generateRemoteRelationshipEditRequest,
|
||||
generateRemoteRelationshipDeleteRequest,
|
||||
generateRemoteRelationshipEditRequest,
|
||||
} from '../utils/generateRequest';
|
||||
import { generateQueryKeys } from '../utils/queryClientUtils';
|
||||
|
||||
export const useManageRemoteDatabaseRelationship = ({
|
||||
dataSourceName,
|
||||
@ -31,7 +30,6 @@ export const useManageRemoteDatabaseRelationship = ({
|
||||
const mutationOptions = useMemo(
|
||||
() => ({
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(generateQueryKeys.metadata());
|
||||
onSuccess?.();
|
||||
},
|
||||
onError: (err: Error) => {
|
||||
|
@ -1,14 +1,13 @@
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { useMetadataMigration } from '../../MetadataAPI';
|
||||
import { useMetadata } from '../../hasura-metadata-api';
|
||||
import { RemoteSchemaRelationship } from '../types';
|
||||
import {
|
||||
generateRemoteRelationshipCreateRequest,
|
||||
generateRemoteRelationshipEditRequest,
|
||||
generateRemoteRelationshipDeleteRequest,
|
||||
generateRemoteRelationshipEditRequest,
|
||||
} from '../utils/generateRequest';
|
||||
import { generateQueryKeys } from '../utils/queryClientUtils';
|
||||
|
||||
export const useManageRemoteSchemaRelationship = ({
|
||||
dataSourceName,
|
||||
@ -31,7 +30,6 @@ export const useManageRemoteSchemaRelationship = ({
|
||||
const mutationOptions = useMemo(
|
||||
() => ({
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(generateQueryKeys.metadata());
|
||||
onSuccess?.();
|
||||
},
|
||||
onError: (err: Error) => {
|
||||
|
@ -11,7 +11,6 @@ interface ManyTablesParams {
|
||||
}
|
||||
|
||||
export const generateQueryKeys = {
|
||||
metadata: () => ['export_metadata'],
|
||||
fkConstraints: (params: BaseParams) =>
|
||||
[
|
||||
'dal-introspection',
|
||||
|
@ -3,12 +3,34 @@ import { Api } from '../../../hooks/apiUtils';
|
||||
import { useQuery, UseQueryOptions, UseQueryResult } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import type { MetadataResponse } from '../types';
|
||||
import {
|
||||
METADATA_QUERY_KEY,
|
||||
MetadataQueryKey,
|
||||
} from '../../hasura-metadata-api/useMetadata';
|
||||
|
||||
// overloads
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
* this metadata library function is no longer recommended.
|
||||
* Please use the `useMetadata` from the features/hasura-metadata-api
|
||||
*/
|
||||
export function useMetadata(): UseQueryResult<MetadataResponse, Error>;
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
* this metadta library function is no longer recommended.
|
||||
* Please use the `useMetadata` from the features/hasura-metadata-api
|
||||
*/
|
||||
export function useMetadata<T extends (d: MetadataResponse) => any>(
|
||||
select: T
|
||||
): UseQueryResult<ReturnType<T>, Error>;
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
* this metadta library function is no longer recommended.
|
||||
* Please use the `useMetadata` from the features/hasura-metadata-api
|
||||
*/
|
||||
export function useMetadata<
|
||||
T extends (d: MetadataResponse) => any,
|
||||
D extends (d: ReturnType<T>) => any
|
||||
@ -16,16 +38,21 @@ export function useMetadata<
|
||||
select: T,
|
||||
transformFn: D,
|
||||
queryOptions?: Omit<
|
||||
UseQueryOptions<MetadataResponse, Error, ReturnType<T>, 'metadata'>,
|
||||
UseQueryOptions<MetadataResponse, Error, ReturnType<T>, MetadataQueryKey>,
|
||||
'queryKey' | 'queryFn'
|
||||
>
|
||||
): UseQueryResult<ReturnType<D>, Error>;
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated
|
||||
* this metadta library function is no longer recommended.
|
||||
* Please use the `useMetadata` from the features/hasura-metadata-api
|
||||
*/
|
||||
export function useMetadata(
|
||||
select = (d: MetadataResponse) => d,
|
||||
transformFn = (d: unknown) => d,
|
||||
queryOptions?: Omit<
|
||||
UseQueryOptions<MetadataResponse, Error, unknown, 'metadata'>,
|
||||
UseQueryOptions<MetadataResponse, Error, unknown, MetadataQueryKey>,
|
||||
'queryKey' | 'queryFn'
|
||||
>
|
||||
) {
|
||||
@ -49,7 +76,7 @@ export function useMetadata(
|
||||
};
|
||||
|
||||
return useQuery({
|
||||
queryKey: 'metadata',
|
||||
queryKey: METADATA_QUERY_KEY,
|
||||
queryFn,
|
||||
...queryOptions,
|
||||
select: d => transformFn(select(d)),
|
||||
|
@ -5,6 +5,7 @@ import Endpoints from '../../../Endpoints';
|
||||
import { Api } from '../../../hooks/apiUtils';
|
||||
import { useConsoleConfig } from '../../../hooks/useEnvVars';
|
||||
import { allowedMetadataTypes, MetadataResponse } from '../types';
|
||||
import { useInvalidateMetadata } from '../../hasura-metadata-api';
|
||||
|
||||
const maxAllowedLength = 255;
|
||||
const unixEpochLength = 14;
|
||||
@ -46,7 +47,8 @@ export function useMetadataMigration<
|
||||
metadataMigrationOptions: MetadataMigrationOptions<
|
||||
ResponseType,
|
||||
ArgsType
|
||||
> = {}
|
||||
> = {},
|
||||
additionalQueryKeysToInvalidate?: string[]
|
||||
) {
|
||||
const { errorTransform, ...mutationOptions } = metadataMigrationOptions;
|
||||
|
||||
@ -57,11 +59,14 @@ export function useMetadataMigration<
|
||||
string
|
||||
>;
|
||||
const queryClient = useQueryClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
let lastBody: any = null;
|
||||
|
||||
return useMutation(
|
||||
async props => {
|
||||
const { query } = props;
|
||||
const body = query;
|
||||
lastBody = body;
|
||||
const result = await Api.post<ResponseType>(
|
||||
{
|
||||
url: Endpoints.metadata,
|
||||
@ -94,10 +99,20 @@ export function useMetadataMigration<
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Get the latest metadata from server (this will NOT update metadata that is in the redux state, to do that please pass a custom onSuccess)
|
||||
*/
|
||||
queryClient.refetchQueries(['metadata'], { active: true });
|
||||
invalidateMetadata({
|
||||
componentName: 'useMetadataMigration()',
|
||||
reasons: [
|
||||
'Metadata migration occurred',
|
||||
`Migration Type: ${lastBody.type}`,
|
||||
`Migration Body:`,
|
||||
JSON.stringify(lastBody, null, 2),
|
||||
],
|
||||
additionalQueryKeys:
|
||||
additionalQueryKeysToInvalidate &&
|
||||
additionalQueryKeysToInvalidate?.length > 0
|
||||
? additionalQueryKeysToInvalidate
|
||||
: undefined,
|
||||
});
|
||||
|
||||
const { onSuccess } = mutationOptions ?? {};
|
||||
if (onSuccess) {
|
||||
|
@ -1,9 +1,8 @@
|
||||
import type { SetOpenTelemetryQuery } from '../../../hasura-metadata-types';
|
||||
|
||||
import { useMetadataVersion, useMetadataMigration } from '../../../MetadataAPI';
|
||||
import { useMetadataMigration, useMetadataVersion } from '../../../MetadataAPI';
|
||||
|
||||
import { useFireNotification } from '../../../../new-components/Notifications';
|
||||
import { useInvalidateMetadata } from '../../../hasura-metadata-api';
|
||||
|
||||
import type { FormValues } from '../../OpenTelemetry/components/Form/schema';
|
||||
|
||||
@ -22,7 +21,6 @@ function errorTransform(error: unknown) {
|
||||
export function useSetOpenTelemetry() {
|
||||
const mutation = useMetadataMigration({ errorTransform });
|
||||
const { data: version } = useMetadataVersion();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const { fireNotification } = useFireNotification();
|
||||
|
||||
@ -45,7 +43,6 @@ export function useSetOpenTelemetry() {
|
||||
{
|
||||
onSuccess: () => {
|
||||
resolve();
|
||||
invalidateMetadata();
|
||||
|
||||
fireNotification({
|
||||
title: 'Success!',
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { useQueryClient } from 'react-query';
|
||||
import { AxiosInstance } from 'axios';
|
||||
import { useQueryClient } from 'react-query';
|
||||
|
||||
import { useMetadataMigration } from '../../../../MetadataAPI';
|
||||
import { exportMetadata } from '../../../../DataSource';
|
||||
import { useHttpClient } from '../../../../Network';
|
||||
import { useFireNotification } from '../../../../../new-components/Notifications';
|
||||
import { AccessType, QueryType } from '../../../types';
|
||||
import { api } from '../../api';
|
||||
import { isPermission, keyToPermission } from '../../../utils';
|
||||
import { PermissionsSchema } from '../../../schema';
|
||||
import { exportMetadata } from '../../../../DataSource';
|
||||
import { useMetadataMigration } from '../../../../MetadataAPI';
|
||||
import { useHttpClient } from '../../../../Network';
|
||||
import { Table } from '../../../../hasura-metadata-types';
|
||||
import { PermissionsSchema } from '../../../schema';
|
||||
import { AccessType, QueryType } from '../../../types';
|
||||
import { isPermission, keyToPermission } from '../../../utils';
|
||||
import { api } from '../../api';
|
||||
|
||||
export interface UseSubmitFormArgs {
|
||||
dataSourceName: string;
|
||||
@ -68,11 +68,12 @@ export const useSubmitForm = (args: UseSubmitFormArgs) => {
|
||||
args;
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const httpClient = useHttpClient();
|
||||
|
||||
const { fireNotification } = useFireNotification();
|
||||
|
||||
const mutate = useMetadataMigration();
|
||||
const mutate = useMetadataMigration(undefined, ['roles']);
|
||||
|
||||
const submit = async (formData: PermissionsSchema) => {
|
||||
const { metadata, resource_version } = await exportMetadata({
|
||||
@ -129,7 +130,6 @@ export const useSubmitForm = (args: UseSubmitFormArgs) => {
|
||||
});
|
||||
},
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries(['export_metadata', 'roles']);
|
||||
queryClient.invalidateQueries([
|
||||
dataSourceName,
|
||||
'permissionFormData',
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { useMutation } from 'react-query';
|
||||
import Endpoints from '../../../../Endpoints';
|
||||
import { Api } from '../../../../hooks/apiUtils';
|
||||
import { useAppSelector } from '../../../../storeHooks';
|
||||
import { useMutation, useQueryClient } from 'react-query';
|
||||
import { useInvalidateMetadata } from '../../../hasura-metadata-api';
|
||||
|
||||
export const useAddRemoteSchemaRelationship = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
const headers = useAppSelector(state => state.tables.dataHeaders);
|
||||
|
||||
return useMutation(
|
||||
@ -19,13 +20,16 @@ export const useAddRemoteSchemaRelationship = () => {
|
||||
}),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.refetchQueries(['metadata'], { active: true });
|
||||
invalidateMetadata({
|
||||
componentName: 'useAddRemoteSchemaRelationship',
|
||||
reasons: ['added a remote schema relationship'],
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
export const useDropRemoteSchemaRelationship = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
const headers = useAppSelector(state => state.tables.dataHeaders);
|
||||
|
||||
return useMutation(
|
||||
@ -40,7 +44,10 @@ export const useDropRemoteSchemaRelationship = () => {
|
||||
}),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.refetchQueries(['metadata'], { active: true });
|
||||
invalidateMetadata({
|
||||
componentName: 'useDropRemoteSchemaRelationship',
|
||||
reasons: ['dropped a remote schema relationship'],
|
||||
});
|
||||
},
|
||||
onError: () => {},
|
||||
}
|
||||
@ -48,7 +55,7 @@ export const useDropRemoteSchemaRelationship = () => {
|
||||
};
|
||||
|
||||
export const useUpdateRemoteSchemaRelationship = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
const headers = useAppSelector(state => state.tables.dataHeaders);
|
||||
|
||||
return useMutation(
|
||||
@ -63,7 +70,10 @@ export const useUpdateRemoteSchemaRelationship = () => {
|
||||
}),
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.refetchQueries(['metadata'], { active: true });
|
||||
invalidateMetadata({
|
||||
componentName: 'useUpdateRemoteSchemaRelationship',
|
||||
reasons: ['updated a remote schema relationship'],
|
||||
});
|
||||
},
|
||||
onError: () => {},
|
||||
}
|
||||
|
@ -4,7 +4,10 @@ export {
|
||||
useInconsistentMetadata,
|
||||
useInvalidateInconsistentMetadata,
|
||||
} from './useInconsistentMetadata';
|
||||
export { useMetadata, useInvalidateMetadata } from './useMetadata';
|
||||
export { useMetadata } from './useMetadata';
|
||||
export type { MetadataQueryKey } from './useMetadata';
|
||||
export { useInvalidateMetadata } from './useInvalidateMetadata';
|
||||
export { useSyncResourceVersionOnMount } from './useSyncResourceVersionOnMount';
|
||||
export { areTablesEqual } from './areTablesEqual';
|
||||
export { MetadataSelectors };
|
||||
export { MetadataUtils };
|
||||
|
@ -0,0 +1,16 @@
|
||||
import { Metadata } from '../hasura-metadata-types';
|
||||
import { reactQueryClient } from '../../lib/reactQuery';
|
||||
import { METADATA_QUERY_KEY } from './useMetadata';
|
||||
|
||||
/**
|
||||
*
|
||||
* You only want to use these in helper libraries, and not in React Components.
|
||||
*
|
||||
* NEVER use these in React Components as it could produce unexpected results.
|
||||
*
|
||||
*/
|
||||
export const MetadataHelpers = {
|
||||
getQueryData: () =>
|
||||
reactQueryClient.getQueryData<Metadata>(METADATA_QUERY_KEY),
|
||||
invalidate: () => reactQueryClient.invalidateQueries(METADATA_QUERY_KEY),
|
||||
};
|
@ -0,0 +1,40 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useQueryClient } from 'react-query';
|
||||
import globals from '../../Globals';
|
||||
import { METADATA_QUERY_KEY } from './useMetadata';
|
||||
|
||||
export type LogMetadataInvalidationProps = {
|
||||
componentName: string;
|
||||
reasons: string[];
|
||||
};
|
||||
|
||||
export const logMetadataInvalidation = ({
|
||||
componentName,
|
||||
reasons,
|
||||
}: LogMetadataInvalidationProps) => {
|
||||
if (!globals.isProduction) {
|
||||
const logLabel = 'Invalidating Metadata...';
|
||||
console.groupCollapsed(logLabel);
|
||||
console.info(`Component: ${componentName}`);
|
||||
console.info(`Reasons:`);
|
||||
reasons.forEach(reason => console.info(`\t${reason}`));
|
||||
console.groupEnd();
|
||||
}
|
||||
};
|
||||
|
||||
export const useInvalidateMetadata = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const invalidate = useCallback(
|
||||
(
|
||||
props: LogMetadataInvalidationProps & { additionalQueryKeys?: string[] }
|
||||
) => {
|
||||
logMetadataInvalidation(props);
|
||||
queryClient.invalidateQueries([
|
||||
METADATA_QUERY_KEY,
|
||||
...(props?.additionalQueryKeys ?? []),
|
||||
]);
|
||||
},
|
||||
[queryClient]
|
||||
);
|
||||
return invalidate;
|
||||
};
|
@ -1,10 +1,10 @@
|
||||
import { exportMetadata } from './exportMetadata';
|
||||
import { Metadata } from '../hasura-metadata-types';
|
||||
import { useHttpClient } from '../Network';
|
||||
import { useCallback } from 'react';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
import { useQuery } from 'react-query';
|
||||
import { APIError } from '../../hooks/error';
|
||||
import { useAppDispatch } from '../../storeHooks';
|
||||
import { useHttpClient } from '../Network';
|
||||
import { Metadata } from '../hasura-metadata-types';
|
||||
import { exportMetadata } from './exportMetadata';
|
||||
import { getCurrentReduxResourceVersion } from '../../store/utils/';
|
||||
|
||||
export const DEFAULT_STALE_TIME = 5 * 60000; // 5 minutes as default stale time
|
||||
|
||||
@ -14,17 +14,9 @@ export const DEFAULT_STALE_TIME = 5 * 60000; // 5 minutes as default stale time
|
||||
Default stale time is 5 minutes, but can be adjusted using the staleTime arg
|
||||
*/
|
||||
|
||||
export const METADATA_QUERY_KEY = 'export_metadata';
|
||||
export type MetadataQueryKey = 'export_metadata';
|
||||
|
||||
export const useInvalidateMetadata = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const invalidate = useCallback(
|
||||
() => queryClient.invalidateQueries([METADATA_QUERY_KEY]),
|
||||
[queryClient]
|
||||
);
|
||||
|
||||
return invalidate;
|
||||
};
|
||||
export const METADATA_QUERY_KEY: MetadataQueryKey = 'export_metadata';
|
||||
|
||||
type Options = {
|
||||
staleTime?: number;
|
||||
@ -39,7 +31,7 @@ export const useMetadata = <FinalResult = Metadata>(
|
||||
}
|
||||
) => {
|
||||
const httpClient = useHttpClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const queryReturn = useQuery<Metadata, APIError, FinalResult>({
|
||||
@ -47,10 +39,12 @@ export const useMetadata = <FinalResult = Metadata>(
|
||||
queryFn: async () => {
|
||||
const result = await exportMetadata({ httpClient });
|
||||
|
||||
dispatch({
|
||||
type: 'Metadata/EXPORT_METADATA_SUCCESS',
|
||||
data: result,
|
||||
});
|
||||
if (result.resource_version !== getCurrentReduxResourceVersion()) {
|
||||
dispatch({
|
||||
type: 'Metadata/EXPORT_METADATA_SUCCESS',
|
||||
data: result,
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
@ -62,6 +56,5 @@ export const useMetadata = <FinalResult = Metadata>(
|
||||
|
||||
return {
|
||||
...queryReturn,
|
||||
invalidateMetadata,
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,41 @@
|
||||
import { useEffect } from 'react';
|
||||
import { getCurrentReduxResourceVersion } from '../../store/utils';
|
||||
import { useInvalidateMetadata } from './useInvalidateMetadata';
|
||||
import { useMetadata } from './useMetadata';
|
||||
|
||||
/**
|
||||
*
|
||||
* This hook checks if the react-query resource_version is out of sync with the redux store on component mount
|
||||
* If it is, it performs a react-query invalidation of the metadata key and logs the action.
|
||||
*
|
||||
*/
|
||||
export const useSyncResourceVersionOnMount = ({
|
||||
componentName,
|
||||
}: {
|
||||
componentName: string;
|
||||
}) => {
|
||||
const { data: reactQueryResourceVersion } = useMetadata(
|
||||
m => m.resource_version
|
||||
);
|
||||
|
||||
const reduxResourceVersion = getCurrentReduxResourceVersion();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
reduxResourceVersion &&
|
||||
reactQueryResourceVersion &&
|
||||
reduxResourceVersion > reactQueryResourceVersion
|
||||
) {
|
||||
invalidateMetadata({
|
||||
componentName,
|
||||
reasons: [
|
||||
`(useSyncResourceVersionOnMount)`,
|
||||
`Resource versions detected to be out of sync on component mount...`,
|
||||
`redux: ${reduxResourceVersion}`,
|
||||
`react-query: ${reactQueryResourceVersion}`,
|
||||
],
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
import { browserHistory } from 'react-router';
|
||||
import { listenForStoreMetadataChanges } from './store.utils';
|
||||
import { reduxStoreListener } from './store/utils/';
|
||||
|
||||
// Since we only use it in dev, this warning doesn't make sense.
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
@ -25,7 +25,7 @@ export const store = configureStore({
|
||||
devTools: __DEVELOPMENT__,
|
||||
});
|
||||
|
||||
listenForStoreMetadataChanges(store);
|
||||
reduxStoreListener(store);
|
||||
|
||||
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
|
@ -1,47 +0,0 @@
|
||||
import { ToolkitStore } from '@reduxjs/toolkit/dist/configureStore';
|
||||
import { reactQueryClient } from './lib/reactQuery';
|
||||
import { Metadata } from './features/hasura-metadata-types';
|
||||
import { METADATA_QUERY_KEY } from './features/hasura-metadata-api/useMetadata';
|
||||
|
||||
export const listenForStoreMetadataChanges = (store: ToolkitStore) => {
|
||||
let previousStore: any = null;
|
||||
|
||||
store.subscribe(() => {
|
||||
if (!previousStore || previousStore?.metadata?.metadataObject == null) {
|
||||
previousStore = store.getState();
|
||||
return;
|
||||
}
|
||||
|
||||
const currentStore = store.getState();
|
||||
|
||||
const reactQueryResourceVersion =
|
||||
reactQueryClient.getQueryData<Metadata>(
|
||||
METADATA_QUERY_KEY
|
||||
)?.resource_version;
|
||||
|
||||
if (
|
||||
currentStore?.metadata?.resourceVersion >
|
||||
previousStore?.metadata?.resourceVersion &&
|
||||
currentStore?.metadata?.resourceVersion !== reactQueryResourceVersion
|
||||
) {
|
||||
console.groupCollapsed(
|
||||
'Metadata change occurred in redux, and is no longer in sync with react-query:'
|
||||
);
|
||||
|
||||
console.info(
|
||||
`current redux store rv: ${currentStore?.metadata?.resourceVersion}`
|
||||
);
|
||||
console.info(
|
||||
`previous redux store rv: ${previousStore?.metadata?.resourceVersion}`
|
||||
);
|
||||
console.info(`react query rv: ${reactQueryResourceVersion}`);
|
||||
console.info(
|
||||
`Triggering react-query invalidation of query key: ${METADATA_QUERY_KEY}`
|
||||
);
|
||||
console.groupEnd();
|
||||
reactQueryClient.invalidateQueries(METADATA_QUERY_KEY);
|
||||
}
|
||||
|
||||
previousStore = currentStore;
|
||||
});
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
export { reduxStoreListener } from './reduxStoreListener';
|
||||
export { getCurrentReduxResourceVersion } from './store-change-handlers/currentReduxResourceVersion';
|
@ -0,0 +1,10 @@
|
||||
import { updateReduxResourceVersion } from './store-change-handlers/currentReduxResourceVersion';
|
||||
import { syncResourceVersions } from './store-change-handlers/syncResourceVersions';
|
||||
|
||||
export type OnStoreChangeProps = { currentStore: any; previousStore: any };
|
||||
|
||||
export const onStoreChange = (props: OnStoreChangeProps) => {
|
||||
// execute functions here....
|
||||
syncResourceVersions(props);
|
||||
updateReduxResourceVersion(props);
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
import { ToolkitStore } from '@reduxjs/toolkit/dist/configureStore';
|
||||
import { onStoreChange } from './onStoreChange';
|
||||
|
||||
// listens for any redux store changes:
|
||||
export const reduxStoreListener = (store: ToolkitStore) => {
|
||||
let previousStore: any = null;
|
||||
|
||||
store.subscribe(() => {
|
||||
if (!previousStore) {
|
||||
previousStore = store.getState();
|
||||
return;
|
||||
}
|
||||
|
||||
const currentStore = store.getState();
|
||||
|
||||
// execute code on store change:
|
||||
onStoreChange({ currentStore, previousStore });
|
||||
|
||||
previousStore = currentStore;
|
||||
});
|
||||
};
|
@ -0,0 +1,19 @@
|
||||
import type { OnStoreChangeProps } from '../onStoreChange';
|
||||
|
||||
// private module variable
|
||||
let CURRENT_REDUX_RESOURCE_VERSION = 0;
|
||||
|
||||
/**
|
||||
* Public exported function to read private variable
|
||||
*
|
||||
* This is intended to get the current resourceVersion from redux. Will NOT react to new changes so don't use it as a reactive value
|
||||
*/
|
||||
export const getCurrentReduxResourceVersion = () => {
|
||||
return CURRENT_REDUX_RESOURCE_VERSION;
|
||||
};
|
||||
|
||||
export const updateReduxResourceVersion = ({
|
||||
currentStore,
|
||||
}: OnStoreChangeProps) => {
|
||||
CURRENT_REDUX_RESOURCE_VERSION = currentStore?.metadata?.resourceVersion;
|
||||
};
|
@ -0,0 +1,40 @@
|
||||
import { MetadataHelpers } from '../../../features/hasura-metadata-api/metadataHelpers';
|
||||
import { logMetadataInvalidation } from '../../../features/hasura-metadata-api/useInvalidateMetadata';
|
||||
import { OnStoreChangeProps } from '../onStoreChange';
|
||||
|
||||
export const syncResourceVersions = ({
|
||||
currentStore,
|
||||
previousStore,
|
||||
}: OnStoreChangeProps) => {
|
||||
if (previousStore.metadata?.metadataObject == null) {
|
||||
// if this is true, then no actual metadata change occurred.
|
||||
// metadata just changed from default state to initial actual metadata
|
||||
return;
|
||||
}
|
||||
|
||||
const redux = {
|
||||
previousResourceVersion: previousStore?.metadata?.resourceVersion,
|
||||
resourceVersion: currentStore?.metadata?.resourceVersion,
|
||||
};
|
||||
const reactQueryResourceVersion =
|
||||
MetadataHelpers.getQueryData()?.resource_version ?? 0;
|
||||
|
||||
if (
|
||||
redux.resourceVersion > redux.previousResourceVersion &&
|
||||
redux.resourceVersion > reactQueryResourceVersion
|
||||
) {
|
||||
// log the invalidation:
|
||||
logMetadataInvalidation({
|
||||
componentName: 'syncResourceVersions() in reduxStoreListener()',
|
||||
reasons: [
|
||||
`Inconsistent resourse version detected between redux and react-query after redux changes:`,
|
||||
`previous redux version: ${redux.previousResourceVersion}`,
|
||||
`current redux version: ${redux.resourceVersion}`,
|
||||
`current react-query version: ${reactQueryResourceVersion}`,
|
||||
],
|
||||
});
|
||||
|
||||
// invalidate react-query's metadata key:
|
||||
MetadataHelpers.invalidate();
|
||||
}
|
||||
};
|
@ -2,7 +2,7 @@ import { compose, createStore, applyMiddleware } from 'redux';
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
import { browserHistory } from 'react-router';
|
||||
import thunk from 'redux-thunk';
|
||||
import { listenForStoreMetadataChanges } from '@hasura/console-legacy-ce';
|
||||
import { reduxStoreListener } from '@hasura/console-legacy-ce';
|
||||
|
||||
import reducer from './reducer';
|
||||
|
||||
@ -27,6 +27,6 @@ if (__DEVELOPMENT__) {
|
||||
|
||||
const store = _finalCreateStore(reducer);
|
||||
|
||||
listenForStoreMetadataChanges(store);
|
||||
reduxStoreListener(store);
|
||||
|
||||
export default store;
|
||||
|
Loading…
Reference in New Issue
Block a user