From ef3ea83c132aeee15fb5386a7fbcbdc94f268a38 Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 13:40:34 +0100 Subject: [PATCH 01/10] TS strict changes --- .../src/components/reports/ChooseGraph.tsx | 7 +- .../src/components/reports/ReportSummary.tsx | 17 +- .../components/reports/graphs/AreaGraph.tsx | 6 +- .../components/reports/graphs/BarGraph.tsx | 14 +- .../components/reports/graphs/DonutGraph.tsx | 6 +- .../components/reports/graphs/LineGraph.tsx | 4 +- .../reports/graphs/StackedBarGraph.tsx | 4 +- .../reports/graphs/adjustTextSize.ts | 34 ++-- .../reports/graphs/tableGraph/ReportTable.tsx | 28 ++- .../graphs/tableGraph/ReportTableHeader.tsx | 20 +-- .../graphs/tableGraph/ReportTableList.tsx | 160 ++++++++++++------ .../graphs/tableGraph/ReportTableRow.tsx | 4 +- .../graphs/tableGraph/ReportTableTotals.tsx | 23 ++- .../reports/reports/CustomReport.tsx | 6 +- .../reports/spreadsheets/calculateLegend.ts | 23 +-- .../spreadsheets/custom-spreadsheet.ts | 11 +- .../spreadsheets/grouped-spreadsheet.ts | 6 +- .../loot-core/src/types/models/reports.d.ts | 32 ++-- 18 files changed, 242 insertions(+), 163 deletions(-) diff --git a/packages/desktop-client/src/components/reports/ChooseGraph.tsx b/packages/desktop-client/src/components/reports/ChooseGraph.tsx index c8afbdd50a3..0e19a7c1467 100644 --- a/packages/desktop-client/src/components/reports/ChooseGraph.tsx +++ b/packages/desktop-client/src/components/reports/ChooseGraph.tsx @@ -1,7 +1,7 @@ // @ts-strict-ignore import React, { useRef } from 'react'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { type CSSProperties } from '../../style'; @@ -20,7 +20,7 @@ import { ReportTableTotals } from './graphs/tableGraph/ReportTableTotals'; import { ReportOptions } from './ReportOptions'; type ChooseGraphProps = { - data: GroupedEntity; + data: DataEntity; filters?: RuleConditionEntity[]; mode: string; graphType: string; @@ -160,13 +160,14 @@ export function ChooseGraph({ {monthUtils.format( startDate, - ReportOptions.intervalFormat.get(interval), + ReportOptions.intervalFormat.get(interval) || '', )} {monthUtils.format( startDate, - ReportOptions.intervalFormat.get(interval), + ReportOptions.intervalFormat.get(interval) || '', ) !== monthUtils.format( endDate, - ReportOptions.intervalFormat.get(interval), + ReportOptions.intervalFormat.get(interval) || '', ) && ' to ' + monthUtils.format( endDate, - ReportOptions.intervalFormat.get(interval), + ReportOptions.intervalFormat.get(interval) || '', )} @@ -153,7 +152,7 @@ export function ReportSummary({ - Per {ReportOptions.intervalMap.get(interval).toLowerCase()} + Per {(ReportOptions.intervalMap.get(interval) || '').toLowerCase()} diff --git a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx index ed21a78200d..860d2c7fcdf 100644 --- a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx @@ -17,7 +17,7 @@ import { amountToCurrency, amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { usePrivacyMode } from '../../../hooks/usePrivacyMode'; import { useResponsive } from '../../../ResponsiveProvider'; @@ -105,14 +105,14 @@ const customLabel = (props, width, end) => { const textAnchor = props.index === 0 ? 'left' : 'middle'; const display = props.value !== 0 && `${amountToCurrencyNoDecimal(props.value)}`; - const textSize = adjustTextSize(width, 'area'); + const textSize = adjustTextSize({ sized: width, type: 'area' }); return renderCustomLabel(calcX, calcY, textAnchor, display, textSize); }; type AreaGraphProps = { style?: CSSProperties; - data: GroupedEntity; + data: DataEntity; balanceTypeOp: string; compact?: boolean; viewLabels: boolean; diff --git a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx index a01984afae5..e8d1eb26b7a 100644 --- a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx @@ -19,7 +19,7 @@ import { amountToCurrency, amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -122,18 +122,18 @@ const customLabel = (props, typeOp) => { const textAnchor = 'middle'; const display = props.value !== 0 && `${amountToCurrencyNoDecimal(props.value)}`; - const textSize = adjustTextSize( - props.width, - typeOp === 'totalTotals' ? 'default' : 'variable', - props.value, - ); + const textSize = adjustTextSize({ + sized: props.width, + type: typeOp === 'totalTotals' ? 'default' : 'variable', + values: props.value, + }); return renderCustomLabel(calcX, calcY, textAnchor, display, textSize); }; type BarGraphProps = { style?: CSSProperties; - data: GroupedEntity; + data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; balanceTypeOp: string; diff --git a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx index e6cfeffa5ed..c1f50df27a3 100644 --- a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx @@ -4,7 +4,7 @@ import React, { useState } from 'react'; import { PieChart, Pie, Cell, Sector, ResponsiveContainer } from 'recharts'; import { amountToCurrency } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -158,7 +158,7 @@ const customLabel = props => { const calcY = props.cy + radius * Math.sin(-props.midAngle * RADIAN); const textAnchor = calcX > props.cx ? 'start' : 'end'; const display = props.value !== 0 && `${(props.percent * 100).toFixed(0)}%`; - const textSize = adjustTextSize(size, 'donut'); + const textSize = adjustTextSize({ sized: size, type: 'donut' }); const showLabel = props.percent; const showLabelThreshold = 0.05; const fill = theme.reportsInnerLabel; @@ -177,7 +177,7 @@ const customLabel = props => { type DonutGraphProps = { style?: CSSProperties; - data: GroupedEntity; + data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; balanceTypeOp: string; diff --git a/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx b/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx index e7b1174246b..3cb78f3d4df 100644 --- a/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx @@ -16,7 +16,7 @@ import { amountToCurrency, amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/types/models/reports'; +import { type DataEntity } from 'loot-core/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -109,7 +109,7 @@ const CustomTooltip = ({ type LineGraphProps = { style?: CSSProperties; - data: GroupedEntity; + data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; compact?: boolean; diff --git a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx index 3712c10a6ba..2df89692dac 100644 --- a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx @@ -17,7 +17,7 @@ import { amountToCurrency, amountToCurrencyNoDecimal, } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../hooks/useAccounts'; @@ -138,7 +138,7 @@ const customLabel = props => { type StackedBarGraphProps = { style?: CSSProperties; - data: GroupedEntity; + data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; compact?: boolean; diff --git a/packages/desktop-client/src/components/reports/graphs/adjustTextSize.ts b/packages/desktop-client/src/components/reports/graphs/adjustTextSize.ts index b8e4824140f..f1b9116ef60 100644 --- a/packages/desktop-client/src/components/reports/graphs/adjustTextSize.ts +++ b/packages/desktop-client/src/components/reports/graphs/adjustTextSize.ts @@ -1,13 +1,23 @@ -// @ts-strict-ignore -export const adjustTextSize = ( - sized: number, - type: string, - values?: number, -): `${number}px` => { - let source; +export const adjustTextSize = ({ + sized, + type, + values = 0, +}: { + sized: number; + type: string; + values?: number; +}): `${number}px` => { + let source: { + size: number; + font: number; + }[] = [{ size: -1, font: -1 }]; switch (type) { case 'variable': - source = variableLookup.find(({ value }) => values >= value).arr; + const findLookup = variableLookup.find(({ value }) => values >= value); + if (!findLookup) { + break; + } + source = findLookup.arr; break; case 'donut': source = donutLookup; @@ -15,8 +25,12 @@ export const adjustTextSize = ( default: source = defaultLookup; } - const lookup = source.find(({ size }) => sized >= size); - return `${lookup.font}px`; + const findSource = source.find(({ size }) => sized >= size); + if (!findSource) { + return '13px'; + } + + return `${findSource.font}px`; }; const defaultLookup = [ diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx index 9987321dbda..ab55c2ffb90 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx @@ -1,13 +1,15 @@ -// @ts-strict-ignore import React, { + type RefObject, useCallback, useLayoutEffect, useRef, type UIEventHandler, } from 'react'; -import { type RefProp } from 'react-spring'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { + type GroupedEntity, + type DataEntity, +} from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { type CSSProperties } from '../../../../style'; @@ -19,11 +21,11 @@ import { ReportTableRow } from './ReportTableRow'; type ReportTableProps = { saveScrollWidth: (value: number) => void; - listScrollRef: RefProp; + listScrollRef: RefObject; handleScroll: UIEventHandler; groupBy: string; balanceTypeOp: 'totalDebts' | 'totalTotals' | 'totalAssets'; - data: GroupedEntity; + data: DataEntity; filters?: RuleConditionEntity[]; mode: string; intervalsCount: number; @@ -59,7 +61,21 @@ export function ReportTable({ }); const renderItem = useCallback( - ({ item, mode, intervalsCount, compact, style, compactStyle }) => { + ({ + item, + mode, + intervalsCount, + compact, + style, + compactStyle, + }: { + item: GroupedEntity; + mode: string; + intervalsCount: number; + compact: boolean; + style?: CSSProperties; + compactStyle?: CSSProperties; + }) => { return ( ; + headerScrollRef: RefObject; handleScroll: UIEventHandler; compact: boolean; - style?: CSSProperties; - compactStyle?: CSSProperties; + style: CSSProperties; + compactStyle: CSSProperties; + mode: string; }; export function ReportTableHeader({ @@ -32,6 +31,7 @@ export function ReportTableHeader({ compact, style, compactStyle, + mode, }: ReportTableHeaderProps) { return ( - {data + {mode === 'time' ? data.map((header, index) => { return ( ReactNode; + intervalsCount: number; + mode: string; + metadata: GroupedEntity[]; + style?: CSSProperties; + compactStyle?: CSSProperties; +}; + +function RenderRow({ + index, + parent_index, + compact, + renderItem, + intervalsCount, + mode, + metadata, + style, + compactStyle, +}: RenderRowProps) { + const child = metadata[index]; + const parent = + parent_index !== undefined ? metadata[parent_index] : ({} as GroupedEntity); + + const item = + parent_index === undefined + ? child + : (parent.categories && parent.categories[index]) || + ({} as GroupedEntity); + + const renderRow = renderItem({ + item, + mode, + intervalsCount, + compact, + style, + compactStyle, + }); + + return {renderRow}; +} + type ReportTableListProps = { - data: GroupedEntity; - mode?: string; - intervalsCount?: number; + data: DataEntity; + mode: string; + intervalsCount: number; groupBy: string; - renderItem; + renderItem: (arg: { + item: GroupedEntity; + mode: string; + intervalsCount: number; + compact: boolean; + style?: CSSProperties; + compactStyle?: CSSProperties; + }) => ReactNode; compact: boolean; style?: CSSProperties; compactStyle?: CSSProperties; @@ -28,42 +89,23 @@ export function ReportTableList({ style, compactStyle, }: ReportTableListProps) { - const groupByData = + const metadata: GroupedEntity[] | undefined = groupBy === 'Category' - ? 'groupedData' + ? data.groupedData || [] : groupBy === 'Interval' - ? 'intervalData' - : 'data'; - const metadata = data[groupByData]; - - type RenderRowProps = { - index: number; - parent_index?: number; - compact: boolean; - style?: CSSProperties; - compactStyle?: CSSProperties; - }; - function RenderRow({ - index, - parent_index, - compact, - style, - compactStyle, - }: RenderRowProps) { - const item = - parent_index === undefined - ? metadata[index] - : metadata[parent_index].categories[index]; - - return renderItem({ - item, - mode, - intervalsCount, - compact, - style, - compactStyle, - }); - } + ? data.intervalData.map(interval => { + return { + id: '', + name: '', + date: interval.date, + totalAssets: interval.totalAssets, + totalDebts: interval.totalDebts, + totalTotals: interval.totalTotals, + intervalData: [], + categories: [], + }; + }) + : data.data; return ( @@ -71,10 +113,14 @@ export function ReportTableList({ {metadata.map((item, index) => { return ( - + - {item.categories.map((category, i) => { - return ( - - ); - })} + {item.categories.map( + (category: GroupedEntity, i: number) => { + return ( + + ); + }, + )} diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx index 54c1c650f54..d759a90d78c 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableRow.tsx @@ -5,7 +5,7 @@ import { amountToInteger, integerToCurrency, } from 'loot-core/src/shared/util'; -import { type DataEntity } from 'loot-core/src/types/models/reports'; +import { type GroupedEntity } from 'loot-core/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../../hooks/useAccounts'; @@ -17,7 +17,7 @@ import { Row, Cell } from '../../../table'; import { showActivity } from '../showActivity'; type ReportTableRowProps = { - item: DataEntity; + item: GroupedEntity; balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; groupBy: string; mode: string; diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx index 48b16e581e8..f9f01a6df62 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTableTotals.tsx @@ -1,13 +1,16 @@ -// @ts-strict-ignore -import React, { type UIEventHandler, useLayoutEffect, useState } from 'react'; -import { type RefProp } from 'react-spring'; +import React, { + type UIEventHandler, + useLayoutEffect, + useState, + type RefObject, +} from 'react'; import { amountToCurrency, amountToInteger, integerToCurrency, } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; import { useAccounts } from '../../../../hooks/useAccounts'; @@ -22,11 +25,11 @@ import { Row, Cell } from '../../../table'; import { showActivity } from '../showActivity'; type ReportTableTotalsProps = { - data: GroupedEntity; - balanceTypeOp: string; + data: DataEntity; + balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; mode: string; intervalsCount: number; - totalScrollRef: RefProp; + totalScrollRef: RefObject; handleScroll: UIEventHandler; compact: boolean; style?: CSSProperties; @@ -58,11 +61,13 @@ export function ReportTableTotals({ if (totalScrollRef.current) { const [parent, child] = [ totalScrollRef.current.offsetParent - ? totalScrollRef.current.parentElement.scrollHeight || 0 + ? (totalScrollRef.current.parentElement + ? totalScrollRef.current.parentElement.scrollHeight + : 0) || 0 : 0, totalScrollRef.current ? totalScrollRef.current.scrollHeight : 0, ]; - setScrollWidthTotals(parent > 0 && child > 0 && parent - child); + setScrollWidthTotals(parent > 0 && child > 0 ? parent - child : 0); } }); const average = amountToInteger(data[balanceTypeOp]) / intervalsCount; diff --git a/packages/desktop-client/src/components/reports/reports/CustomReport.tsx b/packages/desktop-client/src/components/reports/reports/CustomReport.tsx index 53320dd83fb..0f0738b7f00 100644 --- a/packages/desktop-client/src/components/reports/reports/CustomReport.tsx +++ b/packages/desktop-client/src/components/reports/reports/CustomReport.tsx @@ -8,8 +8,8 @@ import * as monthUtils from 'loot-core/src/shared/months'; import { amountToCurrency } from 'loot-core/src/shared/util'; import { type CategoryEntity } from 'loot-core/types/models/category'; import { - type GroupedEntity, type CustomReportEntity, + type DataEntity, } from 'loot-core/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; @@ -240,7 +240,7 @@ export function CustomReport() { } }, [interval, startDate, endDate, firstDayOfWeekIdx]); - const balanceTypeOp = + const balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals' = ReportOptions.balanceTypeMap.get(balanceType) || 'totalDebts'; const payees = usePayees(); const accounts = useAccounts(); @@ -321,7 +321,7 @@ export function CustomReport() { const graphData = useReport('default', getGraphData); const groupedData = useReport('grouped', getGroupData); - const data: GroupedEntity = { ...graphData, groupedData } as GroupedEntity; + const data: DataEntity = { ...graphData, groupedData } as DataEntity; const customReportItems: CustomReportEntity = { id: '', diff --git a/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts b/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts index f19bc69049c..de1ed867585 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts @@ -1,18 +1,19 @@ import { - type IntervalData, - type ItemEntity, + type LegendEntity, + type IntervalEntity, + type GroupedEntity, } from 'loot-core/src/types/models/reports'; import { theme } from '../../../style'; import { getColorScale } from '../chart-theme'; export function calculateLegend( - intervalData: IntervalData[], - calcDataFiltered: ItemEntity[], + intervalData: IntervalEntity[], + calcDataFiltered: GroupedEntity[], groupBy: string, - graphType: string, - balanceTypeOp: string, -) { + graphType?: string, + balanceTypeOp?: keyof GroupedEntity, +): LegendEntity[] { const colorScale = getColorScale('qualitative'); const chooseData = groupBy === 'Interval' @@ -22,10 +23,11 @@ export function calculateLegend( : calcDataFiltered.map(c => { return { name: c.name, id: c.id }; }); - return chooseData.map((item, index) => { + + const legend: LegendEntity[] = chooseData.map((item, index) => { return { - id: item.id, - name: item.name, + id: item.id || '', + name: item.name || '', color: graphType === 'DonutGraph' ? colorScale[index % colorScale.length] @@ -36,4 +38,5 @@ export function calculateLegend( : colorScale[index % colorScale.length], }; }); + return legend; } diff --git a/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts index 5251bafc1ab..149c5678577 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts @@ -13,10 +13,7 @@ import { type RuleConditionEntity, type CategoryGroupEntity, } from 'loot-core/src/types/models'; -import { - type DataEntity, - type GroupedEntity, -} from 'loot-core/src/types/models/reports'; +import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type LocalPrefs } from 'loot-core/types/prefs'; import { @@ -44,7 +41,7 @@ export type createCustomSpreadsheetProps = { showHiddenCategories: boolean; showUncategorized: boolean; groupBy?: string; - balanceTypeOp?: keyof DataEntity; + balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals'; payees?: PayeeEntity[]; accounts?: AccountEntity[]; graphType?: string; @@ -65,7 +62,7 @@ export function createCustomSpreadsheet({ showHiddenCategories, showUncategorized, groupBy, - balanceTypeOp, + balanceTypeOp = 'totalDebts', payees, accounts, graphType, @@ -92,7 +89,7 @@ export function createCustomSpreadsheet({ return async ( spreadsheet: ReturnType, - setData: (data: GroupedEntity) => void, + setData: (data: DataEntity) => void, ) => { if (groupByList.length === 0) { return; diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts index b273ccf07f6..9bd7b45d9aa 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts @@ -4,7 +4,7 @@ import { type useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider'; import { send } from 'loot-core/src/platform/client/fetch'; import * as monthUtils from 'loot-core/src/shared/months'; import { integerToAmount } from 'loot-core/src/shared/util'; -import { type DataEntity } from 'loot-core/src/types/models/reports'; +import { type GroupedEntity } from 'loot-core/src/types/models/reports'; import { categoryLists, ReportOptions } from '../ReportOptions'; @@ -41,7 +41,7 @@ export function createGroupedSpreadsheet({ return async ( spreadsheet: ReturnType, - setData: (data: DataEntity[]) => void, + setData: (data: GroupedEntity[]) => void, ) => { if (categoryList.length === 0) { return; @@ -100,7 +100,7 @@ export function createGroupedSpreadsheet({ endDate, ); - const groupedData: DataEntity[] = categoryGroup.map( + const groupedData: GroupedEntity[] = categoryGroup.map( group => { let totalAssets = 0; let totalDebts = 0; diff --git a/packages/loot-core/src/types/models/reports.d.ts b/packages/loot-core/src/types/models/reports.d.ts index f1c01d6ab0a..563de0b1f44 100644 --- a/packages/loot-core/src/types/models/reports.d.ts +++ b/packages/loot-core/src/types/models/reports.d.ts @@ -57,10 +57,10 @@ export interface SpendingEntity { totalTotals: number; } -export interface GroupedEntity { - data?: DataEntity[]; - intervalData: DataEntity[]; - groupedData?: DataEntity[] | null; +export interface DataEntity { + data?: GroupedEntity[]; + intervalData: IntervalEntity[]; + groupedData?: GroupedEntity[] | null; legend?: LegendEntity[]; startDate?: string; endDate?: string; @@ -75,33 +75,25 @@ type LegendEntity = { color: string; }; -export type ItemEntity = { - id: string; - name: string; - intervalData: IntervalData[]; - totalAssets: number; - totalDebts: number; - totalTotals: number; -}; - -export type IntervalData = { - date: string; - dateLookup: string; +export type IntervalEntity = { + date?: string; + dateStart?: string; + change?: number; + dateLookup?: string; totalAssets: number; totalDebts: number; totalTotals: number; }; -export interface DataEntity { +export interface GroupedEntity { id: string; name: string; date?: string; - dateStart?: string; - intervalData: IntervalData[]; - categories?: ItemEntity[]; + intervalData: IntervalEntity[]; totalAssets: number; totalDebts: number; totalTotals: number; + categories?: GroupedEntity[]; } export type Interval = { From 7ae341bffb55adc656b05c0e2bb30d251c228b30 Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 13:43:02 +0100 Subject: [PATCH 02/10] notes --- upcoming-release-notes/2726.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 upcoming-release-notes/2726.md diff --git a/upcoming-release-notes/2726.md b/upcoming-release-notes/2726.md new file mode 100644 index 00000000000..b6fffc3da21 --- /dev/null +++ b/upcoming-release-notes/2726.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [carkom] +--- + +Making files in custom reports to comply with TS strict - stage #1. From 73ac83911a4fd0aaaef051d03ba361f153ef88ef Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 13:53:02 +0100 Subject: [PATCH 03/10] TS strict custom spreadsheets --- .../src/components/reports/ReportOptions.ts | 38 ++-- .../spreadsheets/custom-spreadsheet.ts | 164 +++++++++--------- .../reports/spreadsheets/filterEmptyRows.ts | 16 +- .../spreadsheets/grouped-spreadsheet.ts | 6 +- 4 files changed, 127 insertions(+), 97 deletions(-) diff --git a/packages/desktop-client/src/components/reports/ReportOptions.ts b/packages/desktop-client/src/components/reports/ReportOptions.ts index e8c7bd8becf..0ae9c6b0a52 100644 --- a/packages/desktop-client/src/components/reports/ReportOptions.ts +++ b/packages/desktop-client/src/components/reports/ReportOptions.ts @@ -226,7 +226,10 @@ export type QueryDataEntity = { amount: number; }; -export type UncategorizedEntity = Pick & { +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 @@ -241,6 +244,7 @@ export type UncategorizedEntity = Pick & { }; const uncategorizedCategory: UncategorizedEntity = { + id: '', name: 'Uncategorized', uncategorized_id: '1', hidden: false, @@ -249,6 +253,7 @@ const uncategorizedCategory: UncategorizedEntity = { has_category: false, }; const transferCategory: UncategorizedEntity = { + id: '', name: 'Transfers', uncategorized_id: '2', hidden: false, @@ -257,6 +262,7 @@ const transferCategory: UncategorizedEntity = { has_category: false, }; const offBudgetCategory: UncategorizedEntity = { + id: '', name: 'Off Budget', uncategorized_id: '3', hidden: false, @@ -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); @@ -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': diff --git a/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts index 149c5678577..182922413c8 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/custom-spreadsheet.ts @@ -1,4 +1,3 @@ -// @ts-strict-ignore import * as d from 'date-fns'; import { runQuery } from 'loot-core/src/client/query-helpers'; @@ -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'; @@ -41,7 +46,7 @@ export type createCustomSpreadsheetProps = { showHiddenCategories: boolean; showUncategorized: boolean; groupBy?: string; - balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals'; + balanceTypeOp?: keyof GroupedEntity; payees?: PayeeEntity[]; accounts?: AccountEntity[]; graphType?: string; @@ -61,10 +66,10 @@ export function createCustomSpreadsheet({ showOffBudget, showHiddenCategories, showUncategorized, - groupBy, - balanceTypeOp = 'totalDebts', - payees, - accounts, + groupBy = '', + balanceTypeOp, + payees = [], + accounts = [], graphType, firstDayOfWeekIdx, setDataCheck, @@ -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, @@ -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', @@ -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 = {}; - 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, @@ -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( diff --git a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts index 2e1d9ca985b..02a48e459b7 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts @@ -1,10 +1,14 @@ -import { type DataEntity } from 'loot-core/src/types/models/reports'; +import { type GroupedEntity } from 'loot-core/src/types/models/reports'; -export function filterEmptyRows( - showEmpty: boolean, - data: DataEntity, - balanceTypeOp: keyof DataEntity, -): boolean { +export function filterEmptyRows({ + showEmpty, + data, + balanceTypeOp = 'totalDebts', +}: { + showEmpty: boolean; + data: GroupedEntity; + balanceTypeOp?: keyof GroupedEntity; +}): boolean { let showHide: boolean; if (balanceTypeOp === 'totalTotals') { showHide = diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts index 9bd7b45d9aa..0995a14fc64 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts @@ -176,14 +176,16 @@ export function createGroupedSpreadsheet({ totalTotals: integerToAmount(totalAssets + totalDebts), intervalData, categories: stackedCategories.filter(i => - filterEmptyRows(showEmpty, i, balanceTypeOp), + filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), ), }; }, [startDate, endDate], ); setData( - groupedData.filter(i => filterEmptyRows(showEmpty, i, balanceTypeOp)), + groupedData.filter(i => + filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), + ), ); }; } From c51659e5522c1cdb8ca842b06d46f9a96de96ddc Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 13:55:53 +0100 Subject: [PATCH 04/10] notes --- upcoming-release-notes/{2726.md => 2727.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename upcoming-release-notes/{2726.md => 2727.md} (96%) diff --git a/upcoming-release-notes/2726.md b/upcoming-release-notes/2727.md similarity index 96% rename from upcoming-release-notes/2726.md rename to upcoming-release-notes/2727.md index b6fffc3da21..78ec3a25f07 100644 --- a/upcoming-release-notes/2726.md +++ b/upcoming-release-notes/2727.md @@ -3,4 +3,4 @@ category: Maintenance authors: [carkom] --- -Making files in custom reports to comply with TS strict - stage #1. +Making files in custom reports to comply with TS strict - stage #2. From 0eb992c88a4e2118af596b4105959b1e41e0d10f Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 14:07:10 +0100 Subject: [PATCH 05/10] TS strict group speadsheets --- .../src/components/reports/ChooseGraph.tsx | 60 ++++--- .../src/components/reports/Container.tsx | 9 +- .../src/components/reports/GraphButton.tsx | 3 +- .../spreadsheets/grouped-spreadsheet.ts | 146 ++++++++++-------- .../reports/spreadsheets/recalculate.ts | 101 ++++++------ 5 files changed, 180 insertions(+), 139 deletions(-) diff --git a/packages/desktop-client/src/components/reports/ChooseGraph.tsx b/packages/desktop-client/src/components/reports/ChooseGraph.tsx index 0e19a7c1467..6d2e557e1f1 100644 --- a/packages/desktop-client/src/components/reports/ChooseGraph.tsx +++ b/packages/desktop-client/src/components/reports/ChooseGraph.tsx @@ -1,5 +1,4 @@ -// @ts-strict-ignore -import React, { useRef } from 'react'; +import React, { type UIEvent, useRef } from 'react'; import { type DataEntity } from 'loot-core/src/types/models/reports'; import { type RuleConditionEntity } from 'loot-core/types/models/rule'; @@ -29,55 +28,70 @@ type ChooseGraphProps = { interval: string; setScrollWidth?: (value: number) => void; viewLabels?: boolean; - compact?: boolean; + compact: boolean; style?: CSSProperties; showHiddenCategories?: boolean; showOffBudget?: boolean; - intervalsCount?: number; + intervalsCount: number; }; export function ChooseGraph({ data, - filters, + filters = [], mode, graphType, balanceType, groupBy, interval, setScrollWidth, - viewLabels, + viewLabels = false, compact, style, - showHiddenCategories, - showOffBudget, + showHiddenCategories = false, + showOffBudget = false, intervalsCount, }: ChooseGraphProps) { const graphStyle = compact ? { ...style } : { flexGrow: 1 }; - const balanceTypeOp = ReportOptions.balanceTypeMap.get(balanceType); + const balanceTypeOp = + ReportOptions.balanceTypeMap.get(balanceType) || 'totalDebts'; - const saveScrollWidth = value => { - setScrollWidth(!value ? 0 : value); + const saveScrollWidth = (value: number) => { + setScrollWidth?.(value || 0); }; - const rowStyle = compact && { flex: '0 0 20px', height: 20 }; - const compactStyle = compact && { ...styles.tinyText }; + const rowStyle: CSSProperties = compact + ? { flex: '0 0 20px', height: 20 } + : {}; + const compactStyle: CSSProperties = compact ? { ...styles.tinyText } : {}; const headerScrollRef = useRef(null); const listScrollRef = useRef(null); const totalScrollRef = useRef(null); - const handleScroll = scroll => { - if (scroll.target.id === 'header') { - totalScrollRef.current.scrollLeft = scroll.target.scrollLeft; - listScrollRef.current.scrollLeft = scroll.target.scrollLeft; + const handleScroll = (scroll: UIEvent) => { + if ( + scroll.currentTarget.id === 'header' && + totalScrollRef.current && + listScrollRef.current + ) { + totalScrollRef.current.scrollLeft = scroll.currentTarget.scrollLeft; + listScrollRef.current.scrollLeft = scroll.currentTarget.scrollLeft; } - if (scroll.target.id === 'total') { - headerScrollRef.current.scrollLeft = scroll.target.scrollLeft; - listScrollRef.current.scrollLeft = scroll.target.scrollLeft; + if ( + scroll.currentTarget.id === 'total' && + headerScrollRef.current && + listScrollRef.current + ) { + headerScrollRef.current.scrollLeft = scroll.currentTarget.scrollLeft; + listScrollRef.current.scrollLeft = scroll.currentTarget.scrollLeft; } - if (scroll.target.id === 'list') { - headerScrollRef.current.scrollLeft = scroll.target.scrollLeft; - totalScrollRef.current.scrollLeft = scroll.target.scrollLeft; + if ( + scroll.currentTarget.id === 'list' && + totalScrollRef.current && + headerScrollRef.current + ) { + headerScrollRef.current.scrollLeft = scroll.currentTarget.scrollLeft; + totalScrollRef.current.scrollLeft = scroll.currentTarget.scrollLeft; } }; diff --git a/packages/desktop-client/src/components/reports/Container.tsx b/packages/desktop-client/src/components/reports/Container.tsx index 93b968fc1bc..e169cc28b22 100644 --- a/packages/desktop-client/src/components/reports/Container.tsx +++ b/packages/desktop-client/src/components/reports/Container.tsx @@ -1,4 +1,3 @@ -// @ts-strict-ignore import React, { useRef, type ReactNode } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; @@ -7,7 +6,11 @@ import { View } from '../common/View'; type ContainerProps = { style?: CSSProperties; - children: (width: number, height: number, host: HTMLDivElement) => ReactNode; + children: ( + width: number, + height: number, + host: HTMLDivElement | null, + ) => ReactNode; }; export function Container({ style, children }: ContainerProps) { const portalHost = useRef(null); @@ -18,7 +21,7 @@ export function Container({ style, children }: ContainerProps) { >
- {({ width, height }) => ( + {({ width, height }: { width: number; height: number }) => (
{children(width, height, portalHost.current)}
diff --git a/packages/desktop-client/src/components/reports/GraphButton.tsx b/packages/desktop-client/src/components/reports/GraphButton.tsx index 0c155d2166d..f648ca14e74 100644 --- a/packages/desktop-client/src/components/reports/GraphButton.tsx +++ b/packages/desktop-client/src/components/reports/GraphButton.tsx @@ -1,4 +1,3 @@ -// @ts-strict-ignore import React, { type HTMLProps } from 'react'; import { type CSSProperties, theme } from '../../style'; @@ -10,7 +9,7 @@ import { Tooltip } from '../tooltips'; type GraphButtonProps = HTMLProps & { selected?: boolean; style?: CSSProperties; - onSelect?: (newValue) => void; + onSelect?: (newValue: string) => void; title?: string; disabled?: boolean; }; diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts index 0995a14fc64..fc40cd99589 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts @@ -1,12 +1,18 @@ -// @ts-strict-ignore import { runQuery } from 'loot-core/src/client/query-helpers'; import { type useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider'; import { send } from 'loot-core/src/platform/client/fetch'; import * as monthUtils from 'loot-core/src/shared/months'; import { integerToAmount } from 'loot-core/src/shared/util'; -import { type GroupedEntity } from 'loot-core/src/types/models/reports'; +import { + type IntervalEntity, + type GroupedEntity, +} from 'loot-core/src/types/models/reports'; -import { categoryLists, ReportOptions } from '../ReportOptions'; +import { + categoryLists, + type QueryDataEntity, + ReportOptions, +} from '../ReportOptions'; import { type createCustomSpreadsheetProps } from './custom-spreadsheet'; import { filterEmptyRows } from './filterEmptyRows'; @@ -52,7 +58,9 @@ export function createGroupedSpreadsheet({ }); 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', @@ -95,87 +103,95 @@ export function createGroupedSpreadsheet({ const intervals = interval === 'Weekly' ? monthUtils.weekRangeInclusive(startDate, endDate, firstDayOfWeekIdx) - : monthUtils[ReportOptions.intervalRange.get(interval)]( - startDate, - endDate, - ); + : monthUtils[ + ReportOptions.intervalRange.get(interval) || 'rangeInclusive' + ](startDate, endDate); const groupedData: GroupedEntity[] = categoryGroup.map( group => { let totalAssets = 0; let totalDebts = 0; - const intervalData = intervals.reduce((arr, intervalItem) => { - let groupedAssets = 0; - let groupedDebts = 0; - - group.categories.forEach(item => { - const intervalAssets = filterHiddenItems( - item, - assets, - showOffBudget, - showHiddenCategories, - showUncategorized, - ) - .filter( - asset => - asset.date === intervalItem && - asset.category === (item.id ?? null), + const intervalData = intervals.reduce( + (arr: IntervalEntity[], intervalItem) => { + let groupedAssets = 0; + let groupedDebts = 0; + + if (!group.categories) { + return []; + } + + group.categories.forEach(item => { + const intervalAssets = filterHiddenItems( + item, + assets, + showOffBudget, + showHiddenCategories, + showUncategorized, ) - .reduce((a, v) => (a = a + v.amount), 0); - groupedAssets += intervalAssets; - - const intervalDebts = filterHiddenItems( + .filter( + asset => + asset.date === intervalItem && + asset.category === (item.id ?? null), + ) + .reduce((a, v) => (a = a + v.amount), 0); + groupedAssets += intervalAssets; + + const intervalDebts = filterHiddenItems( + item, + debts, + showOffBudget, + showHiddenCategories, + showUncategorized, + ) + .filter( + debts => + debts.date === intervalItem && + debts.category === (item.id ?? null), + ) + .reduce((a, v) => (a = a + v.amount), 0); + groupedDebts += intervalDebts; + }); + + totalAssets += groupedAssets; + totalDebts += groupedDebts; + + arr.push({ + date: intervalItem, + totalAssets: integerToAmount(groupedAssets), + totalDebts: integerToAmount(groupedDebts), + totalTotals: integerToAmount(groupedDebts + groupedAssets), + }); + + return arr; + }, + [], + ); + + const stackedCategories = + group.categories && + group.categories.map(item => { + const calc = recalculate({ item, + intervals, + assets, debts, + groupByLabel: 'category', showOffBudget, showHiddenCategories, showUncategorized, - ) - .filter( - debts => - debts.date === intervalItem && - debts.category === (item.id ?? null), - ) - .reduce((a, v) => (a = a + v.amount), 0); - groupedDebts += intervalDebts; - }); - - totalAssets += groupedAssets; - totalDebts += groupedDebts; - - arr.push({ - date: intervalItem, - totalAssets: integerToAmount(groupedAssets), - totalDebts: integerToAmount(groupedDebts), - totalTotals: integerToAmount(groupedDebts + groupedAssets), - }); - - return arr; - }, []); - - const stackedCategories = group.categories.map(item => { - const calc = recalculate({ - item, - intervals, - assets, - debts, - groupByLabel: 'category', - showOffBudget, - showHiddenCategories, - showUncategorized, + }); + return { ...calc }; }); - return { ...calc }; - }); return { - id: group.id, + id: group.id || '', name: group.name, totalAssets: integerToAmount(totalAssets), totalDebts: integerToAmount(totalDebts), totalTotals: integerToAmount(totalAssets + totalDebts), intervalData, - categories: stackedCategories.filter(i => + categories: stackedCategories && stackedCategories.filter(i => filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), ), }; diff --git a/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts b/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts index a19ed597310..a7262dde838 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/recalculate.ts @@ -1,16 +1,22 @@ -// @ts-strict-ignore import { amountToInteger, integerToAmount } from 'loot-core/src/shared/util'; +import { + type GroupedEntity, + type IntervalEntity, +} from 'loot-core/types/models/reports'; -import { type QueryDataEntity } from '../ReportOptions'; +import { + type UncategorizedEntity, + type QueryDataEntity, +} from '../ReportOptions'; import { filterHiddenItems } from './filterHiddenItems'; type recalculateProps = { - item; + item: UncategorizedEntity; intervals: Array; assets: QueryDataEntity[]; debts: QueryDataEntity[]; - groupByLabel: string; + groupByLabel: 'category' | 'categoryGroup' | 'payee' | 'account'; showOffBudget?: boolean; showHiddenCategories?: boolean; showUncategorized?: boolean; @@ -25,59 +31,62 @@ export function recalculate({ showOffBudget, showHiddenCategories, showUncategorized, -}: recalculateProps) { +}: recalculateProps): GroupedEntity { let totalAssets = 0; let totalDebts = 0; - const intervalData = intervals.reduce((arr, intervalItem) => { - const last = arr.length === 0 ? null : arr[arr.length - 1]; + const intervalData = intervals.reduce( + (arr: IntervalEntity[], intervalItem) => { + const last = arr.length === 0 ? null : arr[arr.length - 1]; - 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); - totalAssets += intervalAssets; + .filter( + asset => + asset.date === intervalItem && + asset[groupByLabel] === (item.id ?? null), + ) + .reduce((a, v) => (a = a + v.amount), 0); + totalAssets += 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); - totalDebts += intervalDebts; + .filter( + debt => + debt.date === intervalItem && + debt[groupByLabel] === (item.id ?? null), + ) + .reduce((a, v) => (a = a + v.amount), 0); + totalDebts += intervalDebts; - const change = last - ? intervalAssets + intervalDebts - amountToInteger(last.totalTotals) - : 0; + const change = last + ? intervalAssets + intervalDebts - amountToInteger(last.totalTotals) + : 0; - arr.push({ - totalAssets: integerToAmount(intervalAssets), - totalDebts: integerToAmount(intervalDebts), - totalTotals: integerToAmount(intervalAssets + intervalDebts), - change, - dateLookup: intervalItem, - }); + arr.push({ + totalAssets: integerToAmount(intervalAssets), + totalDebts: integerToAmount(intervalDebts), + totalTotals: integerToAmount(intervalAssets + intervalDebts), + change, + dateLookup: intervalItem, + }); - return arr; - }, []); + return arr; + }, + [], + ); return { - id: item.id, + id: item.id || '', name: item.name, totalAssets: integerToAmount(totalAssets), totalDebts: integerToAmount(totalDebts), From f8bce9708826fc815207c7cfd323ac4bba068f86 Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 14:08:29 +0100 Subject: [PATCH 06/10] notes --- upcoming-release-notes/{2727.md => 2728.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename upcoming-release-notes/{2727.md => 2728.md} (96%) diff --git a/upcoming-release-notes/2727.md b/upcoming-release-notes/2728.md similarity index 96% rename from upcoming-release-notes/2727.md rename to upcoming-release-notes/2728.md index 78ec3a25f07..77a4068ca16 100644 --- a/upcoming-release-notes/2727.md +++ b/upcoming-release-notes/2728.md @@ -3,4 +3,4 @@ category: Maintenance authors: [carkom] --- -Making files in custom reports to comply with TS strict - stage #2. +Making files in custom reports to comply with TS strict - stage #3. From fc801db6b2d6dd90fa9d7ccea07ecbe518fc3e06 Mon Sep 17 00:00:00 2001 From: carkom Date: Wed, 8 May 2024 15:52:14 +0100 Subject: [PATCH 07/10] AreaGraph --- .../components/reports/graphs/AreaGraph.tsx | 42 ++++++++++++++----- .../spreadsheets/grouped-spreadsheet.ts | 8 ++-- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx index 860d2c7fcdf..94999532993 100644 --- a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx @@ -1,4 +1,3 @@ -// @ts-strict-ignore import React from 'react'; import { css } from 'glamor'; @@ -25,7 +24,6 @@ import { theme } from '../../../style'; import { type CSSProperties } from '../../../style'; import { AlignedText } from '../../common/AlignedText'; import { Container } from '../Container'; -import { numberFormatterTooltip } from '../numberFormatter'; import { adjustTextSize } from './adjustTextSize'; import { renderCustomLabel } from './renderCustomLabel'; @@ -42,7 +40,7 @@ type PayloadItem = { type CustomTooltipProps = { active?: boolean; payload?: PayloadItem[]; - balanceTypeOp?: string; + balanceTypeOp: 'totalAssets' | 'totalTotals' | 'totalDebts'; }; const CustomTooltip = ({ @@ -95,16 +93,37 @@ const CustomTooltip = ({
); } + + return
; +}; + +type PropsItem = { + index?: number; + x?: string | number; + y?: string | number; + value?: string | number; + width?: string | number; }; -const customLabel = (props, width, end) => { +const customLabel = ({ + props, + width, + end, +}: { + props: PropsItem; + width: number; + end: number; +}) => { //Add margin to first and last object const calcX = - props.x + (props.index === end ? -10 : props.index === 0 ? 5 : 0); - const calcY = props.y - (props.value > 0 ? 10 : -10); + (typeof props.x === 'number' ? props.x : 0) + + (props.index === end ? -10 : props.index === 0 ? 5 : 0); + const calcY = + (typeof props.y === 'number' ? props.y : 0) - + ((typeof props.value === 'number' ? props.value : 0) > 0 ? 10 : -10); const textAnchor = props.index === 0 ? 'left' : 'middle'; const display = - props.value !== 0 && `${amountToCurrencyNoDecimal(props.value)}`; + props.value !== 0 ? `${amountToCurrencyNoDecimal(props.value)}` : ''; const textSize = adjustTextSize({ sized: width, type: 'area' }); return renderCustomLabel(calcX, calcY, textAnchor, display, textSize); @@ -113,7 +132,7 @@ const customLabel = (props, width, end) => { type AreaGraphProps = { style?: CSSProperties; data: DataEntity; - balanceTypeOp: string; + balanceTypeOp: 'totalAssets' | 'totalTotals' | 'totalDebts'; compact?: boolean; viewLabels: boolean; }; @@ -148,7 +167,7 @@ export function AreaGraph({ : Math.ceil((dataMax + extendRangeAmount) / 100) * 100; const lastLabel = data.intervalData.length - 1; - const tickFormatter = tick => { + const tickFormatter = (tick: number) => { if (!privacyMode) return `${amountToCurrencyNoDecimal(tick)}`; // Formats the tick values as strings with commas return '...'; }; @@ -216,7 +235,6 @@ export function AreaGraph({ {(!isNarrowWidth || !compact) && ( } - formatter={numberFormatterTooltip} isAnimationActive={false} /> )} @@ -272,7 +290,9 @@ export function AreaGraph({ {viewLabels && !compact && ( customLabel(e, width, lastLabel)} + content={props => + customLabel({ props, width, end: lastLabel }) + } /> )} diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts index fc40cd99589..170cc421316 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts @@ -191,9 +191,11 @@ export function createGroupedSpreadsheet({ totalDebts: integerToAmount(totalDebts), totalTotals: integerToAmount(totalAssets + totalDebts), intervalData, - categories: stackedCategories && stackedCategories.filter(i => - filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), - ), + categories: + stackedCategories && + stackedCategories.filter(i => + filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), + ), }; }, [startDate, endDate], From d6ad4bb432a50d3249872fb0530672aa3d117821 Mon Sep 17 00:00:00 2001 From: carkom Date: Mon, 13 May 2024 05:43:10 +0100 Subject: [PATCH 08/10] render row changes --- .../graphs/tableGraph/RenderTableRow.tsx | 55 ++++++++++++++ .../reports/graphs/tableGraph/ReportTable.tsx | 22 +++--- .../graphs/tableGraph/ReportTableList.tsx | 72 +++---------------- 3 files changed, 75 insertions(+), 74 deletions(-) create mode 100644 packages/desktop-client/src/components/reports/graphs/tableGraph/RenderTableRow.tsx diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/RenderTableRow.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/RenderTableRow.tsx new file mode 100644 index 00000000000..aad73c34239 --- /dev/null +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/RenderTableRow.tsx @@ -0,0 +1,55 @@ +import React, { type ReactNode } from 'react'; + +import { type GroupedEntity } from 'loot-core/src/types/models/reports'; + +import { type CSSProperties } from '../../../../style'; +import { View } from '../../../common/View'; + +import { type renderRowProps } from './ReportTable'; + +type RenderTableRowProps = { + index: number; + parent_index?: number; + compact: boolean; + renderRow: (arg: renderRowProps) => ReactNode; + intervalsCount: number; + mode: string; + metadata: GroupedEntity[]; + style?: CSSProperties; + compactStyle?: CSSProperties; +}; + +export function RenderTableRow({ + index, + parent_index, + compact, + renderRow, + intervalsCount, + mode, + metadata, + style, + compactStyle, +}: RenderTableRowProps) { + const child = metadata[index]; + const parent = + parent_index !== undefined ? metadata[parent_index] : ({} as GroupedEntity); + + const item = + parent_index === undefined + ? child + : (parent.categories && parent.categories[index]) || + ({} as GroupedEntity); + + return ( + + {renderRow({ + item, + mode, + intervalsCount, + compact, + style, + compactStyle, + })} + + ); +} diff --git a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx index ab55c2ffb90..c45be017ec6 100644 --- a/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx +++ b/packages/desktop-client/src/components/reports/graphs/tableGraph/ReportTable.tsx @@ -36,6 +36,15 @@ type ReportTableProps = { showOffBudget?: boolean; }; +export type renderRowProps = { + item: GroupedEntity; + mode: string; + intervalsCount: number; + compact: boolean; + style?: CSSProperties; + compactStyle?: CSSProperties; +}; + export function ReportTable({ saveScrollWidth, listScrollRef, @@ -60,7 +69,7 @@ export function ReportTable({ } }); - const renderItem = useCallback( + const renderRow = useCallback( ({ item, mode, @@ -68,14 +77,7 @@ export function ReportTable({ compact, style, compactStyle, - }: { - item: GroupedEntity; - mode: string; - intervalsCount: number; - compact: boolean; - style?: CSSProperties; - compactStyle?: CSSProperties; - }) => { + }: renderRowProps) => { return ( ReactNode; - intervalsCount: number; - mode: string; - metadata: GroupedEntity[]; - style?: CSSProperties; - compactStyle?: CSSProperties; -}; - -function RenderRow({ - index, - parent_index, - compact, - renderItem, - intervalsCount, - mode, - metadata, - style, - compactStyle, -}: RenderRowProps) { - const child = metadata[index]; - const parent = - parent_index !== undefined ? metadata[parent_index] : ({} as GroupedEntity); - - const item = - parent_index === undefined - ? child - : (parent.categories && parent.categories[index]) || - ({} as GroupedEntity); - - const renderRow = renderItem({ - item, - mode, - intervalsCount, - compact, - style, - compactStyle, - }); - - return {renderRow}; -} +import { RenderTableRow } from './RenderTableRow'; +import { type renderRowProps } from './ReportTable'; type ReportTableListProps = { data: DataEntity; mode: string; intervalsCount: number; groupBy: string; - renderItem: (arg: { - item: GroupedEntity; - mode: string; - intervalsCount: number; - compact: boolean; - style?: CSSProperties; - compactStyle?: CSSProperties; - }) => ReactNode; + renderRow: (arg: renderRowProps) => ReactNode; compact: boolean; style?: CSSProperties; compactStyle?: CSSProperties; @@ -84,7 +28,7 @@ export function ReportTableList({ intervalsCount, mode, groupBy, - renderItem, + renderRow, compact, style, compactStyle, @@ -114,10 +58,10 @@ export function ReportTableList({ {metadata.map((item, index) => { return ( - { return ( - Date: Mon, 13 May 2024 21:21:06 +0100 Subject: [PATCH 09/10] type fix --- .../desktop-client/src/components/reports/graphs/AreaGraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx index 5a864814651..94999532993 100644 --- a/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/AreaGraph.tsx @@ -123,7 +123,7 @@ const customLabel = ({ ((typeof props.value === 'number' ? props.value : 0) > 0 ? 10 : -10); const textAnchor = props.index === 0 ? 'left' : 'middle'; const display = - props.value !== 0 && `${amountToCurrencyNoDecimal(props.value)}`; + props.value !== 0 ? `${amountToCurrencyNoDecimal(props.value)}` : ''; const textSize = adjustTextSize({ sized: width, type: 'area' }); return renderCustomLabel(calcX, calcY, textAnchor, display, textSize); From 0722eeba8230992a2fd6e864dd630490c68c383e Mon Sep 17 00:00:00 2001 From: carkom Date: Tue, 14 May 2024 20:12:07 +0100 Subject: [PATCH 10/10] merge fixes --- .../src/components/reports/graphs/BarGraph.tsx | 4 ++-- .../src/components/reports/graphs/DonutGraph.tsx | 2 +- .../src/components/reports/graphs/LineGraph.tsx | 2 +- .../src/components/reports/graphs/StackedBarGraph.tsx | 2 +- .../src/components/reports/graphs/showActivity.ts | 2 +- .../components/reports/spreadsheets/calculateLegend.ts | 2 +- .../components/reports/spreadsheets/filterEmptyRows.ts | 2 +- .../reports/spreadsheets/grouped-spreadsheet.ts | 8 +++++--- 8 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx index e8d1eb26b7a..6b455cf2346 100644 --- a/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/BarGraph.tsx @@ -59,7 +59,7 @@ type PayloadItem = { type CustomTooltipProps = { active?: boolean; payload?: PayloadItem[]; - balanceTypeOp?: string; + balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals'; yAxis?: string; }; @@ -136,7 +136,7 @@ type BarGraphProps = { data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; - balanceTypeOp: string; + balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; compact?: boolean; viewLabels: boolean; showHiddenCategories?: boolean; diff --git a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx index c1f50df27a3..7267f49b791 100644 --- a/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/DonutGraph.tsx @@ -180,7 +180,7 @@ type DonutGraphProps = { data: DataEntity; filters: RuleConditionEntity[]; groupBy: string; - balanceTypeOp: string; + balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; compact?: boolean; viewLabels: boolean; showHiddenCategories?: boolean; diff --git a/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx b/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx index 3cb78f3d4df..15577b4e952 100644 --- a/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/LineGraph.tsx @@ -113,7 +113,7 @@ type LineGraphProps = { filters: RuleConditionEntity[]; groupBy: string; compact?: boolean; - balanceTypeOp: string; + balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; showHiddenCategories?: boolean; showOffBudget?: boolean; }; diff --git a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx index 2df89692dac..f2c2807eb1d 100644 --- a/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx +++ b/packages/desktop-client/src/components/reports/graphs/StackedBarGraph.tsx @@ -143,7 +143,7 @@ type StackedBarGraphProps = { groupBy: string; compact?: boolean; viewLabels: boolean; - balanceTypeOp: string; + balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; showHiddenCategories?: boolean; showOffBudget?: boolean; }; diff --git a/packages/desktop-client/src/components/reports/graphs/showActivity.ts b/packages/desktop-client/src/components/reports/graphs/showActivity.ts index f0f6673bd73..fdbe64f8268 100644 --- a/packages/desktop-client/src/components/reports/graphs/showActivity.ts +++ b/packages/desktop-client/src/components/reports/graphs/showActivity.ts @@ -9,7 +9,7 @@ type showActivityProps = { navigate: NavigateFunction; categories: { list: CategoryEntity[]; grouped: CategoryGroupEntity[] }; accounts: AccountEntity[]; - balanceTypeOp: string; + balanceTypeOp: 'totalAssets' | 'totalDebts' | 'totalTotals'; filters: RuleConditionEntity[]; showHiddenCategories: boolean; showOffBudget: boolean; diff --git a/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts b/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts index de1ed867585..7ada7dec8d9 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/calculateLegend.ts @@ -12,7 +12,7 @@ export function calculateLegend( calcDataFiltered: GroupedEntity[], groupBy: string, graphType?: string, - balanceTypeOp?: keyof GroupedEntity, + balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals', ): LegendEntity[] { const colorScale = getColorScale('qualitative'); const chooseData = diff --git a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts index 02a48e459b7..b133a67da13 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/filterEmptyRows.ts @@ -7,7 +7,7 @@ export function filterEmptyRows({ }: { showEmpty: boolean; data: GroupedEntity; - balanceTypeOp?: keyof GroupedEntity; + balanceTypeOp?: 'totalAssets' | 'totalDebts' | 'totalTotals'; }): boolean { let showHide: boolean; if (balanceTypeOp === 'totalTotals') { diff --git a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts index 32669f30964..170cc421316 100644 --- a/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts +++ b/packages/desktop-client/src/components/reports/spreadsheets/grouped-spreadsheet.ts @@ -191,9 +191,11 @@ export function createGroupedSpreadsheet({ totalDebts: integerToAmount(totalDebts), totalTotals: integerToAmount(totalAssets + totalDebts), intervalData, - categories: stackedCategories.filter(i => - filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), - ), + categories: + stackedCategories && + stackedCategories.filter(i => + filterEmptyRows({ showEmpty, data: i, balanceTypeOp }), + ), }; }, [startDate, endDate],