From cceda0390551e9b1a658a10927450e09eec468bd Mon Sep 17 00:00:00 2001 From: Neil <55785687+carkom@users.noreply.github.com> Date: Thu, 25 Jul 2024 09:35:44 +0100 Subject: [PATCH] Spending Report: add save button (#3112) * add save button * notes * rerun checks * add time * tooltips * change entity to string * lint fix * adjust defaults * lint --- .../src/components/reports/ReportSidebar.tsx | 15 ++++- .../components/reports/reports/Spending.tsx | 58 ++++++++++++++++++- .../reports/reports/SpendingCard.tsx | 10 +++- packages/loot-core/src/types/prefs.d.ts | 2 + upcoming-release-notes/3112.md | 6 ++ 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 upcoming-release-notes/3112.md diff --git a/packages/desktop-client/src/components/reports/ReportSidebar.tsx b/packages/desktop-client/src/components/reports/ReportSidebar.tsx index 230bc01a6..5c9971430 100644 --- a/packages/desktop-client/src/components/reports/ReportSidebar.tsx +++ b/packages/desktop-client/src/components/reports/ReportSidebar.tsx @@ -6,12 +6,14 @@ import { type CategoryGroupEntity } from 'loot-core/types/models/category-group' import { type CustomReportEntity } from 'loot-core/types/models/reports'; import { type LocalPrefs } from 'loot-core/types/prefs'; +import { styles } from '../../style/styles'; import { theme } from '../../style/theme'; import { Button } from '../common/Button'; import { Menu } from '../common/Menu'; import { Popover } from '../common/Popover'; import { Select } from '../common/Select'; import { Text } from '../common/Text'; +import { Tooltip } from '../common/Tooltip'; import { View } from '../common/View'; import { CategorySelector } from './CategorySelector'; @@ -437,7 +439,18 @@ export function ReportSidebar({ /> {!disabledList.currentInterval.get(customReportItems.dateRange) && customReportItems.includeCurrentInterval && ( - <Text style={{ marginLeft: 10 }}>+1</Text> + <Tooltip + placement="bottom start" + content={<Text>Current month</Text>} + style={{ + ...styles.tooltip, + lineHeight: 1.5, + padding: '6px 10px', + marginTop: 5, + }} + > + <Text style={{ marginLeft: 10 }}>+1</Text> + </Tooltip> )} </View> ) : ( diff --git a/packages/desktop-client/src/components/reports/reports/Spending.tsx b/packages/desktop-client/src/components/reports/reports/Spending.tsx index bfecccbd1..0800df9e3 100644 --- a/packages/desktop-client/src/components/reports/reports/Spending.tsx +++ b/packages/desktop-client/src/components/reports/reports/Spending.tsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo } from 'react'; +import React, { useState, useMemo, useEffect } from 'react'; import * as monthUtils from 'loot-core/src/shared/months'; import { amountToCurrency } from 'loot-core/src/shared/util'; @@ -6,13 +6,16 @@ import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useCategories } from '../../../hooks/useCategories'; import { useFilters } from '../../../hooks/useFilters'; +import { useLocalPref } from '../../../hooks/useLocalPref'; import { useNavigate } from '../../../hooks/useNavigate'; import { useResponsive } from '../../../ResponsiveProvider'; import { theme, styles } from '../../../style'; import { AlignedText } from '../../common/AlignedText'; import { Block } from '../../common/Block'; +import { Button } from '../../common/Button'; import { Paragraph } from '../../common/Paragraph'; import { Text } from '../../common/Text'; +import { Tooltip } from '../../common/Tooltip'; import { View } from '../../common/View'; import { AppliedFilters } from '../../filters/AppliedFilters'; import { FilterButton } from '../../filters/FiltersMenu'; @@ -37,8 +40,28 @@ export function Spending() { onConditionsOpChange, } = useFilters<RuleConditionEntity>(); + const [spendingReportFilter = '', setSpendingReportFilter] = useLocalPref( + 'spendingReportFilter', + ); + const [spendingReportTime = 'lastMonth', setSpendingReportTime] = + useLocalPref('spendingReportTime'); + const [dataCheck, setDataCheck] = useState(false); - const [mode, setMode] = useState('lastMonth'); + const [mode, setMode] = useState(spendingReportTime); + + const parseFilter = spendingReportFilter && JSON.parse(spendingReportFilter); + const filterSaved = + JSON.stringify(parseFilter.conditions) === JSON.stringify(conditions) && + parseFilter.conditionsOp === conditionsOp && + spendingReportTime === mode; + + useEffect(() => { + const checkFilter = + spendingReportFilter && JSON.parse(spendingReportFilter); + if (checkFilter.conditions) { + onApplyFilter(checkFilter); + } + }, [onApplyFilter, spendingReportFilter]); const getGraphData = useMemo(() => { setDataCheck(false); @@ -58,6 +81,16 @@ export function Spending() { return null; } + const saveFilter = () => { + setSpendingReportFilter( + JSON.stringify({ + conditionsOp, + conditions, + }), + ); + setSpendingReportTime(mode); + }; + const showAverage = Math.abs( data.intervalData[27].months[ @@ -108,6 +141,27 @@ export function Spending() { hover={false} exclude={['date']} /> + <Tooltip + placement="bottom start" + content={<Text>Save compare and filter options</Text>} + style={{ + ...styles.tooltip, + lineHeight: 1.5, + padding: '6px 10px', + marginLeft: 10, + }} + > + <Button + type="primary" + style={{ + marginLeft: 10, + }} + onClick={saveFilter} + disabled={filterSaved ? true : false} + > + {filterSaved ? 'Saved' : 'Save'} + </Button> + </Tooltip> <View style={{ flex: 1 }} /> </View> )} diff --git a/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx b/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx index 2796261d1..57bbf6ad1 100644 --- a/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx +++ b/packages/desktop-client/src/components/reports/reports/SpendingCard.tsx @@ -4,6 +4,7 @@ import * as monthUtils from 'loot-core/src/shared/months'; import { amountToCurrency } from 'loot-core/src/shared/util'; import { useCategories } from '../../../hooks/useCategories'; +import { useLocalPref } from '../../../hooks/useLocalPref'; import { styles } from '../../../style/styles'; import { theme } from '../../../style/theme'; import { Block } from '../../common/Block'; @@ -20,12 +21,17 @@ export function SpendingCard() { const categories = useCategories(); const [isCardHovered, setIsCardHovered] = useState(false); + const [spendingReportFilter = ''] = useLocalPref('spendingReportFilter'); + const [spendingReportTime = 'lastMonth'] = useLocalPref('spendingReportTime'); + const parseFilter = spendingReportFilter && JSON.parse(spendingReportFilter); const getGraphData = useMemo(() => { return createSpendingSpreadsheet({ categories, + conditions: parseFilter.conditions, + conditionsOp: parseFilter.conditionsOp, }); - }, [categories]); + }, [categories, parseFilter]); const data = useReport('default', getGraphData); const todayDay = @@ -92,7 +98,7 @@ export function SpendingCard() { style={{ flex: 1 }} compact={true} data={data} - mode="lastMonth" + mode={spendingReportTime} /> ) : ( <LoadingIndicator message="Loading report..." /> diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.d.ts index a8a1dbfca..82cd445a0 100644 --- a/packages/loot-core/src/types/prefs.d.ts +++ b/packages/loot-core/src/types/prefs.d.ts @@ -50,6 +50,8 @@ export type LocalPrefs = Partial< reportsViewLegend: boolean; reportsViewSummary: boolean; reportsViewLabel: boolean; + spendingReportFilter: string; + spendingReportTime: string; sidebarWidth: number; 'mobile.showSpentColumn': boolean; } & Record<`flags.${FeatureFlag}`, boolean> diff --git a/upcoming-release-notes/3112.md b/upcoming-release-notes/3112.md new file mode 100644 index 000000000..88fa4cdaa --- /dev/null +++ b/upcoming-release-notes/3112.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [carkom] +--- + +Add a save button to Spending report so you can keep filter settings between sessions -- GitLab