From c87e9232a6681b503bb44ce74cde94f665b6a0d4 Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Sun, 8 Dec 2024 14:55:45 -0800 Subject: [PATCH 1/7] useSplitsExpanded renamed to .tsx --- .../src/hooks/{useSplitsExpanded.jsx => useSplitsExpanded.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/desktop-client/src/hooks/{useSplitsExpanded.jsx => useSplitsExpanded.tsx} (100%) diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.jsx b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx similarity index 100% rename from packages/desktop-client/src/hooks/useSplitsExpanded.jsx rename to packages/desktop-client/src/hooks/useSplitsExpanded.tsx From 82ad03ecd1421a84a58a8f6a046684a5bd4b3e24 Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Sun, 8 Dec 2024 16:37:53 -0800 Subject: [PATCH 2/7] Some type hardening --- .../src/hooks/useSplitsExpanded.tsx | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx index 8b8bb4ed249..03def593369 100644 --- a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx +++ b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx @@ -7,7 +7,17 @@ import React, { } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -const SplitsExpandedContext = createContext(null); +export type SplitMode = 'collapse' | 'expand'; + +export type SplitsStateContext = { + state: { + mode: SplitMode, + ids: Set + transitionId: string | null, + } +}; + +const SplitsExpandedContext = createContext(null); export function useSplitsExpanded() { const data = useContext(SplitsExpandedContext); @@ -15,7 +25,7 @@ export function useSplitsExpanded() { return useMemo( () => ({ ...data, - expanded: id => + expanded: (id: string) => data.state.mode === 'collapse' ? !data.state.ids.has(id) : data.state.ids.has(id), @@ -24,12 +34,43 @@ export function useSplitsExpanded() { ); } +type ToggleSplitAction = { + type: 'toggle-split'; + id: string; +}; + +type OpenSplitAction = { + type: 'open-split'; + id: string; +}; + +type ClospSplitsAction = { + type: 'close-splits'; + ids: string[]; +}; + +type SetModeAction = { + type: 'set-mode'; + mode: SplitMode; +}; + +type SwitchModeAction = { + type: 'switch-mode'; + id: string; +}; + +type FinishSwitchModeAction = { + type: 'finish-switch-mode'; +}; + +export type Actions = ToggleSplitAction | OpenSplitAction | ClospSplitsAction | SetModeAction | SwitchModeAction | FinishSwitchModeAction; + export function SplitsExpandedProvider({ children, initialMode = 'expand' }) { const cachedState = useSelector(state => state.app.lastSplitState); const reduxDispatch = useDispatch(); const [state, dispatch] = useReducer( - (state, action) => { + (state, action: Actions) => { switch (action.type) { case 'toggle-split': { const ids = new Set([...state.ids]); @@ -84,8 +125,6 @@ export function SplitsExpandedProvider({ children, initialMode = 'expand' }) { }; case 'finish-switch-mode': return { ...state, transitionId: null }; - default: - throw new Error('Unknown action type: ' + action.type); } }, cachedState.current || { ids: new Set(), mode: initialMode }, From 6c7090bc0ce1c3dc235569eec55d05d0dc025b78 Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Sun, 8 Dec 2024 16:45:19 -0800 Subject: [PATCH 3/7] add release note --- upcoming-release-notes/3945.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 upcoming-release-notes/3945.md diff --git a/upcoming-release-notes/3945.md b/upcoming-release-notes/3945.md new file mode 100644 index 00000000000..219e2d8618a --- /dev/null +++ b/upcoming-release-notes/3945.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [dkhalife] +--- + +Migrate useSplitsExpanded to TypeScript \ No newline at end of file From b8182908f5b7e6f5e2bdcef82953efd833d6a220 Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Sun, 8 Dec 2024 17:00:56 -0800 Subject: [PATCH 4/7] lint --- .../src/hooks/useSplitsExpanded.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx index 03def593369..e0fea25f5aa 100644 --- a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx +++ b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx @@ -7,14 +7,14 @@ import React, { } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -export type SplitMode = 'collapse' | 'expand'; +type SplitMode = 'collapse' | 'expand'; -export type SplitsStateContext = { +type SplitsStateContext = { state: { - mode: SplitMode, - ids: Set - transitionId: string | null, - } + mode: SplitMode; + ids: Set; + transitionId: string | null; + }; }; const SplitsExpandedContext = createContext(null); @@ -63,7 +63,13 @@ type FinishSwitchModeAction = { type: 'finish-switch-mode'; }; -export type Actions = ToggleSplitAction | OpenSplitAction | ClospSplitsAction | SetModeAction | SwitchModeAction | FinishSwitchModeAction; +type Actions = + | ToggleSplitAction + | OpenSplitAction + | ClospSplitsAction + | SetModeAction + | SwitchModeAction + | FinishSwitchModeAction; export function SplitsExpandedProvider({ children, initialMode = 'expand' }) { const cachedState = useSelector(state => state.app.lastSplitState); From 8efaaac5984f091be12d1222818aa37d334be70a Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Sun, 8 Dec 2024 17:57:39 -0800 Subject: [PATCH 5/7] typecheck --- .../src/hooks/useSplitsExpanded.tsx | 80 +++++++++++-------- .../loot-core/src/client/state-types/app.d.ts | 3 +- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx index e0fea25f5aa..ed5ca765cd5 100644 --- a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx +++ b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx @@ -1,39 +1,15 @@ +import { SplitMode, SplitState } from 'loot-core/client/state-types/app'; import React, { createContext, useMemo, useEffect, useContext, useReducer, + Dispatch, + ReactNode, } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -type SplitMode = 'collapse' | 'expand'; - -type SplitsStateContext = { - state: { - mode: SplitMode; - ids: Set; - transitionId: string | null; - }; -}; - -const SplitsExpandedContext = createContext(null); - -export function useSplitsExpanded() { - const data = useContext(SplitsExpandedContext); - - return useMemo( - () => ({ - ...data, - expanded: (id: string) => - data.state.mode === 'collapse' - ? !data.state.ids.has(id) - : data.state.ids.has(id), - }), - [data], - ); -} - type ToggleSplitAction = { type: 'toggle-split'; id: string; @@ -44,7 +20,7 @@ type OpenSplitAction = { id: string; }; -type ClospSplitsAction = { +type CloseSplitsAction = { type: 'close-splits'; ids: string[]; }; @@ -66,17 +42,53 @@ type FinishSwitchModeAction = { type Actions = | ToggleSplitAction | OpenSplitAction - | ClospSplitsAction + | CloseSplitsAction | SetModeAction | SwitchModeAction | FinishSwitchModeAction; -export function SplitsExpandedProvider({ children, initialMode = 'expand' }) { +type SplitsStateContext = { + state: SplitState; + dispatch: Dispatch; +}; + +const SplitsExpandedContext = createContext({ + state: { + mode: 'collapse', + ids: new Set(), + transitionId: null, + }, + dispatch: () => { + throw new Error('Unitialised context method called: dispatch'); + } +}); + +export function useSplitsExpanded() { + const data = useContext(SplitsExpandedContext); + + return useMemo( + () => ({ + ...data, + expanded: (id: string) => + data.state.mode === 'collapse' + ? !data.state.ids.has(id) + : data.state.ids.has(id), + }), + [data], + ); +} + +type SplitsExpandedProviderProps = { + children?: ReactNode; + initialMode: SplitMode; +}; + +export function SplitsExpandedProvider({ children, initialMode = 'expand' }: SplitsExpandedProviderProps) { const cachedState = useSelector(state => state.app.lastSplitState); const reduxDispatch = useDispatch(); const [state, dispatch] = useReducer( - (state, action: Actions) => { + (state: SplitState, action: Actions): SplitState => { switch (action.type) { case 'toggle-split': { const ids = new Set([...state.ids]); @@ -113,7 +125,7 @@ export function SplitsExpandedProvider({ children, initialMode = 'expand' }) { return { ...state, mode: action.mode, - ids: new Set(), + ids: new Set(), transitionId: null, }; } @@ -127,13 +139,13 @@ export function SplitsExpandedProvider({ children, initialMode = 'expand' }) { ...state, mode: state.mode === 'expand' ? 'collapse' : 'expand', transitionId: action.id, - ids: new Set(), + ids: new Set(), }; case 'finish-switch-mode': return { ...state, transitionId: null }; } }, - cachedState.current || { ids: new Set(), mode: initialMode }, + cachedState.current || { ids: new Set(), mode: initialMode, transitionId: null }, ); useEffect(() => { diff --git a/packages/loot-core/src/client/state-types/app.d.ts b/packages/loot-core/src/client/state-types/app.d.ts index 7420aa7251b..c4ba033f981 100644 --- a/packages/loot-core/src/client/state-types/app.d.ts +++ b/packages/loot-core/src/client/state-types/app.d.ts @@ -1,7 +1,8 @@ import type { UndoState } from '../../server/undo'; import type * as constants from '../constants'; -export type SplitState = { ids: Set; mode: 'collapse' | 'expand' }; +export type SplitMode = 'collapse' | 'expand'; +export type SplitState = { ids: Set; mode: SplitMode; transitionId: string | null }; export type AppState = { loadingText: string | null; From d76b4af10d01f46d51cf21916ba0aecfc3dc9c70 Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Sun, 8 Dec 2024 18:06:21 -0800 Subject: [PATCH 6/7] lint --- .../src/hooks/useSplitsExpanded.tsx | 23 ++++++++++++++----- .../loot-core/src/client/state-types/app.d.ts | 6 ++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx index ed5ca765cd5..10728ec34b7 100644 --- a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx +++ b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx @@ -1,15 +1,19 @@ -import { SplitMode, SplitState } from 'loot-core/client/state-types/app'; import React, { createContext, useMemo, useEffect, useContext, useReducer, - Dispatch, - ReactNode, + type Dispatch, + type ReactNode, } from 'react'; import { useSelector, useDispatch } from 'react-redux'; +import { + type SplitMode, + type SplitState, +} from 'loot-core/client/state-types/app'; + type ToggleSplitAction = { type: 'toggle-split'; id: string; @@ -60,7 +64,7 @@ const SplitsExpandedContext = createContext({ }, dispatch: () => { throw new Error('Unitialised context method called: dispatch'); - } + }, }); export function useSplitsExpanded() { @@ -83,7 +87,10 @@ type SplitsExpandedProviderProps = { initialMode: SplitMode; }; -export function SplitsExpandedProvider({ children, initialMode = 'expand' }: SplitsExpandedProviderProps) { +export function SplitsExpandedProvider({ + children, + initialMode = 'expand', +}: SplitsExpandedProviderProps) { const cachedState = useSelector(state => state.app.lastSplitState); const reduxDispatch = useDispatch(); @@ -145,7 +152,11 @@ export function SplitsExpandedProvider({ children, initialMode = 'expand' }: Spl return { ...state, transitionId: null }; } }, - cachedState.current || { ids: new Set(), mode: initialMode, transitionId: null }, + cachedState.current || { + ids: new Set(), + mode: initialMode, + transitionId: null, + }, ); useEffect(() => { diff --git a/packages/loot-core/src/client/state-types/app.d.ts b/packages/loot-core/src/client/state-types/app.d.ts index c4ba033f981..fd4e4f34414 100644 --- a/packages/loot-core/src/client/state-types/app.d.ts +++ b/packages/loot-core/src/client/state-types/app.d.ts @@ -2,7 +2,11 @@ import type { UndoState } from '../../server/undo'; import type * as constants from '../constants'; export type SplitMode = 'collapse' | 'expand'; -export type SplitState = { ids: Set; mode: SplitMode; transitionId: string | null }; +export type SplitState = { + ids: Set; + mode: SplitMode; + transitionId: string | null; +}; export type AppState = { loadingText: string | null; From 7d2d31931e9ae37a225eb1a742074459b23d14d4 Mon Sep 17 00:00:00 2001 From: Dany Khalife Date: Tue, 10 Dec 2024 19:22:50 -0800 Subject: [PATCH 7/7] rename expanded -> isExpanded --- .../src/components/transactions/TransactionsTable.jsx | 8 ++++---- packages/desktop-client/src/hooks/useSplitsExpanded.tsx | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx index c26fe412d02..60f581b60c0 100644 --- a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx +++ b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx @@ -2105,9 +2105,9 @@ export const TransactionTable = forwardRef((props, ref) => { result = props.transactions.filter((t, idx) => { if (t.parent_id) { if (idx >= index) { - return splitsExpanded.expanded(t.parent_id); + return splitsExpanded.isExpanded(t.parent_id); } else if (prevSplitsExpanded.current) { - return prevSplitsExpanded.current.expanded(t.parent_id); + return prevSplitsExpanded.current.isExpanded(t.parent_id); } } return true; @@ -2124,7 +2124,7 @@ export const TransactionTable = forwardRef((props, ref) => { result = props.transactions.filter(t => { if (t.parent_id) { - return splitsExpanded.expanded(t.parent_id); + return splitsExpanded.isExpanded(t.parent_id); } return true; }); @@ -2595,7 +2595,7 @@ export const TransactionTable = forwardRef((props, ref) => { transactionsByParent={transactionsByParent} transferAccountsByTransaction={transferAccountsByTransaction} selectedItems={selectedItems} - isExpanded={splitsExpanded.expanded} + isExpanded={splitsExpanded.isExpanded} onSave={onSave} onDelete={onDelete} onDuplicate={onDuplicate} diff --git a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx index 10728ec34b7..25386d2dcec 100644 --- a/packages/desktop-client/src/hooks/useSplitsExpanded.tsx +++ b/packages/desktop-client/src/hooks/useSplitsExpanded.tsx @@ -73,7 +73,7 @@ export function useSplitsExpanded() { return useMemo( () => ({ ...data, - expanded: (id: string) => + isExpanded: (id: string) => data.state.mode === 'collapse' ? !data.state.ids.has(id) : data.state.ids.has(id),