From 177b20e8eaf23a609efa4002dc949cedaca627e9 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Tue, 26 May 2026 12:16:19 +0330 Subject: [PATCH] fix(reports): clarify summary actions and chart data --- src/components/reports/ReportsChartPanel.tsx | 27 +++++++++++----- src/components/reports/ReportsTablePanel.tsx | 34 +++++++++++++------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/components/reports/ReportsChartPanel.tsx b/src/components/reports/ReportsChartPanel.tsx index d7c6c24..fc662d8 100644 --- a/src/components/reports/ReportsChartPanel.tsx +++ b/src/components/reports/ReportsChartPanel.tsx @@ -65,7 +65,7 @@ const currencyLabel = (currency: string, lang: "en" | "fa") => { const formatMoneyTotals = (totals: CurrencyTotal[], lang: "en" | "fa") => { if (!totals.length) { - return "-" + return localizeDigits("0", lang) } return totals.map((item) => `${formatAmount(item.amount, lang, item.currency)} ${currencyLabel(item.currency, lang)}`).join(" | ") @@ -194,13 +194,24 @@ const buildSeriesBuckets = ( const createSeriesKey = (series: ChartReportSeries, index: number) => series.user?.id ?? `series_${index}` +const effectiveSeries = (data: ChartReportResponse): ChartReportSeries[] => + data.series.length + ? data.series + : [ + { + user: null, + buckets: [], + }, + ] + const buildChartRows = (data: ChartReportResponse, lang: "en" | "fa") => { const useMonthlyBuckets = data.scope.period === "this_year" || data.scope.period === "half_year_first" || data.scope.period === "half_year_second" - const normalizedSeries = data.series.map((series) => buildSeriesBuckets(series, data, lang, useMonthlyBuckets)) + const seriesList = effectiveSeries(data) + const normalizedSeries = seriesList.map((series) => buildSeriesBuckets(series, data, lang, useMonthlyBuckets)) const baseBuckets = normalizedSeries[0] ?? [] const rows: ChartRow[] = baseBuckets.map((bucket, bucketIndex) => { @@ -214,7 +225,7 @@ const buildChartRows = (data: ChartReportResponse, lang: "en" | "fa") => { tooltip_label: tooltipLabel, } - data.series.forEach((series, seriesIndex) => { + seriesList.forEach((series, seriesIndex) => { const seriesKey = createSeriesKey(series, seriesIndex) row[seriesKey] = normalizedSeries[seriesIndex]?.[bucketIndex]?.total_seconds ?? 0 }) @@ -222,7 +233,7 @@ const buildChartRows = (data: ChartReportResponse, lang: "en" | "fa") => { return row }) - return { rows, useMonthlyBuckets } + return { rows, seriesList, useMonthlyBuckets } } function ChartTooltip({ @@ -300,14 +311,14 @@ export function ReportsChartPanel({ ) } - if (!data || data.series.length === 0) { + if (!data) { return null } - const { rows, useMonthlyBuckets } = buildChartRows(data, lang) + const { rows, seriesList, useMonthlyBuckets } = buildChartRows(data, lang) const interval = useMonthlyBuckets ? 0 : rows.length > 20 ? Math.ceil(rows.length / 10) - 1 : 0 const chartMinWidth = Math.max(640, rows.length * (useMonthlyBuckets ? 110 : 52)) - const isMultiSeries = data.series.length > 1 + const isMultiSeries = seriesList.length > 1 return (
@@ -385,7 +396,7 @@ export function ReportsChartPanel({ wrapperStyle={{ paddingBottom: "16px", fontSize: "12px" }} /> ) : null} - {data.series.map((series, index) => { + {seriesList.map((series, index) => { const dataKey = createSeriesKey(series, index) return ( { }; const formatMoneyTotals = (totals: { currency: string; amount: string }[], lang: "en" | "fa") => { - if (!totals.length) return "-"; + if (!totals.length) return localizeDigits("0", lang); return totals .map((item) => `${formatAmount(item.amount, lang, item.currency)} ${currencyLabel(item.currency, lang)}`) .join(" | "); }; const formatHourlyRate = (rate: { currency: string; amount: string } | null, lang: "en" | "fa") => { - if (!rate) return "-"; + if (!rate) return localizeDigits("0", lang); return `${formatAmount(rate.amount, lang, rate.currency)} ${currencyLabel(rate.currency, lang)}`; }; @@ -321,7 +321,8 @@ function UserSummaryDetailsModal({ - + + @@ -329,13 +330,14 @@ function UserSummaryDetailsModal({ + {isLoading ? ( Array.from({ length: 3 }).map((_, index) => ( - @@ -351,11 +353,12 @@ function UserSummaryDetailsModal({ + )) ) : ( - @@ -507,20 +510,27 @@ function UserSummarySection({ {!financialOnly ? : null} + {rows.map((row) => ( - void openSummaryDetails(row)} - > + {!financialOnly ? : null} + ))} @@ -720,7 +730,7 @@ function DailyDetailsSection({ - +
{labels.hourlyRate} {labels.fromDate} {labels.toDate}{labels.project}
+
{formatDisplayDate(row.from_date, lang)} {formatRateToLabel(row.to_date, lang, labels.now)}{row.project_name || "-"}
+ {labels.noData}
{labels.workingHours}{labels.nonWorkingHours}{labels.totalIncome}{labels.details}
{row.user.name} {localizeDigits(row.user.mobile, lang)} {localizeDigits(row.billable_duration, lang)}{localizeDigits(row.non_billable_duration, lang)}{formatMoneyTotals(row.income_totals, lang)} + +
{labels.total} {localizeDigits(summary.billable_duration, lang)} {localizeDigits(summary.non_billable_duration, lang)}-{localizeDigits("0", lang)} {formatMoneyTotals(summary.income_totals, lang)}