Skip to content

Commit

Permalink
Custom Reports: TS strict changes #2 (#2727)
Browse files Browse the repository at this point in the history
* TS strict changes

* notes

* TS strict custom spreadsheets

* notes

* render row changes

* update report

* notes
  • Loading branch information
carkom committed May 14, 2024
1 parent 7cee3b8 commit f1f1ba8
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 103 deletions.
38 changes: 28 additions & 10 deletions packages/desktop-client/src/components/reports/ReportOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ export type QueryDataEntity = {
amount: number;
};

export type UncategorizedEntity = Pick<CategoryEntity, 'name' | 'hidden'> & {
export type UncategorizedEntity = Pick<
CategoryEntity,
'id' | 'name' | 'hidden'
> & {
/*
When looking at uncategorized and hidden transactions we
need a way to group them. To do this we give them a unique
Expand All @@ -241,6 +244,7 @@ export type UncategorizedEntity = Pick<CategoryEntity, 'name' | 'hidden'> & {
};

const uncategorizedCategory: UncategorizedEntity = {
id: '',
name: 'Uncategorized',
uncategorized_id: '1',
hidden: false,
Expand All @@ -249,6 +253,7 @@ const uncategorizedCategory: UncategorizedEntity = {
has_category: false,
};
const transferCategory: UncategorizedEntity = {
id: '',
name: 'Transfers',
uncategorized_id: '2',
hidden: false,
Expand All @@ -257,6 +262,7 @@ const transferCategory: UncategorizedEntity = {
has_category: false,
};
const offBudgetCategory: UncategorizedEntity = {
id: '',
name: 'Off Budget',
uncategorized_id: '3',
hidden: false,
Expand All @@ -283,7 +289,7 @@ export const categoryLists = (categories: {
list: CategoryEntity[];
grouped: CategoryGroupEntity[];
}) => {
const categoryList = [
const categoryList: UncategorizedEntity[] = [
...categories.list.sort((a, b) => {
//The point of this sorting is to make the graphs match the "budget" page
const catGroupA = categories.grouped.find(f => f.id === a.cat_group);
Expand All @@ -304,34 +310,46 @@ export const categoryLists = (categories: {
transferCategory,
];

const categoryGroup = [...categories.grouped, uncategorizedGroup];
const categoryGroup: UncategorizedGroupEntity[] = [
...categories.grouped,
uncategorizedGroup,
];
return [categoryList, categoryGroup.filter(group => group !== null)] as const;
};

export const groupBySelections = (
groupBy: string,
categoryList: CategoryEntity[],
categoryList: UncategorizedEntity[],
categoryGroup: CategoryGroupEntity[],
payees: PayeeEntity[],
accounts: AccountEntity[],
) => {
let groupByList;
let groupByLabel;
): [
UncategorizedEntity[],
'category' | 'categoryGroup' | 'payee' | 'account',
] => {
let groupByList: UncategorizedEntity[];
let groupByLabel: 'category' | 'categoryGroup' | 'payee' | 'account';
switch (groupBy) {
case 'Category':
groupByList = categoryList;
groupByLabel = 'category';
break;
case 'Group':
groupByList = categoryGroup;
groupByList = categoryGroup.map(group => {
return { id: group.id, name: group.name, hidden: group.hidden };
});
groupByLabel = 'categoryGroup';
break;
case 'Payee':
groupByList = payees;
groupByList = payees.map(payee => {
return { id: payee.id, name: payee.name, hidden: false };
});
groupByLabel = 'payee';
break;
case 'Account':
groupByList = accounts;
groupByList = accounts.map(account => {
return { id: account.id, name: account.name, hidden: false };
});
groupByLabel = 'account';
break;
case 'Interval':
Expand Down
18 changes: 10 additions & 8 deletions packages/desktop-client/src/components/reports/SaveReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ export function SaveReport({
const [chooseMenuOpen, setChooseMenuOpen] = useState(false);
const [menuItem, setMenuItem] = useState('');
const [err, setErr] = useState('');
const [name, setName] = useState(report.name ?? '');
const [newName, setNewName] = useState(report.name ?? '');
const inputRef = createRef<HTMLInputElement>();

async function onApply(cond: string) {
const chooseSavedReport = listReports.find(r => cond === r.id);
onReportChange({ savedReport: chooseSavedReport, type: 'choose' });
setChooseMenuOpen(false);
setName(chooseSavedReport === undefined ? '' : chooseSavedReport.name);
setNewName(chooseSavedReport === undefined ? '' : chooseSavedReport.name);
}

const onAddUpdate = async ({ menuChoice }: { menuChoice?: string }) => {
Expand All @@ -58,7 +58,7 @@ export function SaveReport({
const newSavedReport = {
...report,
...customReportItems,
name,
name: newName,
};

const response = await sendCatch('report/create', newSavedReport);
Expand All @@ -80,9 +80,11 @@ export function SaveReport({
return;
}

const { name, id, ...props } = customReportItems;

const updatedReport = {
...report,
...(menuChoice === 'rename-report' ? { name } : customReportItems),
...(menuChoice === 'rename-report' ? { name: newName } : props),
};

const response = await sendCatch('report/update', updatedReport);
Expand All @@ -100,7 +102,7 @@ export function SaveReport({
};

const onDelete = async () => {
setName('');
setNewName('');
await send('report/delete', report.id);
onReportChange({ type: 'reset' });
setDeleteMenuOpen(false);
Expand Down Expand Up @@ -134,7 +136,7 @@ export function SaveReport({
break;
case 'reset-report':
setMenuOpen(false);
setName('');
setNewName('');
onReportChange({ type: 'reset' });
break;
case 'choose-report':
Expand Down Expand Up @@ -185,8 +187,8 @@ export function SaveReport({
<SaveReportName
onClose={() => setNameMenuOpen(false)}
menuItem={menuItem}
name={name}
setName={setName}
name={newName}
setName={setNewName}
inputRef={inputRef}
onAddUpdate={onAddUpdate}
err={err}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-strict-ignore
import * as d from 'date-fns';

import { runQuery } from 'loot-core/src/client/query-helpers';
Expand All @@ -13,13 +12,19 @@ import {
type RuleConditionEntity,
type CategoryGroupEntity,
} from 'loot-core/src/types/models';
import { type DataEntity } from 'loot-core/src/types/models/reports';
import {
type DataEntity,
type GroupedEntity,
type IntervalEntity,
} from 'loot-core/src/types/models/reports';
import { type LocalPrefs } from 'loot-core/types/prefs';

import {
categoryLists,
groupBySelections,
type QueryDataEntity,
ReportOptions,
type UncategorizedEntity,
} from '../ReportOptions';

import { calculateLegend } from './calculateLegend';
Expand Down Expand Up @@ -61,10 +66,10 @@ export function createCustomSpreadsheet({
showOffBudget,
showHiddenCategories,
showUncategorized,
groupBy,
groupBy = '',
balanceTypeOp = 'totalDebts',
payees,
accounts,
payees = [],
accounts = [],
graphType,
firstDayOfWeekIdx,
setDataCheck,
Expand All @@ -79,13 +84,10 @@ export function createCustomSpreadsheet({
),
);

const [groupByList, groupByLabel] = groupBySelections(
groupBy,
categoryList,
categoryGroup,
payees,
accounts,
);
const [groupByList, groupByLabel]: [
groupByList: UncategorizedEntity[],
groupByLabel: 'category' | 'categoryGroup' | 'payee' | 'account',
] = groupBySelections(groupBy, categoryList, categoryGroup, payees, accounts);

return async (
spreadsheet: ReturnType<typeof useSpreadsheet>,
Expand All @@ -100,7 +102,9 @@ export function createCustomSpreadsheet({
});
const conditionsOpKey = conditionsOp === 'or' ? '$or' : '$and';

let [assets, debts] = await Promise.all([
let assets: QueryDataEntity[];
let debts: QueryDataEntity[];
[assets, debts] = await Promise.all([
runQuery(
makeQuery(
'assets',
Expand Down Expand Up @@ -143,83 +147,85 @@ export function createCustomSpreadsheet({
const intervals =
interval === 'Weekly'
? monthUtils.weekRangeInclusive(startDate, endDate, firstDayOfWeekIdx)
: monthUtils[ReportOptions.intervalRange.get(interval)](
startDate,
endDate,
);
: monthUtils[
ReportOptions.intervalRange.get(interval) || 'rangeInclusive'
](startDate, endDate);

let totalAssets = 0;
let totalDebts = 0;

const intervalData = intervals.reduce((arr, intervalItem) => {
let perIntervalAssets = 0;
let perIntervalDebts = 0;
const stacked = {};
const intervalData = intervals.reduce(
(arr: IntervalEntity[], intervalItem) => {
let perIntervalAssets = 0;
let perIntervalDebts = 0;
const stacked: Record<string, number> = {};

groupByList.map(item => {
let stackAmounts = 0;
groupByList.map(item => {
let stackAmounts = 0;

const intervalAssets = filterHiddenItems(
item,
assets,
showOffBudget,
showHiddenCategories,
showUncategorized,
)
.filter(
asset =>
asset.date === intervalItem &&
asset[groupByLabel] === (item.id ?? null),
const intervalAssets = filterHiddenItems(
item,
assets,
showOffBudget,
showHiddenCategories,
showUncategorized,
)
.reduce((a, v) => (a = a + v.amount), 0);
perIntervalAssets += intervalAssets;
.filter(
asset =>
asset.date === intervalItem &&
asset[groupByLabel] === (item.id ?? null),
)
.reduce((a, v) => (a = a + v.amount), 0);
perIntervalAssets += intervalAssets;

const intervalDebts = filterHiddenItems(
item,
debts,
showOffBudget,
showHiddenCategories,
showUncategorized,
)
.filter(
debt =>
debt.date === intervalItem &&
debt[groupByLabel] === (item.id ?? null),
const intervalDebts = filterHiddenItems(
item,
debts,
showOffBudget,
showHiddenCategories,
showUncategorized,
)
.reduce((a, v) => (a = a + v.amount), 0);
perIntervalDebts += intervalDebts;
.filter(
debt =>
debt.date === intervalItem &&
debt[groupByLabel] === (item.id ?? null),
)
.reduce((a, v) => (a = a + v.amount), 0);
perIntervalDebts += intervalDebts;

if (balanceTypeOp === 'totalAssets') {
stackAmounts += intervalAssets;
}
if (balanceTypeOp === 'totalDebts') {
stackAmounts += intervalDebts;
}
if (stackAmounts !== 0) {
stacked[item.name] = integerToAmount(Math.abs(stackAmounts));
}
if (balanceTypeOp === 'totalAssets') {
stackAmounts += intervalAssets;
}
if (balanceTypeOp === 'totalDebts') {
stackAmounts += intervalDebts;
}
if (stackAmounts !== 0) {
stacked[item.name] = integerToAmount(Math.abs(stackAmounts));
}

return null;
});
totalAssets += perIntervalAssets;
totalDebts += perIntervalDebts;
return null;
});
totalAssets += perIntervalAssets;
totalDebts += perIntervalDebts;

arr.push({
date: d.format(
d.parseISO(intervalItem),
ReportOptions.intervalFormat.get(interval),
),
...stacked,
dateStart: intervalItem,
totalDebts: integerToAmount(perIntervalDebts),
totalAssets: integerToAmount(perIntervalAssets),
totalTotals: integerToAmount(perIntervalDebts + perIntervalAssets),
});
arr.push({
date: d.format(
d.parseISO(intervalItem),
ReportOptions.intervalFormat.get(interval) || '',
),
...stacked,
dateStart: intervalItem,
totalDebts: integerToAmount(perIntervalDebts),
totalAssets: integerToAmount(perIntervalAssets),
totalTotals: integerToAmount(perIntervalDebts + perIntervalAssets),
});

return arr;
}, []);
return arr;
},
[],
);

const calcData = groupByList.map(item => {
const calcData: GroupedEntity[] = groupByList.map(item => {
const calc = recalculate({
item,
intervals,
Expand All @@ -233,7 +239,7 @@ export function createCustomSpreadsheet({
return { ...calc };
});
const calcDataFiltered = calcData.filter(i =>
filterEmptyRows(showEmpty, i, balanceTypeOp),
filterEmptyRows({ showEmpty, data: i, balanceTypeOp }),
);

const legend = calculateLegend(
Expand Down

0 comments on commit f1f1ba8

Please sign in to comment.