From 1278746ff2b3a783be176f0d3cb0308a9b98c6bd Mon Sep 17 00:00:00 2001 From: Jed Fox Date: Wed, 11 Jan 2023 17:21:52 -0500 Subject: [PATCH] Further iteration on the sidebar design (#440) --- .../src/components/SidebarWithData.js | 1 + .../loot-design/src/components/sidebar.js | 263 ++++++++++-------- 2 files changed, 150 insertions(+), 114 deletions(-) diff --git a/packages/desktop-client/src/components/SidebarWithData.js b/packages/desktop-client/src/components/SidebarWithData.js index 0c35a02b31..831c7f03d7 100644 --- a/packages/desktop-client/src/components/SidebarWithData.js +++ b/packages/desktop-client/src/components/SidebarWithData.js @@ -94,6 +94,7 @@ function SidebarWithData({ failedAccounts={failedAccounts} updatedAccounts={updatedAccounts} getBalanceQuery={queries.accountBalance} + getAllAccountBalance={queries.allAccountBalance} getOnBudgetBalance={queries.budgetedAccountBalance} getOffBudgetBalance={queries.offbudgetAccountBalance} onFloat={() => saveGlobalPrefs({ floatingSidebar: !floatingSidebar })} diff --git a/packages/loot-design/src/components/sidebar.js b/packages/loot-design/src/components/sidebar.js index 163ecc3372..290b5801e2 100644 --- a/packages/loot-design/src/components/sidebar.js +++ b/packages/loot-design/src/components/sidebar.js @@ -1,23 +1,25 @@ -import React, { useState, useMemo, useCallback } from 'react'; +import React, { useState, useMemo, useCallback, useEffect } from 'react'; import { RectButton } from 'react-native-gesture-handler'; import { useDispatch } from 'react-redux'; -import { useLocation, useHistory } from 'react-router'; +import { useLocation } from 'react-router'; import { withRouter } from 'react-router-dom'; import { css } from 'glamor'; import { closeBudget } from 'loot-core/src/client/actions/budgets'; import Platform from 'loot-core/src/client/platform'; -import PiggyBank from 'loot-design/src/svg/v1/PiggyBank'; import { styles, colors } from '../style'; import Add from '../svg/v1/Add'; -import ChevronRight from '../svg/v1/CheveronRight'; +import CheveronDown from '../svg/v1/CheveronDown'; +import CheveronRight from '../svg/v1/CheveronRight'; import Cog from '../svg/v1/Cog'; import DotsHorizontalTriple from '../svg/v1/DotsHorizontalTriple'; +import LoadBalancer from '../svg/v1/LoadBalancer'; import Reports from '../svg/v1/Reports'; +import StoreFrontIcon from '../svg/v1/StoreFront'; +import TuningIcon from '../svg/v1/Tuning'; import Wallet from '../svg/v1/Wallet'; -import Wrench from '../svg/v1/Wrench'; import ArrowButtonLeft1 from '../svg/v2/ArrowButtonLeft1'; import CalendarIcon from '../svg/v2/Calendar'; import { @@ -35,9 +37,11 @@ import CellValue from './spreadsheet/CellValue'; export const SIDEBAR_WIDTH = 240; +const fontWeight = 600; + function Item({ children, - icon, + Icon, title, style, indent = 0, @@ -79,7 +83,7 @@ function Item({ height: 20 }} > - {icon} + {title} {button} @@ -108,6 +112,70 @@ function Item({ ); } +function SecondaryItem({ + Icon, + title, + style, + to, + exact, + onClick, + bold, + indent = 0 +}) { + const hoverStyle = { + backgroundColor: colors.n2 + }; + const activeStyle = { + borderLeft: '4px solid ' + colors.p8, + paddingLeft: 14 - 4 + indent, + color: colors.p8, + fontWeight: bold ? fontWeight : null + }; + const linkStyle = [ + accountNameStyle, + { + color: colors.n9, + paddingLeft: 14 + indent, + fontWeight: bold ? fontWeight : null + }, + { ':hover': hoverStyle } + ]; + + const content = ( + + {Icon && } + + {title} + + + ); + + return ( + + {onClick ? ( + + {content} + + ) : ( + + {content} + + )} + + ); +} + let accountNameStyle = [ { marginTop: -2, @@ -179,7 +247,7 @@ function Account({ // has unread transactions. The system does mark is read and // unbolds it, but it still "flashes" bold so this just // ignores it if it's active - fontWeight: 'normal', + fontWeight: (style && style.fontWeight) || 'normal', '& .dot': { backgroundColor: colors.p8, transform: 'translateX(-4.5px)' @@ -218,7 +286,7 @@ function Account({ } /> - {' '} + ); @@ -229,9 +297,11 @@ function Accounts({ failedAccounts, updatedAccounts, getAccountPath, + allAccountsPath, budgetedAccountPath, offBudgetAccountPath, getBalanceQuery, + getAllAccountBalance, getOnBudgetBalance, getOffBudgetBalance, showClosedAccounts, @@ -269,22 +339,25 @@ function Accounts({ paddingTop: isDragging ? 15 : 0, marginTop: isDragging ? -15 : 0 }; - } else if (i === length - 1) { - return { - paddingBottom: 15 - }; } return null; }; return ( + + {budgetedAccounts.length > 0 && ( )} @@ -309,7 +382,7 @@ function Accounts({ name="Off budget" to={offBudgetAccountPath} query={getOffBudgetBalance()} - style={{ color: colors.n6 }} + style={{ fontWeight, marginTop: 13 }} /> )} @@ -330,22 +403,12 @@ function Accounts({ ))} {closedAccounts.length > 0 && ( - - {'Closed Accounts' + (showClosedAccounts ? '' : '...')} - + bold + /> )} {showClosedAccounts && @@ -360,6 +423,16 @@ function Accounts({ onDrop={onReorder} /> ))} + + ); } @@ -431,64 +504,49 @@ const MenuButton = withRouter(function MenuButton({ history }) { function Tools() { let [isOpen, setOpen] = useState(false); - let location = useLocation(); - let history = useHistory(); let onToggle = useCallback(() => setOpen(open => !open), []); + let location = useLocation(); - let items = [ - { name: 'payees', text: 'Payees' }, - { name: 'rules', text: 'Rules' }, - { name: 'repair-splits', text: 'Repair split transactions' } - ]; - - let onMenuSelect = useCallback( - type => { - switch (type) { - case 'payees': - history.push('/payees'); - break; - case 'rules': - history.push('/rules'); - break; - case 'repair-splits': - history.push('/tools/fix-splits', { locationPtr: history.location }); - break; - default: - } - setOpen(false); - }, - [history] + const isActive = ['/payees', '/rules', '/tools'].some(route => + location.pathname.startsWith(route) ); + useEffect(() => { + if (isActive) { + setOpen(true); + } + }, [location.pathname]); + return ( } - exact={true} + title="More" + Icon={isOpen ? CheveronDown : CheveronRight} onClick={onToggle} - style={{ pointerEvents: isOpen ? 'none' : 'auto' }} - forceHover={isOpen} - forceActive={['/payees', '/rules', '/tools'].some(route => - location.pathname.startsWith(route) - )} - button={ - - } + style={{ marginBottom: isOpen ? 8 : 0 }} + forceActive={!isOpen && isActive} /> {isOpen && ( - - - + <> + + + + )} ); @@ -501,6 +559,7 @@ export function Sidebar({ failedAccounts, updatedAccounts, getBalanceQuery, + getAllAccountBalance, getOnBudgetBalance, getOffBudgetBalance, showClosedAccounts, @@ -589,46 +648,20 @@ export function Sidebar({ - } - to="/budget" - /> - } - to="/reports" - /> + + - - } - to="/schedules" - /> + - - } - exact={true} - button={ - - } + `/accounts/${account.id}`} + allAccountsPath="/accounts" budgetedAccountPath="/accounts/budgeted" offBudgetAccountPath="/accounts/offbudget" getBalanceQuery={getBalanceQuery} + getAllAccountBalance={getAllAccountBalance} getOnBudgetBalance={getOnBudgetBalance} getOffBudgetBalance={getOffBudgetBalance} showClosedAccounts={showClosedAccounts}