From 5ca165ee039b6a39d62866667ee851f2661e6a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=9D=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Tue, 1 Sep 2026 15:58:53 +0300 Subject: [PATCH] Add payroll work statistics modal --- .../finance/PayrollDailyWorkSection.tsx | 150 ++++++++++-------- .../finance/PayrollWorkDatePicker.tsx | 6 +- .../EmployeePayrollWorkProfileSection.tsx | 42 ++++- 3 files changed, 121 insertions(+), 77 deletions(-) diff --git a/frontend/src/components/finance/PayrollDailyWorkSection.tsx b/frontend/src/components/finance/PayrollDailyWorkSection.tsx index 03667d34..816d0c9a 100644 --- a/frontend/src/components/finance/PayrollDailyWorkSection.tsx +++ b/frontend/src/components/finance/PayrollDailyWorkSection.tsx @@ -51,9 +51,13 @@ function currentEntryForDate( } export function PayrollDailyWorkSection({ + compactPeriodSelector = false, + detailsTarget, embedded = false, periodSelectorTargetId, }: { + compactPeriodSelector?: boolean; + detailsTarget?: HTMLElement | null; embedded?: boolean; periodSelectorTargetId?: string; }) { @@ -201,6 +205,7 @@ export function PayrollDailyWorkSection({ const periodStatus = selectedPeriod ? periodStatusMeta[selectedPeriod.status] : null; const periodSelector = ( +
+
+

Выработка

+

Ежедневные баллы

+
+ + {selectedPeriod ? ( +
+
+

Период

+

{getPayrollPeriodRange(selectedPeriod)}

+ {periodStatus ? {periodStatus.label} : null} +
+
+

Норма за период

+

{formatPayrollPoints(summary?.target_points, "0")}

+

+ {summary?.target_source === "saved_record" ? "Из сохранённой записи" : `По графику: ${summary?.workdays_count || 0} дн.`} +

+
+
+
+
+

Фактически за период

+

+ {formatPayrollPoints(summary?.actual_points, "0")} / {formatPayrollPoints(summary?.target_points, "0")} +

+
+ {aggregateStatus ? {aggregateStatus.label} : null} +
+
+
+ ) : null} +
+ +
+
+

Записи за период

+ {workspace.entries.length} +
+ {workspace.entries.length ? ( +
+ {workspace.entries.map((entry) => ( + + ))} +
+ ) : ( +
+

За выбранный период записей пока нет.

+
+ )} +
+ + ); return (
@@ -299,75 +377,9 @@ export function PayrollDailyWorkSection({ -
-
-

Выработка

-

Ежедневные баллы

-
- - {selectedPeriod ? ( -
-
-

Период

-

{getPayrollPeriodRange(selectedPeriod)}

- {periodStatus ? {periodStatus.label} : null} -
-
-

Норма за период

-

{formatPayrollPoints(summary?.target_points, "0")}

-

- {summary?.target_source === "saved_record" ? "Из сохранённой записи" : `По графику: ${summary?.workdays_count || 0} дн.`} -

-
-
-
-
-

Фактически за период

-

- {formatPayrollPoints(summary?.actual_points, "0")} / {formatPayrollPoints(summary?.target_points, "0")} -

-
- {aggregateStatus ? {aggregateStatus.label} : null} -
-
-
- ) : null} -
- -
-
-

Записи за период

- {workspace.entries.length} -
- {workspace.entries.length ? ( -
- {workspace.entries.map((entry) => ( - - ))} -
- ) : ( -
-

За выбранный период записей пока нет.

-
- )} -
+ {detailsTarget !== undefined + ? detailsTarget ? createPortal(detailsContent, detailsTarget) : null + : detailsContent}
); } diff --git a/frontend/src/components/finance/PayrollWorkDatePicker.tsx b/frontend/src/components/finance/PayrollWorkDatePicker.tsx index 9f88c828..241275a1 100644 --- a/frontend/src/components/finance/PayrollWorkDatePicker.tsx +++ b/frontend/src/components/finance/PayrollWorkDatePicker.tsx @@ -27,6 +27,7 @@ function compactDate(value: string): string { } export function PayrollWorkDatePicker({ + compact = false, periods, selectedPeriod, selectedDate, @@ -35,6 +36,7 @@ export function PayrollWorkDatePicker({ onSelectDate, onSelectPeriod, }: { + compact?: boolean; periods: PayrollOwnWorkPeriod[]; selectedPeriod: PayrollOwnWorkPeriod | null; selectedDate: string; @@ -78,10 +80,10 @@ export function PayrollWorkDatePicker({ }, [open]); return ( -
+
+
+ + +
- {open ? ( -
- -
- ) : null} +
+ +
+ + setStatisticsOpen(false)} + title="Статистика по выработке" + size="md" + closeOnClickOutside + > +
+ + ); }