Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Redux Toolkit Migration] Use new Redux Toolkit configureStore API #4000

Merged
merged 13 commits into from
Jan 8, 2025

Conversation

joel-jeremy
Copy link
Contributor

@joel-jeremy joel-jeremy commented Dec 17, 2024

Initial migration to redux-toolkit. This PR focuses on retrofitting the existing reducers to the newer redux toolkit APIs. We can work on converting them to redux slices in a future PR.

Aside from converting to the usage of typed useAppDispatcher and useAppSelector, I had to do some changes to the SET_LAST_UNDO_STATE and SET_LAST_SPLIT_STATE to prevent mutating the state in their reducers because redux toolkit now check for that.

There are still some redux validation errors due to non-serializable values being on the the state e.g. modal callback functions. But I have disabled those checks temporarily until we can address them in a future PR.

  • Use redux toolkit's configureStore API
  • Address Redux Immutability Middleware errors in reducers (SET_LAST_UNDO_STATE, SET_LAST_SPLIT_STATE)
  • Address Redux Serializability Middleware errors in reducers (e.g. modal callback functions)
  • Update reducers to use new redux toolkit createSlice API
  • Update actions to use new redux toolkit createAsyncThunk API

@actual-github-bot actual-github-bot bot changed the title Initial upgrade to redux toolkit [WIP] Initial upgrade to redux toolkit Dec 17, 2024
Copy link

netlify bot commented Dec 17, 2024

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 5788ade
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/677da8a7d7494000085d8b3b
😎 Deploy Preview https://deploy-preview-4000.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

github-actions bot commented Dec 17, 2024

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
10 5.66 MB → 5.66 MB (+4.18 kB) +0.07%
Changeset
File Δ Size
node_modules/redux/dist/redux.mjs 🆕 +8.33 kB 0 B → 8.33 kB
node_modules/react-redux/dist/react-redux.mjs 🆕 +7.44 kB 0 B → 7.44 kB
node_modules/@reduxjs/toolkit/dist/redux-toolkit.modern.mjs 🆕 +5.07 kB 0 B → 5.07 kB
node_modules/use-sync-external-store/cjs/use-sync-external-store-with-selector.production.js 🆕 +2.59 kB 0 B → 2.59 kB
home/runner/work/actual/actual/packages/loot-core/src/client/store/index.ts 🆕 +988 B 0 B → 988 B
node_modules/clsx/dist/clsx.js 🆕 +509 B 0 B → 509 B
node_modules/redux-thunk/dist/redux-thunk.mjs 🆕 +375 B 0 B → 375 B
node_modules/use-sync-external-store/with-selector.js 🆕 +122 B 0 B → 122 B
src/redux/index.ts 🆕 +93 B 0 B → 93 B
node_modules/use-sync-external-store/cjs/use-sync-external-store-with-selector.production.js?commonjs-exports 🆕 +53 B 0 B → 53 B
node_modules/use-sync-external-store/with-selector.js?commonjs-module 🆕 +33 B 0 B → 33 B
node_modules/clsx/dist/clsx.js?commonjs-module 🆕 +27 B 0 B → 27 B
src/hooks/useFailedAccounts.ts 📈 +120 B (+126.32%) 95 B → 215 B
home/runner/work/actual/actual/packages/loot-core/src/platform/client/undo/index.web.ts 📈 +19 B (+2.62%) 724 B → 743 B
node_modules/clsx/dist/clsx.m.js 📈 +6 B (+1.73%) 347 B → 353 B
node_modules/react/index.js 📈 +2 B (+1.39%) 144 B → 146 B
node_modules/@use-gesture/react/dist/use-gesture-react.esm.js 📈 +6 B (+1.03%) 580 B → 586 B
home/runner/work/actual/actual/packages/loot-core/src/client/data-hooks/dashboard.ts 📈 +2 B (+0.84%) 239 B → 241 B
home/runner/work/actual/actual/packages/loot-core/src/client/data-hooks/widget.ts 📈 +2 B (+0.72%) 278 B → 280 B
src/components/reports/ReportOptions.ts 📈 +46 B (+0.68%) 6.56 kB → 6.61 kB
src/components/reports/disabledList.ts 📈 +18 B (+0.46%) 3.84 kB → 3.86 kB
node_modules/@react-aria/overlays/dist/useModal.mjs 📈 +14 B (+0.44%) 3.13 kB → 3.14 kB
node_modules/@react-aria/ssr/dist/SSRProvider.mjs 📈 +14 B (+0.38%) 3.61 kB → 3.63 kB
node_modules/react-aria-components/dist/Popover.mjs 📈 +18 B (+0.34%) 5.11 kB → 5.13 kB
node_modules/@react-aria/overlays/dist/Overlay.mjs 📈 +8 B (+0.34%) 2.31 kB → 2.32 kB
node_modules/@react-aria/collections/dist/CollectionBuilder.mjs 📈 +36 B (+0.32%) 11.07 kB → 11.1 kB
node_modules/react-aria-components/dist/Form.mjs 📈 +6 B (+0.31%) 1.88 kB → 1.89 kB
node_modules/@react-aria/interactions/dist/PressResponder.mjs 📈 +6 B (+0.28%) 2.1 kB → 2.11 kB
node_modules/@react-aria/overlays/dist/DismissButton.mjs 📈 +4 B (+0.28%) 1.41 kB → 1.42 kB
node_modules/@react-aria/utils/dist/useLayoutEffect.mjs 📈 +2 B (+0.27%) 738 B → 740 B
node_modules/react-aria-components/dist/Modal.mjs 📈 +18 B (+0.26%) 6.88 kB → 6.89 kB
node_modules/@react-aria/interactions/dist/context.mjs 📈 +2 B (+0.25%) 800 B → 802 B
node_modules/@react-aria/collections/dist/Hidden.mjs 📈 +8 B (+0.24%) 3.26 kB → 3.27 kB
node_modules/react-aria-components/dist/Tooltip.mjs 📈 +12 B (+0.23%) 5.08 kB → 5.09 kB
node_modules/@react-aria/focus/dist/useFocusable.mjs 📈 +6 B (+0.23%) 2.54 kB → 2.54 kB
node_modules/react-simple-pull-to-refresh/build/index.esm.js 📈 +32 B (+0.23%) 13.83 kB → 13.86 kB
node_modules/@react-aria/i18n/dist/context.mjs 📈 +2 B (+0.21%) 952 B → 954 B
node_modules/react-aria-components/dist/ListBox.mjs 📈 +36 B (+0.20%) 17.48 kB → 17.51 kB
node_modules/react-aria-components/dist/Header.mjs 📈 +2 B (+0.17%) 1.12 kB → 1.12 kB
node_modules/react-aria-components/dist/Dialog.mjs 📈 +8 B (+0.17%) 4.65 kB → 4.65 kB
node_modules/@react-stately/collections/dist/CollectionBuilder.mjs 📈 +14 B (+0.15%) 8.84 kB → 8.86 kB
node_modules/react-aria-components/dist/Collection.mjs 📈 +4 B (+0.15%) 2.66 kB → 2.66 kB
node_modules/react-aria-components/dist/DragAndDrop.mjs 📈 +6 B (+0.14%) 4.06 kB → 4.07 kB
node_modules/react-markdown/lib/react-markdown.js 📈 +6 B (+0.12%) 5.01 kB → 5.01 kB
src/components/reports/spreadsheets/net-worth-spreadsheet.ts 📈 +4 B (+0.11%) 3.4 kB → 3.4 kB
src/components/reports/spreadsheets/makeQuery.ts 📈 +2 B (+0.11%) 1.75 kB → 1.76 kB
node_modules/@react-aria/visually-hidden/dist/VisuallyHidden.mjs 📈 +2 B (+0.09%) 2.23 kB → 2.23 kB
src/components/reports/spreadsheets/cash-flow-spreadsheet.tsx 📈 +6 B (+0.09%) 6.8 kB → 6.81 kB
node_modules/react-router-dom/dist/index.js 📈 +10 B (+0.09%) 11.34 kB → 11.35 kB
node_modules/react-aria-components/dist/Button.mjs 📈 +4 B (+0.08%) 4.9 kB → 4.9 kB
src/components/reports/spreadsheets/summary-spreadsheet.ts 📈 +4 B (+0.07%) 5.67 kB → 5.68 kB
node_modules/react-markdown/lib/ast-to-react.js 📈 +6 B (+0.07%) 8.57 kB → 8.57 kB
node_modules/@use-gesture/core/dist/use-gesture-core.esm.js 📈 +4 B (+0.05%) 8.13 kB → 8.13 kB
src/components/reports/spreadsheets/calendar-spreadsheet.ts 📈 +2 B (+0.03%) 5.74 kB → 5.74 kB
src/global-events.ts 📈 +1 B (+0.03%) 3.07 kB → 3.07 kB
src/components/reports/spreadsheets/spending-spreadsheet.ts 📈 +2 B (+0.03%) 6.22 kB → 6.22 kB
src/components/admin/UserAccess/UserAccess.tsx 📈 +2 B (+0.03%) 6.71 kB → 6.71 kB
node_modules/@react-aria/focus/dist/FocusScope.mjs 📈 +10 B (+0.03%) 34.92 kB → 34.93 kB
node_modules/react-aria-components/dist/utils.mjs 📈 +2 B (+0.02%) 8.53 kB → 8.54 kB
node_modules/auto-text-size/dist/index.mjs 📈 +2 B (+0.02%) 8.99 kB → 9 kB
src/components/admin/UserDirectory/UserDirectory.tsx 📈 +2 B (+0.02%) 9.16 kB → 9.16 kB
src/components/Modals.tsx 📈 +2 B (+0.01%) 16.76 kB → 16.77 kB
src/components/reports/reports/Calendar.tsx 📈 +2 B (+0.01%) 26.11 kB → 26.11 kB
node_modules/react-grid-layout/build/ReactGridLayout.js 📉 -1 B (-0.00%) 24.96 kB → 24.96 kB
node_modules/react-grid-layout/build/GridItem.js 📉 -1 B (-0.00%) 21.49 kB → 21.49 kB
node_modules/react-grid-layout/build/components/WidthProvider.js 📉 -1 B (-0.02%) 5.22 kB → 5.22 kB
src/components/sidebar/Accounts.tsx 📉 -4 B (-0.08%) 4.61 kB → 4.61 kB
node_modules/downshift/dist/downshift.esm.js 📉 -44 B (-0.10%) 43.24 kB → 43.2 kB
src/components/accounts/Account.tsx 📉 -111 B (-0.24%) 44.63 kB → 44.52 kB
src/components/table.tsx 📉 -93 B (-0.38%) 24.17 kB → 24.08 kB
src/components/accounts/AccountSyncCheck.tsx 📉 -33 B (-0.55%) 5.88 kB → 5.85 kB
src/hooks/useSelected.tsx 📉 -55 B (-0.72%) 7.45 kB → 7.4 kB
node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js 📉 -2 B (-0.94%) 213 B → 211 B
src/components/payees/ManagePayeesWithData.tsx 📉 -62 B (-1.62%) 3.74 kB → 3.68 kB
node_modules/@babel/runtime/helpers/esm/extends.js 📉 -6 B (-1.94%) 310 B → 304 B
home/runner/work/actual/actual/packages/loot-core/src/client/reducers/account.ts 📉 -14 B (-2.07%) 676 B → 662 B
package.json 📉 -77 B (-2.47%) 3.04 kB → 2.97 kB
src/hooks/useSplitsExpanded.tsx 📉 -116 B (-3.62%) 3.13 kB → 3.01 kB
home/runner/work/actual/actual/packages/loot-core/src/client/actions/app.ts 📉 -102 B (-7.30%) 1.36 kB → 1.26 kB
home/runner/work/actual/actual/packages/loot-core/src/client/constants.ts 📉 -104 B (-7.43%) 1.37 kB → 1.26 kB
node_modules/redux/es/redux.js 📉 -3.71 kB (-43.70%) 8.48 kB → 4.77 kB
src/index.tsx 📉 -727 B (-47.24%) 1.5 kB → 812 B
home/runner/work/actual/actual/packages/loot-core/src/client/reducers/app.ts 📉 -296 B (-48.05%) 616 B → 320 B
node_modules/react-redux/es/hooks/useSelector.js 🔥 -3.13 kB (-100%) 3.13 kB → 0 B
node_modules/react-redux/es/utils/Subscription.js 🔥 -2.7 kB (-100%) 2.7 kB → 0 B
node_modules/redux-thunk/es/index.js 🔥 -1.27 kB (-100%) 1.27 kB → 0 B
node_modules/react-redux/es/hooks/useDispatch.js 🔥 -1.16 kB (-100%) 1.16 kB → 0 B
node_modules/react-redux/es/hooks/useStore.js 🔥 -998 B (-100%) 998 B → 0 B
node_modules/react-redux/es/components/Provider.js 🔥 -953 B (-100%) 953 B → 0 B
node_modules/@babel/runtime/helpers/esm/objectSpread2.js 🔥 -766 B (-100%) 766 B → 0 B
node_modules/react-redux/es/utils/useIsomorphicLayoutEffect.js 🔥 -758 B (-100%) 758 B → 0 B
node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js 🔥 -423 B (-100%) 423 B → 0 B
node_modules/react-redux/es/utils/batch.js 🔥 -399 B (-100%) 399 B → 0 B
node_modules/clsx/dist/clsx.mjs 🔥 -368 B (-100%) 368 B → 0 B
node_modules/react-redux/es/hooks/useReduxContext.js 🔥 -118 B (-100%) 118 B → 0 B
node_modules/react-redux/es/index.js 🔥 -109 B (-100%) 109 B → 0 B
node_modules/react-redux/es/components/Context.js 🔥 -66 B (-100%) 66 B → 0 B
node_modules/clsx/dist/clsx.mjs?commonjs-proxy 🔥 -64 B (-100%) 64 B → 0 B
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/ReportRouter.js 1.58 MB → 1.58 MB (+3.09 kB) +0.19%
static/js/index.js 3.72 MB → 3.72 MB (+1.2 kB) +0.03%

Smaller

Asset File Size % Changed
static/js/wide.js 104.59 kB → 104.48 kB (-111 B) -0.10%

Unchanged

Asset File Size % Changed
static/js/useAccountPreviewTransactions.js 1.63 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/workbox-window.prod.es5.js 5.69 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/AppliedFilters.js 10.24 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/narrow.js 84.22 kB 0%

Copy link
Contributor

github-actions bot commented Dec 17, 2024

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 1.33 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.js 1.33 MB 0%

@joel-jeremy
Copy link
Contributor Author

/update-vrt

@@ -11,6 +11,7 @@ const currentUndoState: T.UndoState = {
url: null,
openModal: null,
selectedItems: null,
current: null,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from redux state.app.lastUndoState to here

@@ -8,6 +8,7 @@ export type UndoState = {
name: string;
items: Set<string>;
} | null;
current: unknown;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from redux state.app.lastUndoState to here

// Reset the state and only keep around things intentionally. This
// blows away everything else
state = {
account: initialAccountState,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TS is complaining about the missing state properties so I have set them to initial states instead.

@@ -1,7 +1,7 @@
import type * as constants from '../constants';

export type AccountState = {
failedAccounts: Map<string, { type: string; code: string }>;
failedAccounts: { [key: string]: { type: string; code: string } };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to object because redux toolkit complains that Map is non-serializable

@@ -18,17 +16,6 @@ export function update(state = initialState, action: Action): AppState {
...state,
...action.state,
};
case constants.SET_LAST_UNDO_STATE:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed from redux state and moved to loot-core/platform/client/undo since redux toolkit is complaining that it's mutating in the reducer

state.lastUndoState.current = action.undoState;
return state;

case constants.SET_LAST_SPLIT_STATE:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed from redux state and moved to useSplitExpanded since redux toolkit is complaining that it's mutating in the reducer

@@ -2,8 +2,8 @@ import * as constants from '../constants';
import type { Action } from '../state-types';
import type { AccountState } from '../state-types/account';

const initialState: AccountState = {
failedAccounts: new Map(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed from Map to object since redux toolkit is complaining that Map is non-serializable

@joel-jeremy joel-jeremy changed the title [WIP] Initial upgrade to redux toolkit Upgrade to redux toolkit (Part 1) Dec 18, 2024
@joel-jeremy joel-jeremy changed the title Upgrade to redux toolkit (Part 1) [Redux Toolkit Migration] Use new Redux Toolkit configureStore API Dec 19, 2024
Copy link
Contributor

@jfdoming jfdoming left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! Left one quick suggestion to start since I think it will make the diff much more manageable to review 😅

Comment on lines 1 to 11
import { useDispatch, useSelector } from 'react-redux';

import { type AppDispatch, type RootState } from 'loot-core/client/store';

export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to keep the names the same so we don't have to rename everywhere?

Suggested change
import { useDispatch, useSelector } from 'react-redux';
import { type AppDispatch, type RootState } from 'loot-core/client/store';
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
import { useDispatch as useReduxDispatch, useSelector as useReduxSelector } from 'react-redux';
import { type AppDispatch, type RootState } from 'loot-core/client/store';
export const useDispatch = useReduxDispatch.withTypes<AppDispatch>();
export const useSelector = useReduxSelector.withTypes<RootState>();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reverted these renames. These are based on redux toolkit recommendations https://redux.js.org/usage/usage-with-typescript. Will separate them out on another PR instead to make this PR more manageable to review.

Copy link
Contributor

@jfdoming jfdoming left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes! Code looks mostly good now, had some questions around performance and bug bashing

Comment on lines +52 to +53
export type AppDispatch = typeof store.dispatch;
export type GetRootState = typeof store.getState;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if there's a reason to call these AppDispatch and GetRootState rather than Dispatch and GetState for the same reason as my first comment! Not a huge deal though at this point

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are based on the redux toolkit recommendations https://redux.js.org/usage/usage-with-typescript. Same as the naming of the useAppDispatch and useAppSelector. I will just bring back these names on another PR to make this PR easier to review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename PR: #4101

@@ -21,7 +22,7 @@ export type BoundActions = {

// https://react-redux.js.org/api/hooks#recipe-useactions
/**
* @deprecated please use actions directly with `useDispatch`
* @deprecated please use actions directly with `useAppDispatch`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @deprecated please use actions directly with `useAppDispatch`
* @deprecated please use actions directly with `useDispatch`

? !data.state.ids.has(id)
: data.state.ids.has(id),
isExpanded: (id: string) => {
const idSet = new Set(data.state.ids);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're now constructing the set on each call to isExpanded (O(n)) I'm a little worried about performance as this function gets called for each transaction. Is there any way we can still cache the set while keeping the state serializable? Maybe use a plain object with IDs as keys instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, since we're not even using Redux at all anymore for this state, couldn't we just keep using a Set? Or is the plan to later move this to Redux?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! Reverted it back to a Set

packages/loot-core/src/platform/client/undo/index.d.ts Outdated Show resolved Hide resolved
@@ -80,15 +79,16 @@ export function ManagePayeesWithData({
await refetchRuleCounts();
}

await dispatch(setLastUndoState(null));
undo.setUndoState('current', null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One side-effect of this approach is that other components (and this component) won't rerender when the undo state changes. Not sure if/where this matters—have you had a chance to confirm if any undo behaviour is broken? Wasn't able to repro anything in my testing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dispatching of setLastUndoState doesn't actually cause a re-render because in the reducer the state is mutated instead of returning a new state. See old comment on https://github.com/actualbudget/actual/pull/4000/files#diff-6312fd65ee6fa1c84229aa82af3e5def6a17a14c01c4938dd5475cba8d66afbaL21.

@@ -1239,8 +1239,8 @@ export function useTableNavigator<T extends TableItem>(
}, []);

useEffect(() => {
modalStackLength.current = store.getState().modals.modalStack.length;
}, []);
modalStackLength.current = modalState.modalStack.length;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I think this approach breaks the field refocus behaviour due to caching. Steps to repro:

  1. Mark transactions as reconciled
  2. Edit the payee on a reconciled transaction
  3. Hit 'Cancel' on the modal
    On edge, this refocuses the payee field. However in this PR the field is not focused

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed on the latest push

.eslintrc.js Outdated Show resolved Hide resolved
jfdoming
jfdoming previously approved these changes Jan 7, 2025
@joel-jeremy joel-jeremy merged commit cc1c11a into master Jan 8, 2025
20 checks passed
@joel-jeremy joel-jeremy deleted the redux-toolkit branch January 8, 2025 00:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants