Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ (dashboards) ability to save filters & timeframes on spending widgets #3432

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions packages/desktop-client/src/components/common/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type SelectProps<Value> = {
disabled?: boolean;
disabledKeys?: Value[];
buttonStyle?: CSSProperties;
popoverStyle?: CSSProperties;
};

/**
Expand All @@ -51,6 +52,7 @@ export function Select<const Value = string>({
disabled = false,
disabledKeys = [],
buttonStyle = {},
popoverStyle = {},
}: SelectProps<Value>) {
const targetOption = options
.filter(isValueOption)
Expand Down Expand Up @@ -111,6 +113,7 @@ export function Select<const Value = string>({
placement="bottom start"
isOpen={isOpen}
onOpenChange={() => setIsOpen(false)}
style={popoverStyle}
>
<Menu
onMenuSelect={item => {
Expand Down
6 changes: 6 additions & 0 deletions packages/desktop-client/src/components/reports/DateRange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ export function DateRange({ start, end, type }: DateRangeProps): ReactElement {
: d.format(endDate, 'MMM yyyy')}
</div>
);
} else if (['budget', 'average'].includes(type || '')) {
content = (
<div>
Compare {d.format(startDate, 'MMM yyyy')} to {type}
</div>
);
} else {
content = d.format(endDate, 'MMMM yyyy');
}
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop-client/src/components/reports/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function Header({
flexShrink: 0,
}}
>
{!['/reports/custom', '/reports/spending'].includes(path) && (
{!['/reports/custom'].includes(path) && (
<View
style={{
flexDirection: isNarrowWidth ? 'column' : 'row',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ export function Overview() {
/>
) : item.type === 'spending-card' ? (
<SpendingCard
widgetId={item.i}
isEditing={isEditing}
meta={item.meta}
onMetaChange={newMeta => onMetaChange(item, newMeta)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function ReportRouter() {
<Route path="/cash-flow/:id" element={<CashFlow />} />
<Route path="/custom" element={<CustomReport />} />
<Route path="/spending" element={<Spending />} />
<Route path="/spending/:id" element={<Spending />} />
</Routes>
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import React from 'react';
import React, { type ComponentProps } from 'react';
import { useTranslation } from 'react-i18next';

import { css } from 'glamor';
Expand Down Expand Up @@ -32,19 +32,22 @@ type PayloadItem = {
totalDebts: number | string;
totalTotals: number | string;
day: string;
months: {
date: string;
cumulative: number | string;
};
months: Record<
string,
{
date: string;
cumulative: number;
}
>;
};
};

type CustomTooltipProps = {
active?: boolean;
payload?: PayloadItem[];
balanceTypeOp?: string;
selection?: string;
compare?: string;
balanceTypeOp: 'cumulative';
selection: string | 'budget' | 'average';
compare: string;
};

const CustomTooltip = ({
Expand All @@ -59,7 +62,7 @@ const CustomTooltip = ({
if (active && payload && payload.length) {
const comparison = ['average', 'budget'].includes(selection)
? payload[0].payload[selection] * -1
: payload[0].payload.months[selection].cumulative * -1;
: payload[0].payload.months[selection]?.cumulative * -1;
return (
<div
className={`${css({
Expand All @@ -82,11 +85,11 @@ const CustomTooltip = ({
</strong>
</div>
<div style={{ lineHeight: 1.5 }}>
{payload[0].payload.months[compare].cumulative ? (
{payload[0].payload.months[compare]?.cumulative ? (
<AlignedText
left={t('Compare:')}
right={amountToCurrency(
payload[0].payload.months[compare].cumulative * -1,
payload[0].payload.months[compare]?.cumulative * -1,
)}
/>
) : null}
Expand All @@ -102,11 +105,11 @@ const CustomTooltip = ({
right={amountToCurrency(comparison)}
/>
)}
{payload[0].payload.months[compare].cumulative ? (
{payload[0].payload.months[compare]?.cumulative ? (
<AlignedText
left={t('Difference:')}
right={amountToCurrency(
payload[0].payload.months[compare].cumulative * -1 -
payload[0].payload.months[compare]?.cumulative * -1 -
comparison,
)}
/>
Expand All @@ -122,7 +125,7 @@ type SpendingGraphProps = {
style?: CSSProperties;
data: SpendingEntity;
compact?: boolean;
mode: string;
mode: 'single-month' | 'budget' | 'average';
compare: string;
compareTo: string;
};
Expand All @@ -138,27 +141,30 @@ export function SpendingGraph({
const privacyMode = usePrivacyMode();
const balanceTypeOp = 'cumulative';

const selection = mode === 'singleMonth' ? compareTo : mode;
const selection = mode === 'single-month' ? compareTo : mode;

const thisMonthMax = data.intervalData.reduce((a, b) =>
a.months[compare][balanceTypeOp] < b.months[compare][balanceTypeOp] ? a : b,
).months[compare][balanceTypeOp];
a.months[compare]?.[balanceTypeOp] < b.months[compare]?.[balanceTypeOp]
? a
: b,
).months[compare]?.[balanceTypeOp];
const selectionMax = ['average', 'budget'].includes(selection)
? data.intervalData[27][selection]
: data.intervalData.reduce((a, b) =>
a.months[selection][balanceTypeOp] < b.months[selection][balanceTypeOp]
a.months[selection]?.[balanceTypeOp] <
b.months[selection]?.[balanceTypeOp]
? a
: b,
).months[selection][balanceTypeOp];
).months[selection]?.[balanceTypeOp];
const maxYAxis = selectionMax > thisMonthMax;
const dataMax = Math.max(
...data.intervalData.map(i => i.months[compare].cumulative),
...data.intervalData.map(i => i.months[compare]?.cumulative),
);
const dataMin = Math.min(
...data.intervalData.map(i => i.months[compare].cumulative),
...data.intervalData.map(i => i.months[compare]?.cumulative),
);

const tickFormatter = tick => {
const tickFormatter: ComponentProps<typeof YAxis>['tickFormatter'] = tick => {
if (!privacyMode) return `${amountToCurrencyNoDecimal(tick)}`; // Formats the tick values as strings with commas
return '...';
};
Expand All @@ -179,7 +185,7 @@ export function SpendingGraph({
return obj[month] && -1 * obj[month];
} else {
return (
obj.months[month][balanceTypeOp] &&
obj.months[month]?.[balanceTypeOp] &&
-1 * obj.months[month][balanceTypeOp]
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export function getLatestRange(offset: number) {
}

export function calculateTimeRange(
timeFrame?: TimeFrame,
timeFrame?: Partial<TimeFrame>,
defaultTimeFrame?: TimeFrame,
) {
const start =
Expand All @@ -181,7 +181,9 @@ export function calculateTimeRange(
return getFullRange(start);
}
if (mode === 'sliding-window') {
return getLatestRange(monthUtils.differenceInCalendarMonths(end, start));
return getLatestRange(
Math.abs(monthUtils.differenceInCalendarMonths(end, start)),
);
}

return [start, end, 'static'] as const;
Expand Down
Loading
Loading