From 97ec8f8d3a63717e10f18e00a86ee54f9b1a2498 Mon Sep 17 00:00:00 2001 From: Neil <55785687+carkom@users.noreply.github.com> Date: Thu, 18 Apr 2024 20:38:25 +0100 Subject: [PATCH] Custom Reports: Add filters to sessionStorage (#2612) * Add filters to sessionStorage * notes * setSessionReports util --- .../src/components/reports/ChooseGraph.tsx | 5 ++ .../src/components/reports/ReportSidebar.jsx | 89 +++++-------------- .../src/components/reports/ReportTopbar.jsx | 8 +- .../components/reports/graphs/BarGraph.tsx | 4 + .../components/reports/graphs/DonutGraph.tsx | 4 + .../reports/reports/CustomReport.jsx | 44 +++++---- .../components/reports/setSessionReport.ts | 18 ++++ upcoming-release-notes/2612.md | 6 ++ 8 files changed, 90 insertions(+), 88 deletions(-) create mode 100644 packages/desktop-client/src/components/reports/setSessionReport.ts create mode 100644 upcoming-release-notes/2612.md diff --git a/packages/desktop-client/src/components/reports/ChooseGraph.tsx b/packages/desktop-client/src/components/reports/ChooseGraph.tsx index 2a671ffc4..3e294fbff 100644 --- a/packages/desktop-client/src/components/reports/ChooseGraph.tsx +++ b/packages/desktop-client/src/components/reports/ChooseGraph.tsx @@ -2,6 +2,7 @@ import React, { useRef } from 'react'; import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { type CSSProperties } from '../../style'; import { styles } from '../../style/styles'; @@ -20,6 +21,7 @@ import { ReportOptions } from './ReportOptions'; type ChooseGraphProps = { data: GroupedEntity; + filters?: RuleConditionEntity[]; mode: string; graphType: string; balanceType: string; @@ -36,6 +38,7 @@ type ChooseGraphProps = { export function ChooseGraph({ data, + filters, mode, graphType, balanceType, @@ -101,6 +104,7 @@ export function ChooseGraph({ style={graphStyle} compact={compact} data={data} + filters={filters} groupBy={groupBy} balanceTypeOp={balanceTypeOp} viewLabels={viewLabels} @@ -118,6 +122,7 @@ export function ChooseGraph({ style={graphStyle} compact={compact} data={data} + filters={filters} groupBy={groupBy} balanceTypeOp={balanceTypeOp} viewLabels={viewLabels} diff --git a/packages/desktop-client/src/components/reports/ReportSidebar.jsx b/packages/desktop-client/src/components/reports/ReportSidebar.jsx index af3339562..e48fb0be5 100644 --- a/packages/desktop-client/src/components/reports/ReportSidebar.jsx +++ b/packages/desktop-client/src/components/reports/ReportSidebar.jsx @@ -16,6 +16,7 @@ import { getLiveRange } from './getLiveRange'; import { ModeButton } from './ModeButton'; import { ReportOptions } from './ReportOptions'; import { validateEnd, validateStart } from './reportRanges'; +import { setSessionReport } from './setSessionReport'; export function ReportSidebar({ customReportItems, @@ -44,11 +45,7 @@ export function ReportSidebar({ }) { const [menuOpen, setMenuOpen] = useState(false); const onSelectRange = cond => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, dateRange: cond }), - ); + setSessionReport('dateRange', cond); onReportChange({ type: 'modify' }); setDateRange(cond); onChangeDates( @@ -57,29 +54,19 @@ export function ReportSidebar({ }; const onChangeMode = cond => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, mode: cond }), - ); + setSessionReport('mode', cond); onReportChange({ type: 'modify' }); setMode(cond); let graph; if (cond === 'time') { if (customReportItems.graphType === 'BarGraph') { - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, graphType: 'StackedBarGraph' }), - ); + setSessionReport('graphType', 'StackedBarGraph'); setGraphType('StackedBarGraph'); graph = 'StackedBarGraph'; } } else { if (customReportItems.graphType === 'StackedBarGraph') { - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, graphType: 'BarGraph' }), - ); + setSessionReport('graphType', 'BarGraph'); setGraphType('BarGraph'); graph = 'BarGraph'; } @@ -88,22 +75,14 @@ export function ReportSidebar({ }; const onChangeSplit = cond => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, groupBy: cond }), - ); + setSessionReport('groupBy', cond); onReportChange({ type: 'modify' }); setGroupBy(cond); defaultItems(cond); }; const onChangeBalanceType = cond => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, balanceType: cond }), - ); + setSessionReport('balanceType', cond); onReportChange({ type: 'modify' }); setBalanceType(cond); }; @@ -203,6 +182,7 @@ export function ReportSidebar({ <Select value={customReportItems.interval} onChange={e => { + setSessionReport('interval', e); setInterval(e); onReportChange({ type: 'modify' }); if ( @@ -249,49 +229,32 @@ export function ReportSidebar({ > <Menu onMenuSelect={type => { - const storedReport = JSON.parse( - sessionStorage.getItem('report'), - ); onReportChange({ type: 'modify' }); if (type === 'show-hidden-categories') { - sessionStorage.setItem( - 'report', - JSON.stringify({ - ...storedReport, - showHiddenCategories: - !customReportItems.showHiddenCategories, - }), + setSessionReport( + 'showHiddenCategories', + !customReportItems.showHiddenCategories, ); setShowHiddenCategories( !customReportItems.showHiddenCategories, ); } else if (type === 'show-off-budget') { - sessionStorage.setItem( - 'report', - JSON.stringify({ - ...storedReport, - showOffBudget: !customReportItems.showOffBudget, - }), + setSessionReport( + 'showOffBudget', + !customReportItems.showOffBudget, ); setShowOffBudget(!customReportItems.showOffBudget); } else if (type === 'show-empty-items') { - sessionStorage.setItem( - 'report', - JSON.stringify({ - ...storedReport, - showEmpty: !customReportItems.showEmpty, - }), + setSessionReport( + 'showEmpty', + !customReportItems.showEmpty, ); setShowEmpty(!customReportItems.showEmpty); } else if (type === 'show-uncategorized') { - sessionStorage.setItem( - 'report', - JSON.stringify({ - ...storedReport, - showUncategorized: - !customReportItems.showUncategorized, - }), + setSessionReport( + 'showUncategorized', + !customReportItems.showUncategorized, ); setShowUncategorized( !customReportItems.showUncategorized, @@ -352,11 +315,7 @@ export function ReportSidebar({ <ModeButton selected={!customReportItems.isDateStatic} onSelect={() => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, isDateStatic: false }), - ); + setSessionReport('isDateStatic', false); setIsDateStatic(false); onSelectRange(customReportItems.dateRange); }} @@ -366,11 +325,7 @@ export function ReportSidebar({ <ModeButton selected={customReportItems.isDateStatic} onSelect={() => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, isDateStatic: true }), - ); + setSessionReport('isDateStatic', true); setIsDateStatic(true); onChangeDates( customReportItems.startDate, diff --git a/packages/desktop-client/src/components/reports/ReportTopbar.jsx b/packages/desktop-client/src/components/reports/ReportTopbar.jsx index 3a98f00ee..6a78e7d8d 100644 --- a/packages/desktop-client/src/components/reports/ReportTopbar.jsx +++ b/packages/desktop-client/src/components/reports/ReportTopbar.jsx @@ -16,6 +16,7 @@ import { FilterButton } from '../filters/FiltersMenu'; import { GraphButton } from './GraphButton'; import { SaveReport } from './SaveReport'; +import { setSessionReport } from './setSessionReport'; export function ReportTopbar({ customReportItems, @@ -32,11 +33,7 @@ export function ReportTopbar({ defaultItems, }) { const onChangeGraph = cond => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ ...storedReport, graphType: cond }), - ); + setSessionReport('graphType', cond); onReportChange({ type: 'modify' }); setGraphType(cond); defaultItems(cond); @@ -171,6 +168,7 @@ export function ReportTopbar({ compact hover onApply={e => { + setSessionReport('conditions', [...customReportItems.conditions, e]); onApplyFilter(e); onReportChange({ type: 'modify' }); }} diff --git a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx index e9d5252b4..e420579bd 100644 --- a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx @@ -20,6 +20,7 @@ import { amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; import { useCategories } from '../../../hooks/useCategories'; @@ -132,6 +133,7 @@ const customLabel = (props, typeOp) => { type BarGraphProps = { style?: CSSProperties; data: GroupedEntity; + filters: RuleConditionEntity[]; groupBy: string; balanceTypeOp: string; compact?: boolean; @@ -143,6 +145,7 @@ type BarGraphProps = { export function BarGraph({ style, data, + filters, groupBy, balanceTypeOp, compact, @@ -187,6 +190,7 @@ export function BarGraph({ const offBudgetAccounts = accounts.filter(f => f.offbudget).map(e => e.id); const conditions = [ + ...filters, { field, op: 'is', value: item.id, type: 'id' }, { field: 'date', diff --git a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx index f30d2560d..e7fe93c5c 100644 --- a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx @@ -5,6 +5,7 @@ import { PieChart, Pie, Cell, Sector, ResponsiveContainer } from 'recharts'; import { amountToCurrency } from 'loot-core/src/shared/util'; import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; import { useCategories } from '../../../hooks/useCategories'; @@ -176,6 +177,7 @@ const customLabel = props => { type DonutGraphProps = { style?: CSSProperties; data: GroupedEntity; + filters: RuleConditionEntity[]; groupBy: string; balanceTypeOp: string; compact?: boolean; @@ -187,6 +189,7 @@ type DonutGraphProps = { export function DonutGraph({ style, data, + filters, groupBy, balanceTypeOp, compact, @@ -211,6 +214,7 @@ export function DonutGraph({ const offBudgetAccounts = accounts.filter(f => f.offbudget).map(e => e.id); const conditions = [ + ...filters, { field, op: 'is', value: item.id, type: 'id' }, { field: 'date', diff --git a/packages/desktop-client/src/components/reports/reports/CustomReport.jsx b/packages/desktop-client/src/components/reports/reports/CustomReport.jsx index 527ebf375..81292f60e 100644 --- a/packages/desktop-client/src/components/reports/reports/CustomReport.jsx +++ b/packages/desktop-client/src/components/reports/reports/CustomReport.jsx @@ -29,6 +29,7 @@ import { ReportOptions, defaultReport } from '../ReportOptions'; import { ReportSidebar } from '../ReportSidebar'; import { ReportSummary } from '../ReportSummary'; import { ReportTopbar } from '../ReportTopbar'; +import { setSessionReport } from '../setSessionReport'; import { createCustomSpreadsheet } from '../spreadsheets/custom-spreadsheet'; import { createGroupedSpreadsheet } from '../spreadsheets/grouped-spreadsheet'; import { useReport } from '../useReport'; @@ -103,7 +104,11 @@ export function CustomReport() { const [earliestTransaction, setEarliestTransaction] = useState(''); const [report, setReport] = useState(loadReport); const [savedStatus, setSavedStatus] = useState( - location.state ? (location.state.report ? 'saved' : 'new') : 'new', + location.state + ? location.state.report + ? 'saved' + : loadReport.savedStatus ?? 'new' + : loadReport.savedStatus ?? 'new', ); useEffect(() => { @@ -342,15 +347,8 @@ export function CustomReport() { }; const onChangeDates = (dateStart, dateEnd) => { - const storedReport = JSON.parse(sessionStorage.getItem('report')); - sessionStorage.setItem( - 'report', - JSON.stringify({ - ...storedReport, - startDate: dateStart, - endDate: dateEnd, - }), - ); + setSessionReport('startDate', dateStart); + setSessionReport('endDate', dateEnd); setStartDate(dateStart); setEndDate(dateEnd); onReportChange({ type: 'modify' }); @@ -401,6 +399,7 @@ export function CustomReport() { const onReportChange = ({ savedReport, type }) => { switch (type) { case 'add-update': + setSessionReport('savedStatus', 'saved'); setSavedStatus('saved'); setReport(savedReport); break; @@ -409,11 +408,12 @@ export function CustomReport() { break; case 'modify': if (report.name) { + setSessionReport('savedStatus', 'modified'); setSavedStatus('modified'); } break; case 'reload': - sessionStorage.clear(); + setSessionReport('savedStatus', 'saved'); setSavedStatus('saved'); setReportData(report); break; @@ -424,7 +424,7 @@ export function CustomReport() { setReportData(defaultReport); break; case 'choose': - sessionStorage.clear(); + setSessionReport('savedStatus', 'saved'); setSavedStatus('saved'); setReport(savedReport); setReportData(savedReport); @@ -515,10 +515,21 @@ export function CustomReport() { > <AppliedFilters filters={filters} - onUpdate={onUpdateFilter} - onDelete={filter => - onChangeAppliedFilter(filter, onDeleteFilter) - } + onUpdate={(oldFilter, newFilter) => { + setSessionReport( + 'conditions', + filters.map(f => (f === oldFilter ? newFilter : f)), + ); + onReportChange({ type: 'modify' }); + onUpdateFilter(oldFilter, newFilter); + }} + onDelete={deletedFilter => { + setSessionReport( + 'conditions', + filters.filter(f => f !== deletedFilter), + ); + onChangeAppliedFilter(deletedFilter, onDeleteFilter); + }} conditionsOp={conditionsOp} onCondOpChange={filter => onChangeAppliedFilter(filter, onCondOpChange) @@ -578,6 +589,7 @@ export function CustomReport() { {dataCheck ? ( <ChooseGraph data={data} + filters={filters} mode={mode} graphType={graphType} balanceType={balanceType} diff --git a/packages/desktop-client/src/components/reports/setSessionReport.ts b/packages/desktop-client/src/components/reports/setSessionReport.ts new file mode 100644 index 000000000..f1ab555be --- /dev/null +++ b/packages/desktop-client/src/components/reports/setSessionReport.ts @@ -0,0 +1,18 @@ +import { type RuleConditionEntity } from 'loot-core/types/models/rule'; + +export const setSessionReport = ( + propName: string, + propValue: string | boolean | RuleConditionEntity[], +) => { + const storedReport = + sessionStorage.report && JSON.parse(sessionStorage.getItem('report') || ''); + const result: Record<string, string | boolean | RuleConditionEntity[]> = {}; + result[propName] = propValue; + sessionStorage.setItem( + 'report', + JSON.stringify({ + ...storedReport, + ...result, + }), + ); +}; diff --git a/upcoming-release-notes/2612.md b/upcoming-release-notes/2612.md new file mode 100644 index 000000000..6bfd1d29d --- /dev/null +++ b/upcoming-release-notes/2612.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [carkom] +--- + +Fixing some of the sessionStorage issues plus adding filters to sessionStorage. -- GitLab