mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-09 03:32:54 -05:00
Fix react query cache not being cleared when switching budgets (#6953)
* Fix react query cache not being cleared when switching budgets * React does not want to export function from src/index * Release note
This commit is contained in:
committed by
GitHub
parent
155e4df219
commit
003efecc23
@@ -100,10 +100,11 @@ export const loadBudget = createAppAsyncThunk(
|
||||
|
||||
export const closeBudget = createAppAsyncThunk(
|
||||
`${sliceName}/closeBudget`,
|
||||
async (_, { dispatch, getState }) => {
|
||||
async (_, { dispatch, getState, extra: { queryClient } }) => {
|
||||
const prefs = getState().prefs.local;
|
||||
if (prefs && prefs.id) {
|
||||
await dispatch(resetApp());
|
||||
queryClient.clear();
|
||||
await dispatch(setAppState({ loadingText: t('Closing...') }));
|
||||
await send('close-budget');
|
||||
await dispatch(setAppState({ loadingText: null }));
|
||||
@@ -116,10 +117,11 @@ export const closeBudget = createAppAsyncThunk(
|
||||
|
||||
export const closeBudgetUI = createAppAsyncThunk(
|
||||
`${sliceName}/closeBudgetUI`,
|
||||
async (_, { dispatch, getState }) => {
|
||||
async (_, { dispatch, getState, extra: { queryClient } }) => {
|
||||
const prefs = getState().prefs.local;
|
||||
if (prefs && prefs.id) {
|
||||
await dispatch(resetApp());
|
||||
queryClient.clear();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { Change } from './Change';
|
||||
|
||||
import { configureAppStore } from '@desktop-client/redux/store';
|
||||
|
||||
const store = configureAppStore();
|
||||
import { TestProviders } from '@desktop-client/mocks';
|
||||
|
||||
describe('Change', () => {
|
||||
it('renders a positive amount with a plus sign and positive color', () => {
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<TestProviders>
|
||||
<Change amount={12345} />
|
||||
</Provider>,
|
||||
</TestProviders>,
|
||||
);
|
||||
const el = screen.getByText('+123.45');
|
||||
expect(el).toBeInTheDocument();
|
||||
@@ -24,9 +21,9 @@ describe('Change', () => {
|
||||
|
||||
it('renders zero with a plus sign and neutral color', () => {
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<TestProviders>
|
||||
<Change amount={0} />
|
||||
</Provider>,
|
||||
</TestProviders>,
|
||||
);
|
||||
const el = screen.getByText('+0.00');
|
||||
expect(el).toBeInTheDocument();
|
||||
@@ -35,9 +32,9 @@ describe('Change', () => {
|
||||
|
||||
it('renders a negative amount with a minus sign and negative color', () => {
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<TestProviders>
|
||||
<Change amount={-9876} />
|
||||
</Provider>,
|
||||
</TestProviders>,
|
||||
);
|
||||
const el = screen.getByText('-98.76');
|
||||
expect(el).toBeInTheDocument();
|
||||
@@ -46,9 +43,9 @@ describe('Change', () => {
|
||||
|
||||
it('merges custom style prop', () => {
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<TestProviders>
|
||||
<Change amount={1000} style={{ fontWeight: 'bold' }} />
|
||||
</Provider>,
|
||||
</TestProviders>,
|
||||
);
|
||||
const el = screen.getByText('+10.00');
|
||||
expect(el).toHaveStyle('font-weight: bold');
|
||||
|
||||
@@ -35,7 +35,7 @@ import * as usersSlice from './users/usersSlice';
|
||||
const queryClient = new QueryClient();
|
||||
window.__TANSTACK_QUERY_CLIENT__ = queryClient;
|
||||
|
||||
const store = configureAppStore();
|
||||
const store = configureAppStore({ queryClient });
|
||||
|
||||
const boundActions = bindActionCreators(
|
||||
{
|
||||
@@ -90,15 +90,15 @@ window.$q = q;
|
||||
const container = document.getElementById('root');
|
||||
const root = createRoot(container);
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<ServerProvider>
|
||||
<AuthProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Provider store={store}>
|
||||
<ServerProvider>
|
||||
<AuthProvider>
|
||||
<App />
|
||||
</QueryClientProvider>
|
||||
</AuthProvider>
|
||||
</ServerProvider>
|
||||
</Provider>,
|
||||
</AuthProvider>
|
||||
</ServerProvider>
|
||||
</Provider>
|
||||
</QueryClientProvider>,
|
||||
);
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -4,22 +4,37 @@ import { Provider } from 'react-redux';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
|
||||
import { configureAppStore } from './redux/store';
|
||||
import type { AppStore } from './redux/store';
|
||||
|
||||
let mockQueryClient = new QueryClient();
|
||||
let mockStore: AppStore = configureAppStore();
|
||||
export function createTestQueryClient() {
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function configureTestAppStore(
|
||||
...args: Parameters<typeof configureAppStore>
|
||||
) {
|
||||
return configureAppStore(...args);
|
||||
}
|
||||
|
||||
let testQueryClient = createTestQueryClient();
|
||||
let testStore = configureTestAppStore({
|
||||
queryClient: testQueryClient,
|
||||
});
|
||||
|
||||
export function resetTestProviders() {
|
||||
mockQueryClient = new QueryClient();
|
||||
mockStore = configureAppStore();
|
||||
testQueryClient = createTestQueryClient();
|
||||
testStore = configureTestAppStore({ queryClient: testQueryClient });
|
||||
}
|
||||
|
||||
export function TestProviders({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<Provider store={mockStore}>
|
||||
<QueryClientProvider client={mockQueryClient}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
<QueryClientProvider client={testQueryClient}>
|
||||
<Provider store={testStore}>{children}</Provider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,11 +7,12 @@ import {
|
||||
|
||||
import { createAsyncThunk } from '@reduxjs/toolkit';
|
||||
|
||||
import type { AppDispatch, AppStore, RootState } from './store';
|
||||
import type { AppDispatch, AppStore, ExtraArguments, RootState } from './store';
|
||||
|
||||
export const createAppAsyncThunk = createAsyncThunk.withTypes<{
|
||||
state: RootState;
|
||||
dispatch: AppDispatch;
|
||||
extra: ExtraArguments;
|
||||
}>();
|
||||
|
||||
export const useStore = useReduxStore.withTypes<AppStore>();
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
createListenerMiddleware,
|
||||
isRejected,
|
||||
} from '@reduxjs/toolkit';
|
||||
import type { QueryClient } from '@tanstack/react-query';
|
||||
|
||||
import {
|
||||
name as accountsSliceName,
|
||||
@@ -77,27 +78,28 @@ notifyOnRejectedActionsMiddleware.startListening({
|
||||
},
|
||||
});
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: rootReducer,
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware({
|
||||
// TODO: Fix this in a separate PR. Remove non-serializable states in the store.
|
||||
serializableCheck: false,
|
||||
}).prepend(notifyOnRejectedActionsMiddleware.middleware),
|
||||
});
|
||||
|
||||
export function configureAppStore() {
|
||||
export function configureAppStore({
|
||||
queryClient,
|
||||
}: {
|
||||
queryClient: QueryClient;
|
||||
}) {
|
||||
return configureStore({
|
||||
reducer: rootReducer,
|
||||
middleware: getDefaultMiddleware =>
|
||||
getDefaultMiddleware({
|
||||
// TODO: Fix this in a separate PR. Remove non-serializable states in the store.
|
||||
serializableCheck: false,
|
||||
thunk: {
|
||||
extraArgument: { queryClient } as ExtraArguments,
|
||||
},
|
||||
}).prepend(notifyOnRejectedActionsMiddleware.middleware),
|
||||
});
|
||||
}
|
||||
|
||||
export type AppStore = typeof store;
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
export type GetRootState = typeof store.getState;
|
||||
export type AppStore = ReturnType<typeof configureAppStore>;
|
||||
export type RootState = ReturnType<AppStore['getState']>;
|
||||
export type AppDispatch = AppStore['dispatch'];
|
||||
export type GetRootState = AppStore['getState'];
|
||||
export type ExtraArguments = {
|
||||
queryClient: QueryClient;
|
||||
};
|
||||
|
||||
6
upcoming-release-notes/6953.md
Normal file
6
upcoming-release-notes/6953.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Bugfixes
|
||||
authors: [joel-jeremy]
|
||||
---
|
||||
|
||||
Fix react query cache not being cleared when switching budgets
|
||||
Reference in New Issue
Block a user