Skip to content
Snippets Groups Projects
Unverified Commit cceda039 authored by Neil's avatar Neil Committed by GitHub
Browse files

Spending Report: add save button (#3112)

* add save button

* notes

* rerun checks

* add time

* tooltips

* change entity to string

* lint fix

* adjust defaults

* lint
parent 982f555a
No related branches found
No related tags found
No related merge requests found
......@@ -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>
) : (
......
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>
)}
......
......@@ -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..." />
......
......@@ -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>
......
---
category: Enhancements
authors: [carkom]
---
Add a save button to Spending report so you can keep filter settings between sessions
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment