mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 12:43:09 -05:00
Refactor: extract tooltip components and clean up lint suppressions (#6721)
* Refactor: extract tooltip components and clean up lint suppressions Extract CustomTooltip components from CrossoverGraph and NetWorthGraph to module level to fix unstable nested components lint warnings. Also consolidate theme file lint rule into oxlintrc.json and add proper typing to styles object. * Add release notes for maintenance updates addressing lint violations * Remove style prop from CustomTooltip to prevent container layout styles from affecting tooltip Co-authored-by: matiss <matiss@mja.lv> * Refactor NetWorthGraph component by extracting TrendTooltip and StackedTooltip into separate functions for improved readability and maintainability. Update tooltip props to include necessary parameters for rendering. Clean up unused code and enhance tooltip styling. * Refactor NetWorthGraph component to streamline tooltip handling - Removed unnecessary prop passing for translation function in TrendTooltip. - Adjusted import statements for better clarity and consistency. - Cleaned up code to enhance readability and maintainability. --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
committed by
GitHub
parent
84cebed20b
commit
c8aa0cf1d3
@@ -390,6 +390,12 @@
|
||||
"typescript-paths/absolute-import": ["error", { "enableAlias": false }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["packages/desktop-client/src/style/themes/*"],
|
||||
"rules": {
|
||||
"eslint/no-restricted-imports": "off"
|
||||
}
|
||||
},
|
||||
// TODO: enable these
|
||||
{
|
||||
"files": [
|
||||
|
||||
@@ -12,8 +12,7 @@ const shadowLarge = {
|
||||
boxShadow: '0 15px 30px 0 rgba(0,0,0,0.11), 0 5px 15px 0 rgba(0,0,0,0.08)',
|
||||
};
|
||||
|
||||
// oxlint-disable-next-line typescript/no-explicit-any
|
||||
export const styles: Record<string, any> = {
|
||||
export const styles: CSSProperties = {
|
||||
incomeHeaderHeight: 70,
|
||||
cardShadow: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)',
|
||||
monthRightPadding: 5,
|
||||
|
||||
@@ -20,6 +20,119 @@ import { Container } from '@desktop-client/components/reports/Container';
|
||||
import { useFormat } from '@desktop-client/hooks/useFormat';
|
||||
import { usePrivacyMode } from '@desktop-client/hooks/usePrivacyMode';
|
||||
|
||||
type PayloadItem = {
|
||||
payload: {
|
||||
x: string;
|
||||
investmentIncome: number | string;
|
||||
expenses: number | string;
|
||||
nestEgg: number | string;
|
||||
adjustedExpenses?: number | string;
|
||||
isProjection?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
type CustomTooltipProps = {
|
||||
active?: boolean;
|
||||
payload?: PayloadItem[];
|
||||
};
|
||||
|
||||
function CustomTooltip({ active, payload }: CustomTooltipProps) {
|
||||
const { t } = useTranslation();
|
||||
const format = useFormat();
|
||||
|
||||
if (active && payload && payload.length) {
|
||||
return (
|
||||
<div
|
||||
className={css({
|
||||
zIndex: 1000,
|
||||
pointerEvents: 'none',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0 1px 6px rgba(0, 0, 0, .20)',
|
||||
backgroundColor: theme.menuBackground,
|
||||
color: theme.menuItemText,
|
||||
padding: 10,
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<strong>{payload[0].payload.x}</strong>
|
||||
{payload[0].payload.isProjection ? (
|
||||
<span style={{ marginLeft: 8, opacity: 0.7 }}>
|
||||
{t('(projected)')}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div style={{ lineHeight: 1.5 }}>
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Monthly investment income:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.investmentIncome, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Monthly expenses:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.expenses, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
{payload[0].payload.adjustedExpenses != null && (
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Target income:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.adjustedExpenses, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
)}
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Life savings:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.nestEgg, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
type CrossoverGraphProps = {
|
||||
style?: CSSProperties;
|
||||
graphData: {
|
||||
@@ -45,7 +158,6 @@ export function CrossoverGraph({
|
||||
compact = false,
|
||||
showTooltip = true,
|
||||
}: CrossoverGraphProps) {
|
||||
const { t } = useTranslation();
|
||||
const privacyMode = usePrivacyMode();
|
||||
const format = useFormat();
|
||||
const animationProps = useRechartsAnimation({ isAnimationActive: false });
|
||||
@@ -57,116 +169,6 @@ export function CrossoverGraph({
|
||||
return `${format(Math.round(tick), 'financial-no-decimals')}`;
|
||||
};
|
||||
|
||||
type PayloadItem = {
|
||||
payload: {
|
||||
x: string;
|
||||
investmentIncome: number | string;
|
||||
expenses: number | string;
|
||||
nestEgg: number | string;
|
||||
adjustedExpenses?: number | string;
|
||||
isProjection?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
type CustomTooltipProps = {
|
||||
active?: boolean;
|
||||
payload?: PayloadItem[];
|
||||
};
|
||||
|
||||
// oxlint-disable-next-line react/no-unstable-nested-components
|
||||
const CustomTooltip = ({ active, payload }: CustomTooltipProps) => {
|
||||
if (active && payload && payload.length) {
|
||||
return (
|
||||
<div
|
||||
className={css({
|
||||
zIndex: 1000,
|
||||
pointerEvents: 'none',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0 1px 6px rgba(0, 0, 0, .20)',
|
||||
backgroundColor: theme.menuBackground,
|
||||
color: theme.menuItemText,
|
||||
padding: 10,
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<strong>{payload[0].payload.x}</strong>
|
||||
{payload[0].payload.isProjection ? (
|
||||
<span style={{ marginLeft: 8, opacity: 0.7 }}>
|
||||
{t('(projected)')}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<div style={{ lineHeight: 1.5 }}>
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Monthly investment income:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.investmentIncome, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Monthly expenses:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.expenses, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
{payload[0].payload.adjustedExpenses != null && (
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Target income:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.adjustedExpenses, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
)}
|
||||
<View
|
||||
className={css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
<Trans>Life savings:</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<FinancialText>
|
||||
{format(payload[0].payload.nestEgg, 'financial')}
|
||||
</FinancialText>
|
||||
</div>
|
||||
</View>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Container
|
||||
style={{
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
import { Container } from '@desktop-client/components/reports/Container';
|
||||
import { numberFormatterTooltip } from '@desktop-client/components/reports/numberFormatter';
|
||||
import { useFormat } from '@desktop-client/hooks/useFormat';
|
||||
import type { UseFormatResult } from '@desktop-client/hooks/useFormat';
|
||||
import { usePrivacyMode } from '@desktop-client/hooks/usePrivacyMode';
|
||||
|
||||
type NetWorthDataPoint = {
|
||||
@@ -40,6 +41,188 @@ type NetWorthDataPoint = {
|
||||
date: string;
|
||||
} & Record<string, string | number>;
|
||||
|
||||
type TrendTooltipProps = TooltipContentProps<number, string> & {
|
||||
style?: CSSProperties;
|
||||
};
|
||||
|
||||
function TrendTooltip({ active, payload, style }: TrendTooltipProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (active && payload && payload.length) {
|
||||
return (
|
||||
<div
|
||||
className={css([
|
||||
{
|
||||
zIndex: 1000,
|
||||
pointerEvents: 'none',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0 1px 6px rgba(0, 0, 0, .20)',
|
||||
backgroundColor: theme.menuBackground,
|
||||
color: theme.menuItemText,
|
||||
padding: 10,
|
||||
},
|
||||
style,
|
||||
])}
|
||||
>
|
||||
<div>
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<strong>{payload[0].payload.date}</strong>
|
||||
</div>
|
||||
<div style={{ lineHeight: 1.5 }}>
|
||||
<AlignedText
|
||||
left={t('Assets:')}
|
||||
right={<FinancialText>{payload[0].payload.assets}</FinancialText>}
|
||||
/>
|
||||
<AlignedText
|
||||
left={t('Debt:')}
|
||||
right={<FinancialText>{payload[0].payload.debt}</FinancialText>}
|
||||
/>
|
||||
<AlignedText
|
||||
left={t('Net worth:')}
|
||||
right={
|
||||
<FinancialText as="strong">
|
||||
{payload[0].payload.networth}
|
||||
</FinancialText>
|
||||
}
|
||||
/>
|
||||
<AlignedText
|
||||
left={t('Change:')}
|
||||
right={<FinancialText>{payload[0].payload.change}</FinancialText>}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
type StackedTooltipProps = TooltipContentProps<number, string> & {
|
||||
sortedAccounts: Array<{ id: string; name: string }>;
|
||||
accounts: Array<{ id: string; name: string }>;
|
||||
hoveredAccountId: string | null;
|
||||
format: UseFormatResult;
|
||||
};
|
||||
|
||||
function StackedTooltip({
|
||||
active,
|
||||
payload,
|
||||
sortedAccounts,
|
||||
accounts,
|
||||
hoveredAccountId,
|
||||
format,
|
||||
}: StackedTooltipProps) {
|
||||
if (active && payload && payload.length) {
|
||||
// Calculate total from payload (visible accounts)
|
||||
const total = payload.reduce(
|
||||
(acc: number, p) => acc + (Number(p.value) || 0),
|
||||
0,
|
||||
);
|
||||
const sortedPayload = [...payload].sort((a, b) => {
|
||||
const indexA = sortedAccounts.findIndex(acc => acc.id === a.dataKey);
|
||||
const indexB = sortedAccounts.findIndex(acc => acc.id === b.dataKey);
|
||||
return indexB - indexA;
|
||||
});
|
||||
|
||||
const hasPositive = payload.some(p => (Number(p.value) || 0) > 0);
|
||||
const hasNegative = payload.some(p => (Number(p.value) || 0) < 0);
|
||||
const showPercentage = !(hasPositive && hasNegative);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={css([
|
||||
{
|
||||
zIndex: 1000,
|
||||
pointerEvents: 'auto',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0 1px 6px rgba(0, 0, 0, .20)',
|
||||
backgroundColor: theme.menuBackground,
|
||||
color: theme.menuItemText,
|
||||
padding: 10,
|
||||
fontSize: 12,
|
||||
maxHeight: '80vh',
|
||||
overflowY: 'auto',
|
||||
},
|
||||
])}
|
||||
>
|
||||
<div style={{ marginBottom: 10, fontWeight: 'bold' }}>
|
||||
{payload[0].payload.date}
|
||||
</div>
|
||||
<table style={{ borderSpacing: '15px 0', marginLeft: '-15px' }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ textAlign: 'left', paddingLeft: 15 }}>
|
||||
<Trans>Account</Trans>
|
||||
</th>
|
||||
<th style={{ textAlign: 'right' }}>
|
||||
<Trans>Value</Trans>
|
||||
</th>
|
||||
{showPercentage && <th style={{ textAlign: 'right' }}>%</th>}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{sortedPayload.map(entry => {
|
||||
const accountId = entry.dataKey as string;
|
||||
const accountName =
|
||||
accounts.find(a => a.id === accountId)?.name || accountId;
|
||||
const value = Number(entry.value);
|
||||
const percent = total !== 0 ? (value / total) * 100 : 0;
|
||||
|
||||
return (
|
||||
<tr key={accountId} style={{ color: entry.color }}>
|
||||
<td
|
||||
style={{
|
||||
textAlign: 'left',
|
||||
paddingLeft: 15,
|
||||
textDecoration:
|
||||
hoveredAccountId === accountId
|
||||
? 'underline'
|
||||
: undefined,
|
||||
}}
|
||||
>
|
||||
{accountName}
|
||||
</td>
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<span style={{ color: theme.pageText }}>
|
||||
<FinancialText>
|
||||
{format(value, 'financial')}
|
||||
</FinancialText>
|
||||
</span>
|
||||
</td>
|
||||
{showPercentage && (
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<span style={{ color: theme.pageText }}>
|
||||
<FinancialText>{percent.toFixed(1)}%</FinancialText>
|
||||
</span>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
<tr
|
||||
style={{
|
||||
fontWeight: 'bold',
|
||||
borderTop: '1px solid ' + theme.tableBorder,
|
||||
}}
|
||||
>
|
||||
<td style={{ textAlign: 'left', paddingLeft: 15, paddingTop: 5 }}>
|
||||
<Trans>Total</Trans>
|
||||
</td>
|
||||
<td style={{ textAlign: 'right', paddingTop: 5 }}>
|
||||
<FinancialText>{format(total, 'financial')}</FinancialText>
|
||||
</td>
|
||||
{showPercentage && (
|
||||
<td style={{ textAlign: 'right', paddingTop: 5 }}>100.0%</td>
|
||||
)}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
type NetWorthGraphProps = {
|
||||
style?: CSSProperties;
|
||||
graphData: {
|
||||
@@ -64,7 +247,6 @@ export function NetWorthGraph({
|
||||
interval = 'Monthly',
|
||||
mode = 'trend',
|
||||
}: NetWorthGraphProps) {
|
||||
const { t } = useTranslation();
|
||||
const privacyMode = usePrivacyMode();
|
||||
const id = useId();
|
||||
const format = useFormat();
|
||||
@@ -151,184 +333,6 @@ export function NetWorthGraph({
|
||||
.map(point => point.x);
|
||||
}, [interval, graphData.data]);
|
||||
|
||||
// Trend Tooltip
|
||||
// oxlint-disable-next-line react/no-unstable-nested-components
|
||||
const TrendTooltip = ({
|
||||
active,
|
||||
payload,
|
||||
}: TooltipContentProps<number, string>) => {
|
||||
if (active && payload && payload.length) {
|
||||
return (
|
||||
<div
|
||||
className={css([
|
||||
{
|
||||
zIndex: 1000,
|
||||
pointerEvents: 'none',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0 1px 6px rgba(0, 0, 0, .20)',
|
||||
backgroundColor: theme.menuBackground,
|
||||
color: theme.menuItemText,
|
||||
padding: 10,
|
||||
},
|
||||
style,
|
||||
])}
|
||||
>
|
||||
<div>
|
||||
<div style={{ marginBottom: 10 }}>
|
||||
<strong>{payload[0].payload.date}</strong>
|
||||
</div>
|
||||
<div style={{ lineHeight: 1.5 }}>
|
||||
<AlignedText
|
||||
left={t('Assets:')}
|
||||
right={
|
||||
<FinancialText>{payload[0].payload.assets}</FinancialText>
|
||||
}
|
||||
/>
|
||||
<AlignedText
|
||||
left={t('Debt:')}
|
||||
right={<FinancialText>{payload[0].payload.debt}</FinancialText>}
|
||||
/>
|
||||
<AlignedText
|
||||
left={t('Net worth:')}
|
||||
right={
|
||||
<FinancialText as="strong">
|
||||
{payload[0].payload.networth}
|
||||
</FinancialText>
|
||||
}
|
||||
/>
|
||||
<AlignedText
|
||||
left={t('Change:')}
|
||||
right={
|
||||
<FinancialText>{payload[0].payload.change}</FinancialText>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// Stacked Tooltip
|
||||
// oxlint-disable-next-line react/no-unstable-nested-components
|
||||
const StackedTooltip = ({
|
||||
active,
|
||||
payload,
|
||||
}: TooltipContentProps<number, string>) => {
|
||||
if (active && payload && payload.length) {
|
||||
// Calculate total from payload (visible accounts)
|
||||
const total = payload.reduce(
|
||||
(acc: number, p) => acc + (Number(p.value) || 0),
|
||||
0,
|
||||
);
|
||||
const sortedPayload = [...payload].sort((a, b) => {
|
||||
const indexA = sortedAccounts.findIndex(acc => acc.id === a.dataKey);
|
||||
const indexB = sortedAccounts.findIndex(acc => acc.id === b.dataKey);
|
||||
return indexB - indexA;
|
||||
});
|
||||
|
||||
const hasPositive = payload.some(p => (Number(p.value) || 0) > 0);
|
||||
const hasNegative = payload.some(p => (Number(p.value) || 0) < 0);
|
||||
const showPercentage = !(hasPositive && hasNegative);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={css([
|
||||
{
|
||||
zIndex: 1000,
|
||||
pointerEvents: 'auto',
|
||||
borderRadius: 2,
|
||||
boxShadow: '0 1px 6px rgba(0, 0, 0, .20)',
|
||||
backgroundColor: theme.menuBackground,
|
||||
color: theme.menuItemText,
|
||||
padding: 10,
|
||||
fontSize: 12,
|
||||
maxHeight: '80vh',
|
||||
overflowY: 'auto',
|
||||
},
|
||||
])}
|
||||
>
|
||||
<div style={{ marginBottom: 10, fontWeight: 'bold' }}>
|
||||
{payload[0].payload.date}
|
||||
</div>
|
||||
<table style={{ borderSpacing: '15px 0', marginLeft: '-15px' }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ textAlign: 'left', paddingLeft: 15 }}>
|
||||
<Trans>Account</Trans>
|
||||
</th>
|
||||
<th style={{ textAlign: 'right' }}>
|
||||
<Trans>Value</Trans>
|
||||
</th>
|
||||
{showPercentage && <th style={{ textAlign: 'right' }}>%</th>}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{sortedPayload.map(entry => {
|
||||
const accountId = entry.dataKey as string;
|
||||
const accountName =
|
||||
accounts.find(a => a.id === accountId)?.name || accountId;
|
||||
const value = Number(entry.value);
|
||||
const percent = total !== 0 ? (value / total) * 100 : 0;
|
||||
|
||||
return (
|
||||
<tr key={accountId} style={{ color: entry.color }}>
|
||||
<td
|
||||
style={{
|
||||
textAlign: 'left',
|
||||
paddingLeft: 15,
|
||||
textDecoration:
|
||||
hoveredAccountId === accountId
|
||||
? 'underline'
|
||||
: undefined,
|
||||
}}
|
||||
>
|
||||
{accountName}
|
||||
</td>
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<span style={{ color: theme.pageText }}>
|
||||
<FinancialText>
|
||||
{format(value, 'financial')}
|
||||
</FinancialText>
|
||||
</span>
|
||||
</td>
|
||||
{showPercentage && (
|
||||
<td style={{ textAlign: 'right' }}>
|
||||
<span style={{ color: theme.pageText }}>
|
||||
<FinancialText>{percent.toFixed(1)}%</FinancialText>
|
||||
</span>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
<tr
|
||||
style={{
|
||||
fontWeight: 'bold',
|
||||
borderTop: '1px solid ' + theme.tableBorder,
|
||||
}}
|
||||
>
|
||||
<td
|
||||
style={{ textAlign: 'left', paddingLeft: 15, paddingTop: 5 }}
|
||||
>
|
||||
<Trans>Total</Trans>
|
||||
</td>
|
||||
<td style={{ textAlign: 'right', paddingTop: 5 }}>
|
||||
<FinancialText>{format(total, 'financial')}</FinancialText>
|
||||
</td>
|
||||
{showPercentage && (
|
||||
<td style={{ textAlign: 'right', paddingTop: 5 }}>100.0%</td>
|
||||
)}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
<Container
|
||||
style={{
|
||||
@@ -391,14 +395,22 @@ export function NetWorthGraph({
|
||||
/>
|
||||
{effectiveShowTooltip && mode === 'trend' && (
|
||||
<Tooltip<number, string>
|
||||
content={props => <TrendTooltip {...props} />}
|
||||
content={props => <TrendTooltip {...props} style={style} />}
|
||||
formatter={numberFormatterTooltip}
|
||||
isAnimationActive={false}
|
||||
/>
|
||||
)}
|
||||
{effectiveShowTooltip && mode === 'stacked' && (
|
||||
<Tooltip<number, string>
|
||||
content={props => <StackedTooltip {...props} />}
|
||||
content={props => (
|
||||
<StackedTooltip
|
||||
{...props}
|
||||
sortedAccounts={sortedAccounts}
|
||||
accounts={accounts}
|
||||
hoveredAccountId={hoveredAccountId}
|
||||
format={format}
|
||||
/>
|
||||
)}
|
||||
isAnimationActive={false}
|
||||
wrapperStyle={{ zIndex: 9999, pointerEvents: 'auto' }}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// oxlint-disable-next-line eslint/no-restricted-imports
|
||||
import * as colorPalette from '@desktop-client/style/palette';
|
||||
|
||||
export const pageBackground = colorPalette.gray900;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// oxlint-disable-next-line eslint/no-restricted-imports
|
||||
import * as colorPalette from '@desktop-client/style/palette';
|
||||
|
||||
export const pageBackground = colorPalette.navy100;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// oxlint-disable-next-line eslint/no-restricted-imports
|
||||
import * as colorPalette from '@desktop-client/style/palette';
|
||||
|
||||
export const pageBackground = colorPalette.navy100;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// oxlint-disable-next-line eslint/no-restricted-imports
|
||||
import * as colorPalette from '@desktop-client/style/palette';
|
||||
|
||||
export const pageBackground = colorPalette.gray600;
|
||||
|
||||
6
upcoming-release-notes/6721.md
Normal file
6
upcoming-release-notes/6721.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Maintenance
|
||||
authors: [MatissJanis]
|
||||
---
|
||||
|
||||
lint: fix low-hanging fruit violations
|
||||
Reference in New Issue
Block a user