mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-09 03:32:54 -05:00
Custom reports: make views global (#2094)
* make views global * notes and lint fixes * fixes * lint fix * fix * fix
This commit is contained in:
@@ -5,7 +5,7 @@ import Text from '../common/Text';
|
||||
import View from '../common/View';
|
||||
|
||||
type ReportLegendProps = {
|
||||
legend: Array<{ name: string; color: string }>;
|
||||
legend?: Array<{ name: string; color: string }>;
|
||||
groupBy: string;
|
||||
};
|
||||
|
||||
@@ -31,37 +31,38 @@ function ReportLegend({ legend, groupBy }: ReportLegendProps) {
|
||||
{groupBy}
|
||||
</Text>
|
||||
<View>
|
||||
{legend.map(item => {
|
||||
return (
|
||||
<View
|
||||
key={item.name}
|
||||
style={{
|
||||
padding: 10,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{legend &&
|
||||
legend.map(item => {
|
||||
return (
|
||||
<View
|
||||
key={item.name}
|
||||
style={{
|
||||
marginRight: 5,
|
||||
borderRadius: 1000,
|
||||
width: 14,
|
||||
height: 14,
|
||||
backgroundColor: item.color,
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
flexShrink: 0,
|
||||
padding: 10,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
<View
|
||||
style={{
|
||||
marginRight: 5,
|
||||
borderRadius: 1000,
|
||||
width: 14,
|
||||
height: 14,
|
||||
backgroundColor: item.color,
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
whiteSpace: 'nowrap',
|
||||
textOverflow: 'ellipsis',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -29,7 +29,6 @@ export function ReportSidebar({
|
||||
allMonths,
|
||||
graphType,
|
||||
setGraphType,
|
||||
setViewLegend,
|
||||
typeDisabled,
|
||||
setTypeDisabled,
|
||||
groupBy,
|
||||
@@ -49,6 +48,7 @@ export function ReportSidebar({
|
||||
categories,
|
||||
selectedCategories,
|
||||
setSelectedCategories,
|
||||
onChangeViews,
|
||||
}) {
|
||||
const onSelectRange = cond => {
|
||||
setDateRange(cond);
|
||||
@@ -99,7 +99,7 @@ export function ReportSidebar({
|
||||
}
|
||||
if (['AreaGraph', 'DonutGraph'].includes(graphType)) {
|
||||
setGraphType('TableGraph');
|
||||
setViewLegend(false);
|
||||
onChangeViews('viewLegend', false);
|
||||
}
|
||||
if (['Month', 'Year'].includes(groupBy)) {
|
||||
setGroupBy('Category');
|
||||
|
||||
@@ -130,7 +130,7 @@ function ReportSummary({
|
||||
}}
|
||||
>
|
||||
<PrivacyFilter blurIntensity={7}>
|
||||
{integerToCurrency(Math.round(average))}
|
||||
{!isNaN(average) && integerToCurrency(Math.round(average))}
|
||||
</PrivacyFilter>
|
||||
</Text>
|
||||
<Text style={{ fontWeight: 600 }}>Per month</Text>
|
||||
|
||||
@@ -19,17 +19,15 @@ export function ReportTopbar({
|
||||
setGraphType,
|
||||
mode,
|
||||
viewLegend,
|
||||
setViewLegend,
|
||||
setTypeDisabled,
|
||||
balanceType,
|
||||
setBalanceType,
|
||||
groupBy,
|
||||
setGroupBy,
|
||||
viewSummary,
|
||||
setViewSummary,
|
||||
viewLabels,
|
||||
setViewLabels,
|
||||
onApplyFilter,
|
||||
onChangeViews,
|
||||
}) {
|
||||
return (
|
||||
<View
|
||||
@@ -45,7 +43,7 @@ export function ReportTopbar({
|
||||
title="Data Table"
|
||||
onSelect={() => {
|
||||
setGraphType('TableGraph');
|
||||
setViewLegend(false);
|
||||
onChangeViews('viewLegend', false);
|
||||
setTypeDisabled([]);
|
||||
}}
|
||||
style={{ marginRight: 15 }}
|
||||
@@ -78,7 +76,7 @@ export function ReportTopbar({
|
||||
onSelect={() => {
|
||||
setGraphType('AreaGraph');
|
||||
setGroupBy('Month');
|
||||
setViewLegend(false);
|
||||
onChangeViews('viewLegend', false);
|
||||
setTypeDisabled([]);
|
||||
}}
|
||||
style={{ marginRight: 15 }}
|
||||
@@ -111,7 +109,7 @@ export function ReportTopbar({
|
||||
<GraphButton
|
||||
selected={viewLegend}
|
||||
onSelect={() => {
|
||||
setViewLegend(!viewLegend);
|
||||
onChangeViews('viewLegend');
|
||||
}}
|
||||
style={{ marginRight: 15 }}
|
||||
title="Show Legend"
|
||||
@@ -124,7 +122,7 @@ export function ReportTopbar({
|
||||
<GraphButton
|
||||
selected={viewSummary}
|
||||
onSelect={() => {
|
||||
setViewSummary(!viewSummary);
|
||||
onChangeViews('viewSummary');
|
||||
}}
|
||||
style={{ marginRight: 15 }}
|
||||
title="Show Summary"
|
||||
@@ -134,7 +132,7 @@ export function ReportTopbar({
|
||||
<GraphButton
|
||||
selected={viewLabels}
|
||||
onSelect={() => {
|
||||
setViewLabels(!viewLabels);
|
||||
onChangeViews('viewLabels');
|
||||
}}
|
||||
style={{ marginRight: 15 }}
|
||||
title="Show labels"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import * as d from 'date-fns';
|
||||
|
||||
@@ -8,6 +9,7 @@ import { send } from 'loot-core/src/platform/client/fetch';
|
||||
import * as monthUtils from 'loot-core/src/shared/months';
|
||||
import { amountToCurrency } from 'loot-core/src/shared/util';
|
||||
|
||||
import { useActions } from '../../../hooks/useActions';
|
||||
import useCategories from '../../../hooks/useCategories';
|
||||
import useFilters from '../../../hooks/useFilters';
|
||||
import { theme, styles } from '../../../style';
|
||||
@@ -33,6 +35,14 @@ import { fromDateRepr } from '../util';
|
||||
export default function CustomReport() {
|
||||
const categories = useCategories();
|
||||
|
||||
const viewLegend =
|
||||
useSelector(state => state.prefs.local?.reportsViewLegend) || false;
|
||||
const viewSummary =
|
||||
useSelector(state => state.prefs.local?.reportsViewSummary) || false;
|
||||
const viewLabels =
|
||||
useSelector(state => state.prefs.local?.reportsViewLabel) || false;
|
||||
const { savePrefs } = useActions();
|
||||
|
||||
const {
|
||||
filters,
|
||||
conditionsOp,
|
||||
@@ -61,9 +71,6 @@ export default function CustomReport() {
|
||||
const [dataCheck, setDataCheck] = useState(false);
|
||||
|
||||
const [graphType, setGraphType] = useState('BarGraph');
|
||||
const [viewLegend, setViewLegend] = useState(false);
|
||||
const [viewSummary, setViewSummary] = useState(false);
|
||||
const [viewLabels, setViewLabels] = useState(false);
|
||||
const dateRangeLine = ReportOptions.dateRange.length - 3;
|
||||
const months = monthUtils.rangeInclusive(startDate, endDate);
|
||||
|
||||
@@ -182,6 +189,18 @@ export default function CustomReport() {
|
||||
setEndDate(endDate);
|
||||
};
|
||||
|
||||
const onChangeViews = (viewType, status) => {
|
||||
if (viewType === 'viewLegend') {
|
||||
savePrefs({ reportsViewLegend: status ?? !viewLegend });
|
||||
}
|
||||
if (viewType === 'viewSummary') {
|
||||
savePrefs({ reportsViewSummary: !viewSummary });
|
||||
}
|
||||
if (viewType === 'viewLabels') {
|
||||
savePrefs({ reportsViewLabels: !viewLabels });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={{ ...styles.page, minWidth: 650, overflow: 'hidden' }}>
|
||||
<Header title="Custom Reports" />
|
||||
@@ -204,7 +223,6 @@ export default function CustomReport() {
|
||||
allMonths={allMonths}
|
||||
graphType={graphType}
|
||||
setGraphType={setGraphType}
|
||||
setViewLegend={setViewLegend}
|
||||
typeDisabled={typeDisabled}
|
||||
setTypeDisabled={setTypeDisabled}
|
||||
groupBy={groupBy}
|
||||
@@ -224,6 +242,7 @@ export default function CustomReport() {
|
||||
categories={categories}
|
||||
selectedCategories={selectedCategories}
|
||||
setSelectedCategories={setSelectedCategories}
|
||||
onChangeViews={onChangeViews}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
@@ -235,17 +254,15 @@ export default function CustomReport() {
|
||||
setGraphType={setGraphType}
|
||||
mode={mode}
|
||||
viewLegend={viewLegend}
|
||||
setViewLegend={setViewLegend}
|
||||
setTypeDisabled={setTypeDisabled}
|
||||
balanceType={balanceType}
|
||||
setBalanceType={setBalanceType}
|
||||
groupBy={groupBy}
|
||||
setGroupBy={setGroupBy}
|
||||
viewSummary={viewSummary}
|
||||
setViewSummary={setViewSummary}
|
||||
viewLabels={viewLabels}
|
||||
setViewLabels={setViewLabels}
|
||||
onApplyFilter={onApplyFilter}
|
||||
onChangeViews={onChangeViews}
|
||||
/>
|
||||
{filters && filters.length > 0 && (
|
||||
<View
|
||||
@@ -328,7 +345,7 @@ export default function CustomReport() {
|
||||
<LoadingIndicator message={'Loading report...'} />
|
||||
)}
|
||||
</View>
|
||||
{(viewLegend || viewSummary) && (
|
||||
{(viewLegend || viewSummary) && data && (
|
||||
<View
|
||||
style={{
|
||||
padding: 10,
|
||||
|
||||
3
packages/loot-core/src/types/prefs.d.ts
vendored
3
packages/loot-core/src/types/prefs.d.ts
vendored
@@ -50,6 +50,9 @@ export type LocalPrefs = Partial<
|
||||
userId: string;
|
||||
resetClock: boolean;
|
||||
lastScheduleRun: string;
|
||||
reportsViewLegend: boolean;
|
||||
reportsViewSummary: boolean;
|
||||
reportsViewLabel: boolean;
|
||||
} & Record<`flags.${FeatureFlag}`, boolean>
|
||||
>;
|
||||
|
||||
|
||||
6
upcoming-release-notes/2094.md
Normal file
6
upcoming-release-notes/2094.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Enhancements
|
||||
authors: [carkom]
|
||||
---
|
||||
|
||||
Custom reports: Convert the view options (legend/summary/labels) to global preferences that apply to all graphs.
|
||||
Reference in New Issue
Block a user