diff --git a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png index 4e52ef1c12cfc0a07ce6b792971e89c29e6a17b3..32c77b8ac70867d01f65e581272fe96083dc16cb 100644 Binary files a/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png and b/packages/desktop-client/e2e/mobile.test.js-snapshots/Mobile-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png differ diff --git a/packages/desktop-client/src/components/budget/MobileBudgetTable.js b/packages/desktop-client/src/components/budget/MobileBudgetTable.js index 0b27c37b4f17d6cdf1c4dd4490bcfa45cb512efa..6f8dbf39bcea5cd7330172632c0fe848e0d3c669 100644 --- a/packages/desktop-client/src/components/budget/MobileBudgetTable.js +++ b/packages/desktop-client/src/components/budget/MobileBudgetTable.js @@ -1,4 +1,5 @@ import React, { Component, memo, PureComponent, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; // import { // RectButton, // PanGestureHandler, @@ -9,6 +10,7 @@ import React, { Component, memo, PureComponent, useState } from 'react'; import memoizeOne from 'memoize-one'; +import { savePrefs } from 'loot-core/src/client/actions'; import { rolloverBudget, reportBudget } from 'loot-core/src/client/queries'; import * as monthUtils from 'loot-core/src/shared/months'; import { amountToInteger, integerToAmount } from 'loot-core/src/shared/util'; @@ -16,6 +18,7 @@ import { amountToInteger, integerToAmount } from 'loot-core/src/shared/util'; import Add from '../../icons/v1/Add'; import ArrowThinLeft from '../../icons/v1/ArrowThinLeft'; import ArrowThinRight from '../../icons/v1/ArrowThinRight'; +import { useResponsive } from '../../ResponsiveProvider'; import { colors, styles } from '../../style'; import Button from '../common/Button'; import Card from '../common/Card'; @@ -71,7 +74,13 @@ function Saved({ projected }) { let isNegative = saved < 0; return ( - <View style={{ flexDirection: 'column', alignItems: 'flex-start' }}> + <View + style={{ + flexDirection: 'column', + alignItems: 'flex-start', + flexBasis: '80px', + }} + > {projected ? ( <Label title="PROJECTED SAVINGS" style={{ color: colors.n1 }} /> ) : ( @@ -237,45 +246,26 @@ class BudgetCategory extends PureComponent { super(props); let { editMode, blank } = props; - // this.opacity = new Animated.Value(editMode || blank ? 0 : 1); this.opacity = editMode || blank ? 0 : 1; } - // componentDidUpdate(prevProps) { - // if (prevProps.editing !== this.props.editing) { - // if (this.props.editing && ACTScrollViewManager) { - // ACTScrollViewManager.setFocused(findNodeHandle(this.container)); - // } - // } - - // if (prevProps.editMode !== this.props.editMode) { - // Animated.timing(this.opacity, { - // toValue: this.props.editMode ? 0 : 1, - // duration: 200, - // easing: Easing.inOut(Easing.ease) - // }).start(); - // } - // } - render() { let { category, editing, index, - // gestures, - // editMode, style, month, - // onEdit, onBudgetAction, + show3Cols, + showBudgetedCol, } = this.props; - let budgeted = rolloverBudget.catBudgeted(category.id); let balance = rolloverBudget.catBalance(category.id); + let spent = rolloverBudget.catSumAmount(category.id); let content = !category.hidden && ( <ListItem - // ref={el => (this.container = el)} style={{ backgroundColor: editing ? colors.p11 : 'transparent', borderBottomWidth: 0, @@ -289,13 +279,6 @@ class BudgetCategory extends PureComponent { {category.name} </Text> </View> - {/* <Animated.View - style={{ - flexDirection: 'row', - alignItems: 'center', - opacity: this.opacity - }} - > */} <View style={{ alignItems: 'center', @@ -303,16 +286,30 @@ class BudgetCategory extends PureComponent { opacity: this.opacity, }} > - <BudgetCell - name="budgeted" - binding={budgeted} - editing={editing} - style={{ width: 90 }} - textStyle={{ ...styles.smallText, textAlign: 'right' }} - categoryId={category.id} - month={month} - onBudgetAction={onBudgetAction} - /> + {show3Cols || showBudgetedCol ? ( + <BudgetCell + name="budgeted" + binding={budgeted} + editing={editing} + style={{ width: 90 }} + textStyle={{ ...styles.smallText, textAlign: 'right' }} + categoryId={category.id} + month={month} + onBudgetAction={onBudgetAction} + /> + ) : null} + {show3Cols || !showBudgetedCol ? ( + <CellValue + name="spent" + binding={spent} + style={{ + ...styles.smallText, + width: 90, + textAlign: 'right', + }} + type="financial" + /> + ) : null} <CellValue name="balance" binding={balance} @@ -325,7 +322,6 @@ class BudgetCategory extends PureComponent { type="financial" /> </View> - {/* </Animated.View> */} </ListItem> ); @@ -383,8 +379,8 @@ class TotalsRow extends PureComponent { // } render() { - let { group, editMode, onAddCategory } = this.props; - + let { group, editMode, onAddCategory, show3Cols, showBudgetedCol } = + this.props; let content = ( <ListItem style={{ @@ -416,16 +412,30 @@ class TotalsRow extends PureComponent { opacity: this.opacity, }} > - <CellValue - binding={rolloverBudget.groupBudgeted(group.id)} - style={{ - ...styles.smallText, - width: 90, - fontWeight: '500', - textAlign: 'right', - }} - type="financial" - /> + {show3Cols || showBudgetedCol ? ( + <CellValue + binding={rolloverBudget.groupBudgeted(group.id)} + style={{ + ...styles.smallText, + width: 90, + fontWeight: '500', + textAlign: 'right', + }} + type="financial" + /> + ) : null} + {show3Cols || !showBudgetedCol ? ( + <CellValue + binding={rolloverBudget.groupSumAmount(group.id)} + style={{ + ...styles.smallText, + width: 90, + fontWeight: '500', + textAlign: 'right', + }} + type="financial" + /> + ) : null} <CellValue binding={rolloverBudget.groupBalance(group.id)} style={{ @@ -485,7 +495,6 @@ class TotalsRow extends PureComponent { // </Droppable> } } - class IncomeCategory extends PureComponent { render() { const { @@ -597,6 +606,8 @@ class BudgetGroup extends PureComponent { // onReorderGroup, onAddCategory, onBudgetAction, + showBudgetedCol, + show3Cols, } = this.props; function editable(content) { @@ -637,8 +648,10 @@ class BudgetGroup extends PureComponent { > <TotalsRow group={group} + showBudgetedCol={showBudgetedCol} budgeted={rolloverBudget.groupBudgeted(group.id)} balance={rolloverBudget.groupBalance(group.id)} + show3Cols={show3Cols} editMode={editMode} onAddCategory={onAddCategory} onReorderCategory={onReorderCategory} @@ -648,9 +661,11 @@ class BudgetGroup extends PureComponent { // const editing = editingId === category.id; return ( <BudgetCategory + show3Cols={show3Cols} key={category.id} index={index} category={category} + showBudgetedCol={showBudgetedCol} editing={undefined} //editing} editMode={editMode} //gestures={gestures} @@ -754,6 +769,8 @@ class BudgetGroups extends Component { onReorderCategory, onReorderGroup, onBudgetAction, + showBudgetedCol, + show3Cols, } = this.props; const { incomeGroup, expenseGroups } = this.getGroups(categoryGroups); @@ -768,6 +785,7 @@ class BudgetGroups extends Component { key={group.id} group={group} editingId={editingId} + showBudgetedCol={showBudgetedCol} editMode={undefined} //editMode} gestures={gestures} month={month} @@ -776,6 +794,7 @@ class BudgetGroups extends Component { onReorderCategory={onReorderCategory} onReorderGroup={onReorderGroup} onBudgetAction={onBudgetAction} + show3Cols={show3Cols} /> ); })} @@ -788,11 +807,11 @@ class BudgetGroups extends Component { export function BudgetTable(props) { const [editingCategory, setEditingCategory] = useState(null); - function onEditCategory(id) { setEditingCategory(id); } - + const { width } = useResponsive(); + const show3Cols = width >= 360; const { type, categoryGroups, @@ -815,11 +834,40 @@ export function BudgetTable(props) { let currentMonth = monthUtils.currentMonth(); let format = useFormat(); + const mobileShowBudgetedColPref = useSelector(state => { + return ( + (state.prefs.local && state.prefs.local.toggleMobileDisplayPref) || true + ); + }); + + let [showBudgetedCol, setShowBudgetedCol] = useState( + !mobileShowBudgetedColPref && + !document.cookie.match(/mobileShowBudgetedColPref=true/), + ); + + let dispatch = useDispatch(); + + function toggleDisplay() { + setShowBudgetedCol(!showBudgetedCol); + if (!showBudgetedCol) { + // remember the pref indefinitely + dispatch(savePrefs({ mobileShowBudgetedColPref: true })); + } + } + let buttonStyle = { + padding: 0, + backgroundColor: 'transparent', + borderRadius: 'unset', + }; + return ( <NamespaceContext.Provider value={monthUtils.sheetForMonth(month, type)}> <View style={{ flex: 1, overflowY: 'hidden' }} data-testid="budget-table"> <BudgetHeader + show3Cols={show3Cols} currentMonth={month} + toggleDisplay={toggleDisplay} + showBudgetedCol={showBudgetedCol} monthBounds={monthBounds} editMode={editMode} onDone={() => onEditMode(false)} @@ -847,23 +895,62 @@ export function BudgetTable(props) { /> )} <View style={{ flex: 1 }} /> - - <View style={{ width: 90, justifyContent: 'center' }}> - <Label title="BUDGETED" style={{ color: colors.n1 }} /> - <CellValue - binding={reportBudget.totalBudgetedExpense} - type="financial" - style={{ - ...styles.smallText, - color: colors.n1, - textAlign: 'right', - fontWeight: '500', - }} - formatter={value => { - return format(-parseFloat(value || '0'), 'financial'); - }} - /> - </View> + <Button + type="bare" + disabled={show3Cols} + onClick={toggleDisplay} + style={{ + ...buttonStyle, + padding: '0 8px', + margin: '0 -8px', + background: + showBudgetedCol && !show3Cols + ? `linear-gradient(-45deg, ${colors.p5} 8px, transparent 0)` + : !show3Cols + ? `linear-gradient(45deg, ${colors.p5} 8px, transparent 0)` + : null, + // 45deg to flip it to the lower left corner + }} + > + {show3Cols || showBudgetedCol ? ( + <View style={{ width: 90, justifyContent: 'center' }}> + <Label title="BUDGETED" style={{ color: colors.n1 }} /> + <CellValue + binding={reportBudget.totalBudgetedExpense} + type="financial" + style={{ + ...styles.smallText, + color: colors.n1, + textAlign: 'right', + fontWeight: '500', + }} + formatter={value => { + return format(-parseFloat(value || '0'), 'financial'); + }} + /> + </View> + ) : null} + {show3Cols || !showBudgetedCol ? ( + <View + style={{ + width: 90, + justifyContent: 'center', + }} + > + <Label title="SPENT" style={{ color: colors.n1 }} /> + <CellValue + binding={rolloverBudget.totalSpent} + type="financial" + style={{ + ...styles.smallText, + color: colors.n1, + textAlign: 'right', + fontWeight: '500', + }} + /> + </View> + ) : null} + </Button> <View style={{ width: 90, @@ -899,6 +986,8 @@ export function BudgetTable(props) { categoryGroups={categoryGroups} editingId={editingCategory} editMode={editMode} + showBudgetedCol={showBudgetedCol} + show3Cols={show3Cols} // gestures={gestures} month={month} onEditCategory={onEditCategory} @@ -922,6 +1011,8 @@ export function BudgetTable(props) { <View> <BudgetGroups categoryGroups={categoryGroups} + showBudgetedCol={showBudgetedCol} + show3Cols={show3Cols} editingId={editingCategory} editMode={editMode} // gestures={gestures} @@ -950,6 +1041,9 @@ function BudgetHeader({ onDone, onPrevMonth, onNextMonth, + toggleDisplay, + showBudgetedCol, + show3Cols, }) { let serverURL = useServerURL(); diff --git a/upcoming-release-notes/1651.md b/upcoming-release-notes/1651.md new file mode 100644 index 0000000000000000000000000000000000000000..c73a84ef356fc6fef4b93e9b24e6db49e7792b0b --- /dev/null +++ b/upcoming-release-notes/1651.md @@ -0,0 +1,6 @@ +--- +category: Features +authors: [Crazypkr1099] +--- + +Add spent column to mobile view