mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
Sync redux metadata with react-query and vice versa
[DSF-429]: https://hasurahq.atlassian.net/browse/DSF-429?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9565 GitOrigin-RevId: 6d53d39ebd445a17186233aa056ebe4d957c386b
This commit is contained in:
parent
d711392fb1
commit
b309fc9211
@ -175,4 +175,6 @@ export {
|
||||
removeLSItem,
|
||||
} from './lib/utils/localStorage';
|
||||
|
||||
export { listenForStoreMetadataChanges } from './lib/store.utils';
|
||||
|
||||
export { default as App } from './lib/components/App/App';
|
||||
|
@ -9,6 +9,7 @@ import { stripTrailingSlash } from './components/Common/utils/urlUtils';
|
||||
|
||||
import { SERVER_CONSOLE_MODE } from './constants';
|
||||
import { parseConsoleType, ConsoleType } from './utils/envUtils';
|
||||
import { QueryClient } from 'react-query';
|
||||
|
||||
export type LuxFeature =
|
||||
| 'DatadogIntegration'
|
||||
@ -179,6 +180,7 @@ export type EnvVars = {
|
||||
declare global {
|
||||
interface Window extends GlobalWindowHeap {
|
||||
__env: EnvVars;
|
||||
reactQueryClient: QueryClient;
|
||||
}
|
||||
const CONSOLE_ASSET_VERSION: string;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { useHttpClient } from '../Network';
|
||||
import { useCallback } from 'react';
|
||||
import { useQuery, useQueryClient } from 'react-query';
|
||||
import { APIError } from '../../hooks/error';
|
||||
import { useAppDispatch } from '../../storeHooks';
|
||||
|
||||
export const DEFAULT_STALE_TIME = 5 * 60000; // 5 minutes as default stale time
|
||||
|
||||
@ -39,11 +40,18 @@ export const useMetadata = <FinalResult = Metadata>(
|
||||
) => {
|
||||
const httpClient = useHttpClient();
|
||||
const invalidateMetadata = useInvalidateMetadata();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const queryReturn = useQuery<Metadata, APIError, FinalResult>({
|
||||
queryKey: [METADATA_QUERY_KEY],
|
||||
queryFn: async () => {
|
||||
const result = await exportMetadata({ httpClient });
|
||||
|
||||
dispatch({
|
||||
type: 'Metadata/EXPORT_METADATA_SUCCESS',
|
||||
data: result,
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
staleTime: options.staleTime,
|
||||
|
@ -4,6 +4,12 @@ import { ReactQueryDevtools } from 'react-query/devtools';
|
||||
|
||||
export const reactQueryClient = new QueryClient();
|
||||
|
||||
/**
|
||||
* This is needed by the redux store to trigger
|
||||
* invalidate queries when the metadata is updated in the store.
|
||||
*/
|
||||
window.reactQueryClient = reactQueryClient;
|
||||
|
||||
export const ReactQueryProvider: React.FC = ({ children }) => (
|
||||
<QueryClientProvider client={reactQueryClient}>
|
||||
{children}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MetadataActions } from './actions';
|
||||
import { ExportMetadataSuccess, MetadataActions } from './actions';
|
||||
import {
|
||||
HasuraMetadataV3,
|
||||
CollectionName,
|
||||
@ -99,30 +99,37 @@ const renameSourceAttributes = (sources: HasuraMetadataV3['sources']) =>
|
||||
return { ...s, tables };
|
||||
});
|
||||
|
||||
const updateMetadata = (
|
||||
action: ExportMetadataSuccess,
|
||||
state: MetadataState
|
||||
) => {
|
||||
const metadata =
|
||||
'metadata' in action.data ? action.data.metadata : action.data;
|
||||
return {
|
||||
...state,
|
||||
metadataObject: {
|
||||
...metadata,
|
||||
sources: renameSourceAttributes(metadata.sources),
|
||||
},
|
||||
resourceVersion:
|
||||
'resource_version' in action.data ? action.data.resource_version : 1,
|
||||
allowedQueries: setAllowedQueries(
|
||||
metadata?.query_collections,
|
||||
metadata?.allowlist
|
||||
),
|
||||
inheritedRoles: metadata?.inherited_roles,
|
||||
loading: false,
|
||||
error: null,
|
||||
};
|
||||
};
|
||||
|
||||
export const metadataReducer = (
|
||||
state = defaultState,
|
||||
action: MetadataActions
|
||||
): MetadataState => {
|
||||
switch (action.type) {
|
||||
case 'Metadata/EXPORT_METADATA_SUCCESS':
|
||||
const metadata =
|
||||
'metadata' in action.data ? action.data.metadata : action.data;
|
||||
return {
|
||||
...state,
|
||||
metadataObject: {
|
||||
...metadata,
|
||||
sources: renameSourceAttributes(metadata.sources),
|
||||
},
|
||||
resourceVersion:
|
||||
'resource_version' in action.data ? action.data.resource_version : 1,
|
||||
allowedQueries: setAllowedQueries(
|
||||
metadata?.query_collections,
|
||||
metadata?.allowlist
|
||||
),
|
||||
inheritedRoles: metadata?.inherited_roles,
|
||||
loading: false,
|
||||
error: null,
|
||||
};
|
||||
return updateMetadata(action, state);
|
||||
case 'Metadata/EXPORT_METADATA_REQUEST':
|
||||
return {
|
||||
...state,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
import { browserHistory } from 'react-router';
|
||||
import { listenForStoreMetadataChanges } from './store.utils';
|
||||
|
||||
// Since we only use it in dev, this warning doesn't make sense.
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
@ -24,6 +25,8 @@ export const store = configureStore({
|
||||
devTools: __DEVELOPMENT__,
|
||||
});
|
||||
|
||||
listenForStoreMetadataChanges(store);
|
||||
|
||||
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
|
20
frontend/libs/console/legacy-ce/src/lib/store.utils.ts
Normal file
20
frontend/libs/console/legacy-ce/src/lib/store.utils.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { ToolkitStore } from '@reduxjs/toolkit/dist/configureStore';
|
||||
|
||||
let previousStore: any = null;
|
||||
export const listenForStoreMetadataChanges = (store: ToolkitStore) => {
|
||||
store.subscribe(() => {
|
||||
if (!previousStore) {
|
||||
previousStore = store.getState();
|
||||
return;
|
||||
}
|
||||
const currentStore = store.getState();
|
||||
if (
|
||||
currentStore?.metadata?.resourceVersion >
|
||||
previousStore?.metadata?.resourceVersion
|
||||
) {
|
||||
window.reactQueryClient.invalidateQueries('export_metadata');
|
||||
}
|
||||
|
||||
previousStore = store.getState();
|
||||
});
|
||||
};
|
@ -2,6 +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 reducer from './reducer';
|
||||
|
||||
@ -26,4 +27,6 @@ if (__DEVELOPMENT__) {
|
||||
|
||||
const store = _finalCreateStore(reducer);
|
||||
|
||||
listenForStoreMetadataChanges(store);
|
||||
|
||||
export default store;
|
||||
|
Loading…
Reference in New Issue
Block a user