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

Update sidebar scrolling #3554

Merged
merged 26 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
87da867
Updated Sidebar
tlesicka Oct 4, 2024
2480331
Update VRT snapshots
tlesicka Oct 4, 2024
9cde369
Create 3554.md
tlesicka Oct 4, 2024
62f0908
Change recommended by coderabbitai
tlesicka Oct 4, 2024
87aee2c
Update VRT snapshots
tlesicka Oct 4, 2024
083b8fa
Merge remote-tracking branch 'upstream/master' into update-sidebar-sc…
tlesicka Oct 4, 2024
17e741b
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 5, 2024
1a0f31c
Fixed issue sidenav icon is no longer in the correct location
tlesicka Oct 5, 2024
1f03866
removed @ts-strict-ignore from 3 files
tlesicka Oct 5, 2024
59f57fe
Fixed small window scrolling issue
tlesicka Oct 6, 2024
2a23ea7
Scroll area expands to fill full space
tlesicka Oct 6, 2024
24c5c04
Update VRT
tlesicka Oct 6, 2024
35a214b
Updated optional chaining to match other locations in file
tlesicka Oct 6, 2024
c2babfd
Update VRT
tlesicka Oct 6, 2024
1b2b6a0
Updated code to remove @ts-strict-ignore
tlesicka Oct 6, 2024
521860f
Changed responsiveness from React Responsive to CSS media query
tlesicka Oct 6, 2024
5445314
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 6, 2024
5b885ee
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 7, 2024
b945a27
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 7, 2024
65c8567
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 7, 2024
b5c6efc
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 7, 2024
9edb2b4
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 8, 2024
61f0c6d
Merge branch 'actualbudget:master' into update-sidebar-scrolling
tlesicka Oct 9, 2024
8db81c2
Merge remote-tracking branch 'upstream/master' into update-sidebar-sc…
tlesicka Oct 9, 2024
bb53bb8
Update VRT
tlesicka Oct 9, 2024
9baf708
Merge branch 'master' into update-sidebar-scrolling
MatissJanis Oct 9, 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
227 changes: 125 additions & 102 deletions packages/desktop-client/src/components/sidebar/Accounts.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,32 @@
// @ts-strict-ignore
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';

import { moveAccount } from 'loot-core/src/client/actions';
import * as queries from 'loot-core/src/client/queries';
import { type State } from 'loot-core/src/client/state-types';
import { type AccountEntity } from 'loot-core/types/models';

import { useAccounts } from '../../hooks/useAccounts';
import { useBudgetedAccounts } from '../../hooks/useBudgetedAccounts';
import { useClosedAccounts } from '../../hooks/useClosedAccounts';
import { useFailedAccounts } from '../../hooks/useFailedAccounts';
import { useLocalPref } from '../../hooks/useLocalPref';
import { useOffBudgetAccounts } from '../../hooks/useOffBudgetAccounts';
import { useUpdatedAccounts } from '../../hooks/useUpdatedAccounts';
import { SvgAdd } from '../../icons/v1';
import { theme } from '../../style';
import { View } from '../common/View';
import { type OnDropCallback } from '../sort';

import { Account } from './Account';
import { SecondaryItem } from './SecondaryItem';

const fontWeight = 600;

type AccountsProps = {
onAddAccount: () => void;
onToggleClosedAccounts: () => void;
onReorder: OnDropCallback;
};

export function Accounts({
onAddAccount,
onToggleClosedAccounts,
onReorder,
}: AccountsProps) {
export function Accounts() {
const { t } = useTranslation();
const dispatch = useDispatch();
const [isDragging, setIsDragging] = useState(false);
const accounts = useAccounts();
const failedAccounts = useFailedAccounts();
const updatedAccounts = useUpdatedAccounts();
const offbudgetAccounts = useOffBudgetAccounts();
Expand All @@ -43,126 +36,156 @@ export function Accounts({
(state: State) => state.account.accountsSyncing,
);

const getAccountPath = account => `/accounts/${account.id}`;
const getAccountPath = (account: AccountEntity) => `/accounts/${account.id}`;
tlesicka marked this conversation as resolved.
Show resolved Hide resolved

const [showClosedAccounts] = useLocalPref('ui.showClosedAccounts');
const [showClosedAccounts, setShowClosedAccountsPref] = useLocalPref(
'ui.showClosedAccounts',
);

function onDragChange(drag) {
function onDragChange(drag: { state: string }) {
setIsDragging(drag.state === 'start');
}

const makeDropPadding = i => {
const makeDropPadding = (i: number) => {
if (i === 0) {
return {
paddingTop: isDragging ? 15 : 0,
marginTop: isDragging ? -15 : 0,
};
}
return null;
return undefined;
};

async function onReorder(
id: string,
dropPos: 'top' | 'bottom',
targetId: unknown,
) {
tlesicka marked this conversation as resolved.
Show resolved Hide resolved
let targetIdToMove = targetId;
if (dropPos === 'bottom') {
const idx = accounts.findIndex(a => a.id === targetId) + 1;
targetIdToMove = idx < accounts.length ? accounts[idx].id : null;
}

dispatch(moveAccount(id, targetIdToMove));
}
tlesicka marked this conversation as resolved.
Show resolved Hide resolved
tlesicka marked this conversation as resolved.
Show resolved Hide resolved

const onToggleClosedAccounts = () => {
setShowClosedAccountsPref(!showClosedAccounts);
};

return (
<View>
<Account
name={t('All accounts')}
to="/accounts"
query={queries.allAccountBalance()}
style={{ fontWeight, marginTop: 15 }}
<View
style={{
flexGrow: 1,
'@media screen and (max-height: 480px)': {
minHeight: 'auto',
},
}}
>
<View
style={{
height: 1,
backgroundColor: theme.sidebarItemBackgroundHover,
marginTop: 15,
flexShrink: 0,
}}
/>

{budgetedAccounts.length > 0 && (
<View style={{ overflow: 'auto' }}>
<Account
name={t('For budget')}
to="/accounts/budgeted"
query={queries.budgetedAccountBalance()}
style={{
fontWeight,
marginTop: 13,
marginBottom: 5,
}}
name={t('All accounts')}
to="/accounts"
query={queries.allAccountBalance()}
style={{ fontWeight, marginTop: 15 }}
/>
)}

{budgetedAccounts.map((account, i) => (
<Account
key={account.id}
name={account.name}
account={account}
connected={!!account.bank}
pending={syncingAccountIds.includes(account.id)}
failed={failedAccounts && failedAccounts.has(account.id)}
updated={updatedAccounts && updatedAccounts.includes(account.id)}
to={getAccountPath(account)}
query={queries.accountBalance(account)}
onDragChange={onDragChange}
onDrop={onReorder}
outerStyle={makeDropPadding(i)}
/>
))}
{budgetedAccounts.length > 0 && (
<Account
name={t('For budget')}
to="/accounts/budgeted"
query={queries.budgetedAccountBalance()}
style={{
fontWeight,
marginTop: 13,
marginBottom: 5,
}}
/>
)}

{offbudgetAccounts.length > 0 && (
<Account
name={t('Off budget')}
to="/accounts/offbudget"
query={queries.offbudgetAccountBalance()}
style={{
fontWeight,
marginTop: 13,
marginBottom: 5,
}}
/>
)}
{budgetedAccounts.map((account, i) => (
<Account
key={account.id}
name={account.name}
account={account}
connected={!!account.bank}
pending={syncingAccountIds.includes(account.id)}
failed={failedAccounts?.has(account.id)}
updated={updatedAccounts?.includes(account.id)}
to={getAccountPath(account)}
query={queries.accountBalance(account)}
onDragChange={onDragChange}
onDrop={onReorder}
outerStyle={makeDropPadding(i)}
/>
))}

{offbudgetAccounts.map((account, i) => (
<Account
key={account.id}
name={account.name}
account={account}
connected={!!account.bank}
pending={syncingAccountIds.includes(account.id)}
failed={failedAccounts && failedAccounts.has(account.id)}
updated={updatedAccounts && updatedAccounts.includes(account.id)}
to={getAccountPath(account)}
query={queries.accountBalance(account)}
onDragChange={onDragChange}
onDrop={onReorder}
outerStyle={makeDropPadding(i)}
/>
))}

{closedAccounts.length > 0 && (
<SecondaryItem
style={{ marginTop: 15 }}
title={
showClosedAccounts ? t('Closed accounts') : t('Closed accounts...')
}
onClick={onToggleClosedAccounts}
bold
/>
)}
{offbudgetAccounts.length > 0 && (
<Account
name={t('Off budget')}
to="/accounts/offbudget"
query={queries.offbudgetAccountBalance()}
style={{
fontWeight,
marginTop: 13,
marginBottom: 5,
}}
/>
)}

{showClosedAccounts &&
closedAccounts.map(account => (
{offbudgetAccounts.map((account, i) => (
<Account
key={account.id}
name={account.name}
account={account}
connected={!!account.bank}
pending={syncingAccountIds.includes(account.id)}
failed={failedAccounts?.has(account.id)}
updated={updatedAccounts?.includes(account.id)}
to={getAccountPath(account)}
query={queries.accountBalance(account)}
onDragChange={onDragChange}
onDrop={onReorder}
outerStyle={makeDropPadding(i)}
/>
))}

<SecondaryItem
style={{
marginTop: 15,
marginBottom: 9,
}}
onClick={onAddAccount}
Icon={SvgAdd}
title={t('Add account')}
/>
{closedAccounts.length > 0 && (
<SecondaryItem
style={{ marginTop: 15 }}
title={
showClosedAccounts
? t('Closed accounts')
: t('Closed accounts...')
}
onClick={onToggleClosedAccounts}
bold
/>
)}

{showClosedAccounts &&
closedAccounts.map(account => (
<Account
key={account.id}
name={account.name}
account={account}
to={getAccountPath(account)}
query={queries.accountBalance(account)}
onDragChange={onDragChange}
onDrop={onReorder}
/>
))}
</View>
</View>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import {
SvgCheveronDown,
SvgCheveronRight,
SvgCog,
SvgReports,
SvgStoreFront,
SvgTuning,
SvgWallet,
} from '../../icons/v1';
import { SvgCalendar } from '../../icons/v2';
import { View } from '../common/View';

import { Item } from './Item';
import { SecondaryItem } from './SecondaryItem';

export function Tools() {
export function PrimaryButtons() {
const { t } = useTranslation();
const [isOpen, setOpen] = useState(false);
const onToggle = useCallback(() => setOpen(open => !open), []);
Expand All @@ -28,10 +31,13 @@ export function Tools() {
if (isActive) {
setOpen(true);
}
}, [location.pathname]);
}, [isActive, location.pathname]);

return (
<View style={{ flexShrink: 0 }}>
<Item title={t('Budget')} Icon={SvgWallet} to="/budget" />
<Item title={t('Reports')} Icon={SvgReports} to="/reports" />
<Item title={t('Schedules')} Icon={SvgCalendar} to="/schedules" />
<Item
title="More"
Icon={isOpen ? SvgCheveronDown : SvgCheveronRight}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { type ComponentType, type SVGProps } from 'react';

import { View } from '../common/View';

import { SecondaryItem } from './SecondaryItem';

type SecondaryButtonItems = {
title: string;
Icon:
| ComponentType<SVGProps<SVGElement>>
| ComponentType<SVGProps<SVGSVGElement>>;
onClick: () => void;
};

type SecondaryButtonsProps = {
buttons: Array<SecondaryButtonItems>;
};

export function SecondaryButtons({ buttons }: SecondaryButtonsProps) {
return (
<View
style={{
flexShrink: 0,
padding: '5px 0',
}}
>
{buttons.map(item => (
<SecondaryItem
key={item.title}
title={item.title}
Icon={item.Icon}
onClick={item.onClick}
/>
))}
</View>
);
}
Loading