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

Hooks for frequently made operations #2293

Merged
merged 32 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fd24b27
Hooks for frequently made operations
joel-jeremy Jan 27, 2024
42077a7
Release notes
joel-jeremy Jan 27, 2024
67c6631
Fix typecheck errors
joel-jeremy Jan 27, 2024
ca90ffb
Remove useGlobalPrefs
joel-jeremy Jan 27, 2024
054bbb0
Add null checks
joel-jeremy Jan 27, 2024
da79abb
Fix showCleared pref
joel-jeremy Jan 28, 2024
87d3849
Add loaded flag for categories, accounts and payees state
joel-jeremy Jan 28, 2024
0d64693
Refactor to reduce unnecessary states
joel-jeremy Jan 28, 2024
34f62f6
Fix eslint errors
joel-jeremy Jan 28, 2024
5cc6019
Fix hooks deps
joel-jeremy Feb 3, 2024
02d37d7
Add useEffect
joel-jeremy Feb 3, 2024
262a036
Fix typecheck error
joel-jeremy Feb 7, 2024
4a1b878
Set local and global pref hooks
joel-jeremy Feb 8, 2024
8169790
Fix lint error
joel-jeremy Feb 8, 2024
7da5a02
VRT
joel-jeremy Feb 8, 2024
7d8200f
Fix typecheck error
joel-jeremy Feb 8, 2024
f324e6e
Remove eager loading
joel-jeremy Feb 8, 2024
ee1234e
Fix typecheck error
joel-jeremy Feb 8, 2024
45898bc
Fix typo
joel-jeremy Feb 8, 2024
c9b2548
Fix typecheck error
joel-jeremy Feb 9, 2024
a13875d
Update useTheme
joel-jeremy Feb 9, 2024
f0378a6
Typecheck errors
joel-jeremy Feb 9, 2024
4f26375
Typecheck error
joel-jeremy Feb 9, 2024
b77a589
defaultValue
joel-jeremy Feb 10, 2024
102b1c0
Explicitly check undefined
joel-jeremy Feb 10, 2024
df1cdc4
Remove useGlobalPref and useLocalPref defaults
joel-jeremy Feb 10, 2024
2596416
Fix default prefs
joel-jeremy Feb 10, 2024
3aaf776
Default value
joel-jeremy Feb 10, 2024
60b9cee
Fix lint error
joel-jeremy Feb 10, 2024
a6df36e
Set default theme
joel-jeremy Feb 10, 2024
9009c07
Default date format in Account
joel-jeremy Feb 10, 2024
e352ee5
Update packages/desktop-client/src/style/theme.tsx
joel-jeremy Feb 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 9 additions & 38 deletions packages/desktop-client/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ import {
} from 'react-error-boundary';
import { useSelector } from 'react-redux';

import { type State } from 'loot-core/client/state-types';
import { type AppState } from 'loot-core/client/state-types/app';
import { type PrefsState } from 'loot-core/client/state-types/prefs';
import * as Platform from 'loot-core/src/client/platform';
import { type State } from 'loot-core/src/client/state-types';
import {
init as initConnection,
send,
} from 'loot-core/src/platform/client/fetch';
import { type GlobalPrefs } from 'loot-core/src/types/prefs';

import { useActions } from '../hooks/useActions';
import { useLocalPref } from '../hooks/useLocalPref';
import { installPolyfills } from '../polyfills';
import { ResponsiveProvider } from '../ResponsiveProvider';
import { styles, hasHiddenScrollbars, ThemeStyle } from '../style';
Expand All @@ -34,26 +32,13 @@ import { UpdateNotification } from './UpdateNotification';
type AppInnerProps = {
budgetId: string;
cloudFileId: string;
loadingText: string;
loadBudget: (
id: string,
loadingText?: string,
options?: object,
) => Promise<void>;
closeBudget: () => Promise<void>;
loadGlobalPrefs: () => Promise<GlobalPrefs>;
};

function AppInner({
budgetId,
cloudFileId,
loadingText,
loadBudget,
closeBudget,
loadGlobalPrefs,
}: AppInnerProps) {
function AppInner({ budgetId, cloudFileId }: AppInnerProps) {
const [initializing, setInitializing] = useState(true);
const { showBoundary: showErrorBoundary } = useErrorBoundary();
const loadingText = useSelector((state: State) => state.app.loadingText);
const { loadBudget, closeBudget, loadGlobalPrefs } = useActions();

async function init() {
const socketName = await global.Actual.getServerSocket();
Expand Down Expand Up @@ -126,16 +111,9 @@ function ErrorFallback({ error }: FallbackProps) {
}

export function App() {
const budgetId = useSelector<State, PrefsState['local']['id']>(
state => state.prefs.local && state.prefs.local.id,
);
const cloudFileId = useSelector<State, PrefsState['local']['cloudFileId']>(
state => state.prefs.local && state.prefs.local.cloudFileId,
);
const loadingText = useSelector<State, AppState['loadingText']>(
state => state.app.loadingText,
);
const { loadBudget, closeBudget, loadGlobalPrefs, sync } = useActions();
const [budgetId] = useLocalPref('id');
const [cloudFileId] = useLocalPref('cloudFileId');
const { sync } = useActions();
const [hiddenScrollbars, setHiddenScrollbars] = useState(
hasHiddenScrollbars(),
);
Expand Down Expand Up @@ -184,14 +162,7 @@ export function App() {
{process.env.REACT_APP_REVIEW_ID && !Platform.isPlaywright && (
<DevelopmentTopBar />
)}
<AppInner
budgetId={budgetId}
cloudFileId={cloudFileId}
loadingText={loadingText}
loadBudget={loadBudget}
closeBudget={closeBudget}
loadGlobalPrefs={loadGlobalPrefs}
/>
<AppInner budgetId={budgetId} cloudFileId={cloudFileId} />
</ErrorBoundary>
<ThemeStyle />
</View>
Expand Down
7 changes: 3 additions & 4 deletions packages/desktop-client/src/components/BankSyncStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { useTransition, animated } from 'react-spring';

import { type State } from 'loot-core/client/state-types';
import { type AccountState } from 'loot-core/client/state-types/account';
import { type State } from 'loot-core/src/client/state-types';

import { theme, styles } from '../style';

Expand All @@ -12,8 +11,8 @@ import { Text } from './common/Text';
import { View } from './common/View';

export function BankSyncStatus() {
const accountsSyncing = useSelector<State, AccountState['accountsSyncing']>(
state => state.account.accountsSyncing,
const accountsSyncing = useSelector(
(state: State) => state.account.accountsSyncing,
);

const name = accountsSyncing
Expand Down
41 changes: 20 additions & 21 deletions packages/desktop-client/src/components/FinancesApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import React, { type ReactElement, useEffect, useMemo } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend as Backend } from 'react-dnd-html5-backend';
import { useSelector } from 'react-redux';
import {
Route,
Routes,
Expand All @@ -13,12 +14,12 @@ import {

import hotkeys from 'hotkeys-js';

import { AccountsProvider } from 'loot-core/src/client/data-hooks/accounts';
import { PayeesProvider } from 'loot-core/src/client/data-hooks/payees';
import { SpreadsheetProvider } from 'loot-core/src/client/SpreadsheetProvider';
import { type State } from 'loot-core/src/client/state-types';
import { checkForUpdateNotification } from 'loot-core/src/client/update-notification';
import * as undo from 'loot-core/src/platform/client/undo';

import { useAccounts } from '../hooks/useAccounts';
import { useActions } from '../hooks/useActions';
import { useNavigate } from '../hooks/useNavigate';
import { useResponsive } from '../ResponsiveProvider';
Expand All @@ -39,7 +40,8 @@ import { Reports } from './reports';
import { NarrowAlternate, WideComponent } from './responsive';
import { ScrollProvider } from './ScrollProvider';
import { Settings } from './settings';
import { FloatableSidebar, SidebarProvider } from './sidebar';
import { FloatableSidebar } from './sidebar';
import { SidebarProvider } from './sidebar/SidebarProvider';
import { Titlebar, TitlebarProvider } from './Titlebar';
import { TransactionEdit } from './transactions/MobileTransaction';

Expand Down Expand Up @@ -71,18 +73,19 @@ function WideNotSupported({ children, redirectTo = '/budget' }) {
return isNarrowWidth ? children : null;
}

function RouterBehaviors({ getAccounts }) {
function RouterBehaviors() {
const navigate = useNavigate();
const accounts = useAccounts();
const accountsLoaded = useSelector(
(state: State) => state.queries.accountsLoaded,
);
useEffect(() => {
// Get the accounts and check if any exist. If there are no
// accounts, we want to redirect the user to the All Accounts
// screen which will prompt them to add an account
getAccounts().then(accounts => {
if (accounts.length === 0) {
navigate('/accounts');
}
});
}, []);
// If there are no accounts, we want to redirect the user to
// the All Accounts screen which will prompt them to add an account
if (accountsLoaded && accounts.length === 0) {
navigate('/accounts');
}
}, [accountsLoaded, accounts]);

const location = useLocation();
const href = useHref(location);
Expand Down Expand Up @@ -116,7 +119,7 @@ function FinancesAppWithoutContext() {

return (
<BrowserRouter>
<RouterBehaviors getAccounts={actions.getAccounts} />
<RouterBehaviors />
<ExposeNavigate />

<View style={{ height: '100%' }}>
Expand Down Expand Up @@ -265,13 +268,9 @@ export function FinancesApp() {
<TitlebarProvider>
<SidebarProvider>
<BudgetMonthCountProvider>
<PayeesProvider>
<AccountsProvider>
<DndProvider backend={Backend}>
<ScrollProvider>{app}</ScrollProvider>
</DndProvider>
</AccountsProvider>
</PayeesProvider>
<DndProvider backend={Backend}>
<ScrollProvider>{app}</ScrollProvider>
</DndProvider>
</BudgetMonthCountProvider>
</SidebarProvider>
</TitlebarProvider>
Expand Down
7 changes: 2 additions & 5 deletions packages/desktop-client/src/components/LoggedInUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux';

import { type State } from 'loot-core/client/state-types';
import { type UserState } from 'loot-core/client/state-types/user';
import { type State } from 'loot-core/src/client/state-types';

import { useActions } from '../hooks/useActions';
import { theme, styles, type CSSProperties } from '../style';
Expand All @@ -25,9 +24,7 @@ export function LoggedInUser({
style,
color,
}: LoggedInUserProps) {
const userData = useSelector<State, UserState['data']>(
state => state.user.data,
);
const userData = useSelector((state: State) => state.user.data);
const { getUserData, signOut, closeBudget } = useActions();
const [loading, setLoading] = useState(true);
const [menuOpen, setMenuOpen] = useState(false);
Expand Down
23 changes: 9 additions & 14 deletions packages/desktop-client/src/components/ManageRules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import React, {
type SetStateAction,
type Dispatch,
} from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';

import { type State } from 'loot-core/client/state-types';
import { type QueriesState } from 'loot-core/client/state-types/queries';
import { pushModal } from 'loot-core/src/client/actions/modals';
import { initiallyLoadPayees } from 'loot-core/src/client/actions/queries';
import { send } from 'loot-core/src/platform/client/fetch';
Expand All @@ -19,7 +17,9 @@ import { mapField, friendlyOp } from 'loot-core/src/shared/rules';
import { describeSchedule } from 'loot-core/src/shared/schedules';
import { type RuleEntity } from 'loot-core/src/types/models';

import { useAccounts } from '../hooks/useAccounts';
import { useCategories } from '../hooks/useCategories';
import { usePayees } from '../hooks/usePayees';
import { useSelected, SelectedProvider } from '../hooks/useSelected';
import { theme } from '../style';

Expand Down Expand Up @@ -105,18 +105,13 @@ function ManageRulesContent({

const { data: schedules } = SchedulesQuery.useQuery();
const { list: categories } = useCategories();
const state = useSelector<
State,
{
payees: QueriesState['payees'];
accounts: QueriesState['accounts'];
schedules: ReturnType<(typeof SchedulesQuery)['useQuery']>;
}
>(state => ({
payees: state.queries.payees,
accounts: state.queries.accounts,
const payees = usePayees();
const accounts = useAccounts();
const state = {
payees,
accounts,
schedules,
}));
};
const filterData = useMemo(
() => ({
...state,
Expand Down
20 changes: 5 additions & 15 deletions packages/desktop-client/src/components/MobileWebMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { savePrefs } from 'loot-core/src/client/actions';
import { type State } from 'loot-core/src/client/state-types';
import { type PrefsState } from 'loot-core/src/client/state-types/prefs';

import { useLocalPref } from '../hooks/useLocalPref';
import { useResponsive } from '../ResponsiveProvider';
import { theme, styles } from '../style';

Expand All @@ -16,30 +12,24 @@ import { Checkbox } from './forms';
const buttonStyle = { border: 0, fontSize: 15, padding: '10px 13px' };

export function MobileWebMessage() {
const hideMobileMessagePref = useSelector<
State,
PrefsState['local']['hideMobileMessage']
>(state => {
return (state.prefs.local && state.prefs.local.hideMobileMessage) || true;
});
const [hideMobileMessage = true, setHideMobileMessagePref] =
useLocalPref('hideMobileMessage');

const { isNarrowWidth } = useResponsive();

const [show, setShow] = useState(
isNarrowWidth &&
!hideMobileMessagePref &&
!hideMobileMessage &&
!document.cookie.match(/hideMobileMessage=true/),
);
const [requestDontRemindMe, setRequestDontRemindMe] = useState(false);

const dispatch = useDispatch();

function onTry() {
setShow(false);

if (requestDontRemindMe) {
// remember the pref indefinitely
dispatch(savePrefs({ hideMobileMessage: true }));
setHideMobileMessagePref(true);
} else {
// Set a cookie for 5 minutes
const d = new Date();
Expand Down
39 changes: 6 additions & 33 deletions packages/desktop-client/src/components/Modals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@ import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom';

import { type State } from 'loot-core/src/client/state-types';
import {
type ModalsState,
type PopModalAction,
} from 'loot-core/src/client/state-types/modals';
import { type PrefsState } from 'loot-core/src/client/state-types/prefs';
import { type QueriesState } from 'loot-core/src/client/state-types/queries';
import { type PopModalAction } from 'loot-core/src/client/state-types/modals';
import { send } from 'loot-core/src/platform/client/fetch';

import { useActions } from '../hooks/useActions';
import { useCategories } from '../hooks/useCategories';
import { useSyncServerStatus } from '../hooks/useSyncServerStatus';

import { CategoryGroupMenu } from './modals/CategoryGroupMenu';
Expand Down Expand Up @@ -56,19 +50,8 @@ export type CommonModalProps = {
};

export function Modals() {
const modalStack = useSelector<State, ModalsState['modalStack']>(
state => state.modals.modalStack,
);
const isHidden = useSelector<State, ModalsState['isHidden']>(
state => state.modals.isHidden,
);
const accounts = useSelector<State, QueriesState['accounts']>(
state => state.queries.accounts,
);
const { grouped: categoryGroups, list: categories } = useCategories();
const budgetId = useSelector<State, PrefsState['local']['id']>(
state => state.prefs.local && state.prefs.local.id,
);
const modalStack = useSelector((state: State) => state.modals.modalStack);
const isHidden = useSelector((state: State) => state.modals.isHidden);
const actions = useActions();
const location = useLocation();

Expand Down Expand Up @@ -118,8 +101,6 @@ export function Modals() {
account={options.account}
balance={options.balance}
canDelete={options.canDelete}
accounts={accounts.filter(acct => acct.closed === 0)}
categoryGroups={categoryGroups}
actions={actions}
/>
);
Expand All @@ -130,7 +111,6 @@ export function Modals() {
modalProps={modalProps}
externalAccounts={options.accounts}
requisitionId={options.requisitionId}
localAccounts={accounts.filter(acct => acct.closed === 0)}
actions={actions}
syncSource={options.syncSource}
/>
Expand All @@ -140,15 +120,8 @@ export function Modals() {
return (
<ConfirmCategoryDelete
modalProps={modalProps}
category={
'category' in options &&
categories.find(c => c.id === options.category)
}
group={
'group' in options &&
categoryGroups.find(g => g.id === options.group)
}
categoryGroups={categoryGroups}
category={options.category}
group={options.group}
onDelete={options.onDelete}
/>
);
Expand All @@ -166,7 +139,7 @@ export function Modals() {
return (
<LoadBackup
watchUpdates
budgetId={budgetId}
budgetId={options.budgetId}
modalProps={modalProps}
actions={actions}
backupDisabled={false}
Expand Down
Loading
Loading