Skip to content

Commit

Permalink
Update and organize reports (actualbudget#2274)
Browse files Browse the repository at this point in the history
* Add schema work

* notes

* merge fixes

* Add Reports Save Menu

* merge fixes

* updates

* notes

* updates

* updates

* save updates fix

* typecheck fixes

* revert changes

* notes

* error fixes

* update

* fix

* merge fixes

* review changes

* reportChange and savedStatus

* Update packages/desktop-client/src/components/reports/SaveReport.tsx

Co-authored-by: DJ Mountney <[email protected]>

* merge fixes

---------

Co-authored-by: DJ Mountney <[email protected]>
  • Loading branch information
carkom and twk3 authored Feb 3, 2024
1 parent 8398319 commit f0ae386
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 36 deletions.
14 changes: 8 additions & 6 deletions packages/desktop-client/src/components/reports/ReportOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,24 @@ import {
const startDate = monthUtils.subMonths(monthUtils.currentMonth(), 5);
const endDate = monthUtils.currentMonth();

export const defaultState: CustomReportEntity = {
export const defaultReport: CustomReportEntity = {
id: undefined,
name: 'Default',
startDate,
endDate,
isDateStatic: false,
dateRange: 'Last 6 months',
mode: 'total',
groupBy: 'Category',
balanceType: 'Payment',
showEmpty: false,
showOffBudget: false,
showHiddenCategories: false,
showUncategorized: false,
selectedCategories: [],
graphType: 'BarGraph',
startDate,
endDate,
selectedCategories: null,
isDateStatic: false,
conditions: [],
conditionsOp: 'and',
name: 'Default',
};

const balanceTypeOptions = [
Expand Down
11 changes: 10 additions & 1 deletion packages/desktop-client/src/components/reports/ReportSidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ export function ReportSidebar({
setSelectedCategories,
onChangeDates,
onChangeViews,
onReportChange,
}) {
const [menuOpen, setMenuOpen] = useState(false);
const onSelectRange = cond => {
onReportChange(null, 'modify');
setDateRange(cond);
switch (cond) {
case 'All time':
Expand Down Expand Up @@ -77,6 +79,7 @@ export function ReportSidebar({
};

const onChangeMode = cond => {
onReportChange(null, 'modify');
setMode(cond);
if (cond === 'time') {
if (customReportItems.graphType === 'TableGraph') {
Expand Down Expand Up @@ -107,6 +110,7 @@ export function ReportSidebar({
};

const onChangeSplit = cond => {
onReportChange(null, 'modify');
setGroupBy(cond);
if (customReportItems.mode === 'total') {
if (customReportItems.graphType !== 'TableGraph') {
Expand All @@ -123,6 +127,11 @@ export function ReportSidebar({
}
};

const onChangeBalanceType = cond => {
onReportChange(null, 'modify');
setBalanceType(cond);
};

return (
<View
style={{
Expand Down Expand Up @@ -206,7 +215,7 @@ export function ReportSidebar({
</Text>
<Select
value={customReportItems.balanceType}
onChange={setBalanceType}
onChange={e => onChangeBalanceType(e)}
options={ReportOptions.balanceType.map(option => [
option.description,
option.description,
Expand Down
13 changes: 11 additions & 2 deletions packages/desktop-client/src/components/reports/ReportTopbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { SaveReportMenuButton } from './SaveReport';

export function ReportTopbar({
customReportItems,
savedStatus,
setGraphType,
setTypeDisabled,
setBalanceType,
Expand All @@ -27,6 +28,7 @@ export function ReportTopbar({
viewLabels,
onApplyFilter,
onChangeViews,
onReportChange,
}) {
return (
<View
Expand Down Expand Up @@ -158,10 +160,17 @@ export function ReportTopbar({
marginRight: 15,
flexShrink: 0,
}}
/>{' '}
<FilterButton
compact
hover
onApply={e => {
onApplyFilter(e);
onReportChange(null, 'modify');
}}
/>
<FilterButton onApply={onApplyFilter} compact hover />
<View style={{ flex: 1 }} />
<SaveReportMenuButton />
<SaveReportMenuButton savedStatus={savedStatus} />
</View>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function SaveReportMenu({ setMenuOpen }) {
);
}

export function SaveReportMenuButton() {
export function SaveReportMenuButton({ savedStatus }: { savedStatus: string }) {
const [menuOpen, setMenuOpen] = useState(false);

return (
Expand All @@ -65,6 +65,7 @@ export function SaveReportMenuButton() {
>
Unsaved Report&nbsp;
</Text>
{savedStatus === 'modified' && <Text>(modified)&nbsp;</Text>}
<SvgExpandArrow width={8} height={8} style={{ marginRight: 5 }} />
</Button>
{menuOpen && <SaveReportMenu setMenuOpen={setMenuOpen} />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ChooseGraph } from '../ChooseGraph';
import { Header } from '../Header';
import { LoadingIndicator } from '../LoadingIndicator';
import { ReportLegend } from '../ReportLegend';
import { ReportOptions, defaultState } from '../ReportOptions';
import { ReportOptions, defaultReport } from '../ReportOptions';
import { ReportSidebar } from '../ReportSidebar';
import { ReportSummary } from '../ReportSummary';
import { ReportTopbar } from '../ReportTopbar';
Expand Down Expand Up @@ -54,7 +54,9 @@ export function CustomReport() {
} = useFilters();

const location = useLocation();
const loadReport = location.state && (location.state.report ?? defaultState);
const loadReport = location.state
? location.state.report ?? defaultReport
: defaultReport;

const [allMonths, setAllMonths] = useState(null);
const [typeDisabled, setTypeDisabled] = useState(['Net']);
Expand All @@ -78,14 +80,18 @@ export function CustomReport() {
);
const [graphType, setGraphType] = useState(loadReport.graphType);

const [dateRange, setDateRange] = useState('Last 6 months');
const [dateRange, setDateRange] = useState(loadReport.dateRange);
const [dataCheck, setDataCheck] = useState(false);
const dateRangeLine = ReportOptions.dateRange.length - 3;

const [report, setReport] = useState(loadReport);
const [savedStatus, setSavedStatus] = useState(
location.state ? (location.state.report ? 'saved' : 'new') : 'new',
);
const months = monthUtils.rangeInclusive(startDate, endDate);

useEffect(() => {
if (selectedCategories === null && categories.list.length !== 0) {
if (selectedCategories.length === 0 && categories.list.length !== 0) {
setSelectedCategories(categories.list);
}
}, [categories, selectedCategories]);
Expand Down Expand Up @@ -196,26 +202,27 @@ export function CustomReport() {
const groupedData = useReport('grouped', getGroupData);

const data = { ...graphData, groupedData };

const customReportItems = {
id: null,
id: undefined,
name: undefined,
startDate,
endDate,
isDateStatic,
dateRange,
mode,
groupBy,
balanceType,
showEmpty,
showOffBudget,
showHiddenCategories,
showUncategorized,
graphType,
startDate,
endDate,
selectedCategories,
isDateStatic,
dateRange,
filters,
graphType,
conditions: filters,
conditionsOp,
data,
};

const [scrollWidth, setScrollWidth] = useState(0);

if (!allMonths || !data) {
Expand All @@ -225,6 +232,7 @@ export function CustomReport() {
const onChangeDates = (startDate, endDate) => {
setStartDate(startDate);
setEndDate(endDate);
setSavedStatus('modified');
};

const onChangeViews = (viewType, status) => {
Expand All @@ -239,6 +247,48 @@ export function CustomReport() {
}
};

const onChangeAppliedFilter = (filter, changedElement) => {
onReportChange(null, 'modify');
return changedElement(filter);
};

const onReportChange = (savedReport, type) => {
switch (type) {
case 'add-update':
setSavedStatus('saved');
setReport(savedReport);
break;
case 'rename':
setReport({ ...report, name: savedReport.name });
break;
case 'modify':
if (report.name) {
setSavedStatus('modified');
}
break;
case 'reload':
setSavedStatus('saved');

setStartDate(report.startDate);
setEndDate(report.endDate);
setIsDateStatic(report.isDateStatic);
setDateRange(report.dateRange);
setMode(report.mode);
setGroupBy(report.groupBy);
setBalanceType(report.balanceType);
setShowEmpty(report.showEmpty);
setShowOffBudget(report.showOffBudget);
setShowUncategorized(report.showUncategorized);
setSelectedCategories(report.selectedCategories);
setGraphType(report.graphType);
onApplyFilter(null);
report.conditions.forEach(condition => onApplyFilter(condition));
onCondOpChange(report.conditionsOp);
break;
default:
}
};

return (
<View style={{ ...styles.page, minWidth: 650, overflow: 'hidden' }}>
<Header title="Custom Reports" />
Expand Down Expand Up @@ -271,6 +321,7 @@ export function CustomReport() {
setSelectedCategories={setSelectedCategories}
onChangeDates={onChangeDates}
onChangeViews={onChangeViews}
onReportChange={onReportChange}
/>
<View
style={{
Expand All @@ -279,6 +330,7 @@ export function CustomReport() {
>
<ReportTopbar
customReportItems={customReportItems}
savedStatus={savedStatus}
setGraphType={setGraphType}
setTypeDisabled={setTypeDisabled}
setBalanceType={setBalanceType}
Expand All @@ -288,6 +340,7 @@ export function CustomReport() {
viewLabels={viewLabels}
onApplyFilter={onApplyFilter}
onChangeViews={onChangeViews}
onReportChange={onReportChange}
/>
{filters && filters.length > 0 && (
<View
Expand All @@ -300,9 +353,14 @@ export function CustomReport() {
<AppliedFilters
filters={filters}
onUpdate={onUpdateFilter}
onDelete={onDeleteFilter}
onDelete={filter =>
onChangeAppliedFilter(filter, onDeleteFilter)
}
conditionsOp={conditionsOp}
onCondOpChange={onCondOpChange}
onCondOpChange={filter =>
onChangeAppliedFilter(filter, onCondOpChange)
}
onUpdateChange={onReportChange}
/>
</View>
)}
Expand Down
1 change: 0 additions & 1 deletion packages/loot-core/src/client/data-hooks/reports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ function toJS(rows: CustomReportData[]) {
const test: CustomReportEntity = {
...row,
conditionsOp: row.conditions_op ?? 'and',
filters: row.conditions,
};
return test;
});
Expand Down
7 changes: 2 additions & 5 deletions packages/loot-core/src/server/reports/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
type CustomReportData,
type CustomReportEntity,
} from '../../types/models';
import { parseConditionsOrActions } from '../accounts/transaction-rules';
import { createApp } from '../app';
import * as db from '../db';
import { requiredFields } from '../models';
Expand All @@ -30,22 +29,20 @@ const reportModel = {
return {
...row,
conditionsOp: row.conditions_op,
filters: parseConditionsOrActions(row.conditions),
};
},

fromJS(report: CustomReportEntity) {
const { filters, conditionsOp, ...row }: CustomReportData = report;
const { conditionsOp, ...row }: CustomReportData = report;
if (conditionsOp) {
row.conditions_op = conditionsOp;
row.conditions = filters;
}
return row;
},
};

async function reportNameExists(
name: string,
name: string | undefined,
reportId: string | undefined,
newItem: boolean,
) {
Expand Down
14 changes: 8 additions & 6 deletions packages/loot-core/src/types/models/reports.d.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { CategoryEntity } from './category';
import { type RuleConditionEntity } from './rule';

export interface CustomReportEntity {
id: string | undefined;
name: string;
startDate: string;
endDate: string;
isDateStatic: boolean;
dateRange: string;
mode: string;
groupBy: string;
balanceType: string;
showEmpty: boolean;
showOffBudget: boolean;
showHiddenCategories: boolean;
showUncategorized: boolean;
selectedCategories: CategoryEntity[];
graphType: string;
selectedCategories;
filters?: RuleConditionEntity[];
conditions?: RuleConditionEntity[];
conditionsOp: string;
name: string;
startDate: string;
endDate: string;
isDateStatic: boolean;
data?: GroupedEntity;
tombstone?: boolean;
}
Expand Down
6 changes: 6 additions & 0 deletions upcoming-release-notes/2274.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [carkom]
---

Updating and organizing code in preperation for saved custom reports menu.

0 comments on commit f0ae386

Please sign in to comment.