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

Add YTD and last year to Reports headers #4019

Merged
merged 19 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 51 additions & 1 deletion packages/desktop-client/src/components/reports/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
type RuleConditionEntity,
type TimeFrame,
} from 'loot-core/types/models';
import { type SyncedPrefs } from 'loot-core/types/prefs';

import { Button } from '../common/Button2';
import { Select } from '../common/Select';
Expand All @@ -15,6 +16,7 @@ import { AppliedFilters } from '../filters/AppliedFilters';
import { FilterButton } from '../filters/FiltersMenu';
import { useResponsive } from '../responsive/ResponsiveProvider';

import { getLiveRange } from './getLiveRange';
import {
calculateTimeRange,
getFullRange,
Expand All @@ -29,6 +31,8 @@ type HeaderProps = {
mode?: TimeFrame['mode'];
show1Month?: boolean;
allMonths: Array<{ name: string; pretty: string }>;
earliestTransaction: string;
firstDayOfWeekIdx?: SyncedPrefs['firstDayOfWeekIdx'];
onChangeDates: (
start: TimeFrame['start'],
end: TimeFrame['end'],
Expand All @@ -51,6 +55,8 @@ export function Header({
mode,
show1Month,
allMonths,
earliestTransaction,
firstDayOfWeekIdx,
onChangeDates,
filters,
conditionsOp,
Expand All @@ -62,6 +68,14 @@ export function Header({
}: HeaderProps) {
const { t } = useTranslation();
const { isNarrowWidth } = useResponsive();
function convertToMonth(
start: string,
end: string,
_: TimeFrame['mode'],
mode: TimeFrame['mode'],
): [string, string, TimeFrame['mode']] {
return [monthUtils.getMonth(start), monthUtils.getMonth(end), mode];
}

return (
<View
Expand Down Expand Up @@ -129,7 +143,7 @@ export function Header({
</SpaceBetween>
</SpaceBetween>

<SpaceBetween>
<SpaceBetween gap={3}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we up this? I think it looks a bit squished.

Current:
image

Here's 10px
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small screens would have a problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any way to force it to wrap when the save button starts to overlap with the filter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea. my knowledge of CSS is less than js

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, we'll go with it for now then. If anyone works out a way it can be a separate PR

{show1Month && (
<Button
variant="bare"
Expand All @@ -156,6 +170,42 @@ export function Header({
>
{t('1 year')}
</Button>
<Button
variant="bare"
onPress={() =>
onChangeDates(
...convertToMonth(
...getLiveRange(
'Year to date',
earliestTransaction,
true,
firstDayOfWeekIdx,
),
'yearToDate',
),
)
}
>
{t('Year to date')}
</Button>
<Button
variant="bare"
onPress={() =>
onChangeDates(
...convertToMonth(
...getLiveRange(
'Last year',
earliestTransaction,
false,
firstDayOfWeekIdx,
),
'lastYear',
),
)
}
>
{t('Last year')}
</Button>
<Button
variant="bare"
onPress={() =>
Expand Down
14 changes: 14 additions & 0 deletions packages/desktop-client/src/components/reports/reportRanges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,20 @@ export function calculateTimeRange(

return getLatestRange(offset);
}
if (mode === 'lastYear') {
return [
monthUtils.getYearStart(monthUtils.prevYear(monthUtils.currentMonth())),
monthUtils.getYearEnd(monthUtils.prevYear(monthUtils.currentDate())),
'lastYear',
] as const;
}
if (mode === 'yearToDate') {
return [
monthUtils.currentYear() + '-01',
monthUtils.currentMonth(),
'yearToDate',
] as const;
}
matt-fidd marked this conversation as resolved.
Show resolved Hide resolved

return [start, end, 'static'] as const;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
},
);

const [earliestTransaction, _] = useState('');

matt-fidd marked this conversation as resolved.
Show resolved Hide resolved
return (
<Page
header={
Expand Down Expand Up @@ -492,6 +494,8 @@ function CalendarInner({ widget, parameters }: CalendarInnerProps) {
allMonths={allMonths}
start={start}
end={end}
earliestTransaction={earliestTransaction}
firstDayOfWeekIdx={firstDayOfWeekIdx}
mode={mode}
onChangeDates={onChangeDates}
filters={conditions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {

import { useFilters } from '../../../hooks/useFilters';
import { useNavigate } from '../../../hooks/useNavigate';
import { useSyncedPref } from '../../../hooks/useSyncedPref';
import { useDispatch } from '../../../redux';
import { theme } from '../../../style';
import { AlignedText } from '../../common/AlignedText';
Expand Down Expand Up @@ -187,6 +188,10 @@ function CashFlowInner({ widget }: CashFlowInnerProps) {
});
};

const [earliestTransaction, _] = useState('');
const [_firstDayOfWeekIdx] = useSyncedPref('firstDayOfWeekIdx');
const firstDayOfWeekIdx = _firstDayOfWeekIdx || '0';

if (!allMonths || !data) {
return null;
}
Expand Down Expand Up @@ -224,6 +229,8 @@ function CashFlowInner({ widget }: CashFlowInnerProps) {
allMonths={allMonths}
start={start}
end={end}
earliestTransaction={earliestTransaction}
firstDayOfWeekIdx={firstDayOfWeekIdx}
mode={mode}
show1Month
onChangeDates={onChangeDates}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { type TimeFrame, type NetWorthWidget } from 'loot-core/types/models';
import { useAccounts } from '../../../hooks/useAccounts';
import { useFilters } from '../../../hooks/useFilters';
import { useNavigate } from '../../../hooks/useNavigate';
import { useSyncedPref } from '../../../hooks/useSyncedPref';
import { useDispatch } from '../../../redux';
import { theme, styles } from '../../../style';
import { Button } from '../../common/Button2';
Expand Down Expand Up @@ -162,6 +163,10 @@ function NetWorthInner({ widget }: NetWorthInnerProps) {
});
};

const [earliestTransaction, _] = useState('');
const [_firstDayOfWeekIdx] = useSyncedPref('firstDayOfWeekIdx');
const firstDayOfWeekIdx = _firstDayOfWeekIdx || '0';
matt-fidd marked this conversation as resolved.
Show resolved Hide resolved

if (!allMonths || !data) {
return null;
}
Expand Down Expand Up @@ -197,6 +202,8 @@ function NetWorthInner({ widget }: NetWorthInnerProps) {
allMonths={allMonths}
start={start}
end={end}
earliestTransaction={earliestTransaction}
firstDayOfWeekIdx={firstDayOfWeekIdx}
mode={mode}
onChangeDates={onChangeDates}
filters={conditions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {

import { useFilters } from '../../../hooks/useFilters';
import { useNavigate } from '../../../hooks/useNavigate';
import { useSyncedPref } from '../../../hooks/useSyncedPref';
import { SvgEquals } from '../../../icons/v1';
import { SvgCloseParenthesis } from '../../../icons/v2/CloseParenthesis';
import { SvgOpenParenthesis } from '../../../icons/v2/OpenParenthesis';
Expand Down Expand Up @@ -147,6 +148,10 @@ function SummaryInner({ widget }: SummaryInnerProps) {
}>
>([]);

const [earliestTransaction, _] = useState('');
const [_firstDayOfWeekIdx] = useSyncedPref('firstDayOfWeekIdx');
const firstDayOfWeekIdx = _firstDayOfWeekIdx || '0';
matt-fidd marked this conversation as resolved.
Show resolved Hide resolved

useEffect(() => {
async function run() {
const trans = await send('get-earliest-transaction');
Expand Down Expand Up @@ -219,7 +224,6 @@ function SummaryInner({ widget }: SummaryInnerProps) {
);
return;
}

await send('dashboard-update-widget', {
id: widget.id,
meta: {
Expand Down Expand Up @@ -273,6 +277,8 @@ function SummaryInner({ widget }: SummaryInnerProps) {
allMonths={allMonths}
start={start}
end={end}
earliestTransaction={earliestTransaction}
firstDayOfWeekIdx={firstDayOfWeekIdx}
mode={mode}
onChangeDates={onChangeDates}
onApply={dividendFilters.onApply}
Expand Down
2 changes: 1 addition & 1 deletion packages/loot-core/src/types/models/dashboard.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type RuleConditionEntity } from './rule';
export type TimeFrame = {
start: string;
end: string;
mode: 'sliding-window' | 'static' | 'full';
mode: 'sliding-window' | 'static' | 'full' | 'lastYear' | 'yearToDate';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? The existing mode types are for how the window functions. Plus the existing window options aren't in this list, so it seems like you shouldn't need to change this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is. Sliding window will be always against current month.
With ytd and last year is not against current month.

In my opinion we could migrate it to other structure to be more productive but we can’t because they are already being used.

we should get the interval size, interval type and anchor.
3 month
Would be 3, month, current month

or
Last year would be
12, month, begin of current year

Two years
2, years, current month

};

type AbstractWidget<
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/4019.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [rodriguestiago0]
---

Add "Year to date" and "Last year" to reports header.
Loading