From f3539a5f36dee3f1a9a5a6081c0675dc5cbd14bc Mon Sep 17 00:00:00 2001 From: PotapovaA Date: Thu, 1 Oct 2026 18:20:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D1=81=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/FORM_4/STRUCTURE.js | 806 +++++++++--------- .../RealtimeTable/hooks/useRealtimeData.js | 40 +- .../RealtimeTable/utils/rowUtils.js | 31 + .../RealtimeTable/utils/rowUtils.test.js | 21 + .../ProjectPages/ProjectSummariesPage.jsx | 4 +- web/src/pages/Svod2Page/Svod2Page.jsx | 18 +- web/src/pages/SvodPage/SummaryTable.jsx | 41 +- web/src/pages/SvodPage/SvodPage.jsx | 4 +- 8 files changed, 491 insertions(+), 474 deletions(-) create mode 100644 web/src/components/RealtimeTable/utils/rowUtils.test.js diff --git a/web/src/components/RealtimeTable/constants/FORM_4/STRUCTURE.js b/web/src/components/RealtimeTable/constants/FORM_4/STRUCTURE.js index 1f6f899..a85ad36 100644 --- a/web/src/components/RealtimeTable/constants/FORM_4/STRUCTURE.js +++ b/web/src/components/RealtimeTable/constants/FORM_4/STRUCTURE.js @@ -9,769 +9,769 @@ import { export const config = { config: { colors: { - 'data.header.section_code': { + "data.header.section_code": { color_type: greenColumn, - accessorKey: 'data.header.section_code', + accessorKey: "data.header.section_code", }, - 'data.header.item_id': { + "data.header.item_id": { color_type: greenColumn, - accessorKey: 'data.header.item_id', + accessorKey: "data.header.item_id", }, - 'data.header.num_group': { + "data.header.num_group": { color_type: greenColumn, - accessorKey: 'data.header.num_group', + accessorKey: "data.header.num_group", }, - 'data.header.name': { + "data.header.name": { color_type: greenColumn, - accessorKey: 'data.header.name', + accessorKey: "data.header.name", }, - 'data.header.internal_order': { + "data.header.internal_order": { color_type: greenColumn, - accessorKey: 'data.header.internal_order', + accessorKey: "data.header.internal_order", }, - 'data.plan.q1': { + "data.plan.q1": { color_type: greenColumn, - accessorKey: 'data.plan.q1', + accessorKey: "data.plan.q1", }, - 'data.plan.q2': { + "data.plan.q2": { color_type: greenColumn, - accessorKey: 'data.plan.q2', + accessorKey: "data.plan.q2", }, - 'data.plan.q3': { + "data.plan.q3": { color_type: greenColumn, - accessorKey: 'data.plan.q3', + accessorKey: "data.plan.q3", }, - 'data.plan.q4': { + "data.plan.q4": { color_type: greenColumn, - accessorKey: 'data.plan.q4', + accessorKey: "data.plan.q4", }, - 'data.plan.year': { + "data.plan.year": { color_type: greenColumn, - accessorKey: 'data.plan.year', + accessorKey: "data.plan.year", }, - 'data.plan.comment': { + "data.plan.comment": { color_type: greenColumn, - accessorKey: 'data.plan.comment', + accessorKey: "data.plan.comment", }, - 'data.contract_summary.amount': { + "data.contract_summary.amount": { color_type: greenColumn, - accessorKey: 'data.contract_summary.amount', + accessorKey: "data.contract_summary.amount", }, - 'data.contract_summary.counterparty': { + "data.contract_summary.counterparty": { color_type: greenColumn, - accessorKey: 'data.contract_summary.counterparty', + accessorKey: "data.contract_summary.counterparty", }, - 'data.contract_summary.deadline': { + "data.contract_summary.deadline": { color_type: greenColumn, - accessorKey: 'data.contract_summary.deadline', + accessorKey: "data.contract_summary.deadline", }, - 'data.contract_summary.comment': { + "data.contract_summary.comment": { color_type: greenColumn, - accessorKey: 'data.contract_summary.comment', + accessorKey: "data.contract_summary.comment", }, - 'data.contract_summary.future_payments_y1': { + "data.contract_summary.future_payments_y1": { color_type: greenColumn, - accessorKey: 'data.contract_summary.future_payments_y1', + accessorKey: "data.contract_summary.future_payments_y1", }, - 'data.contract_summary.future_payments_y2': { + "data.contract_summary.future_payments_y2": { color_type: greenColumn, - accessorKey: 'data.contract_summary.future_payments_y2', + accessorKey: "data.contract_summary.future_payments_y2", }, - 'data.contract_summary.other_ssp_amount': { + "data.contract_summary.other_ssp_amount": { color_type: greenColumn, - accessorKey: 'data.contract_summary.other_ssp_amount', + accessorKey: "data.contract_summary.other_ssp_amount", }, - 'data.allocation.contract_ref': { + "data.allocation.contract_ref": { color_type: greenColumn, - accessorKey: 'data.allocation.contract_ref', + accessorKey: "data.allocation.contract_ref", }, - 'data.allocation.allocation_purpose': { + "data.allocation.allocation_purpose": { color_type: greenColumn, - accessorKey: 'data.allocation.allocation_purpose', + accessorKey: "data.allocation.allocation_purpose", }, - 'data.seq_dfip.q1': { + "data.seq_dfip.q1": { color_type: greenColumn, - accessorKey: 'data.seq_dfip.q1', + accessorKey: "data.seq_dfip.q1", }, - 'data.seq_dfip.q2': { + "data.seq_dfip.q2": { color_type: greenColumn, - accessorKey: 'data.seq_dfip.q2', + accessorKey: "data.seq_dfip.q2", }, - 'data.seq_dfip.q3': { + "data.seq_dfip.q3": { color_type: greenColumn, - accessorKey: 'data.seq_dfip.q3', + accessorKey: "data.seq_dfip.q3", }, - 'data.seq_dfip.q4': { + "data.seq_dfip.q4": { color_type: greenColumn, - accessorKey: 'data.seq_dfip.q4', + accessorKey: "data.seq_dfip.q4", }, - 'data.seq_dfip.year': { + "data.seq_dfip.year": { color_type: greenColumn, - accessorKey: 'data.seq_dfip.year', + accessorKey: "data.seq_dfip.year", }, - 'data.seq_dfip.justification': { + "data.seq_dfip.justification": { color_type: greenColumn, - accessorKey: 'data.seq_dfip.justification', + accessorKey: "data.seq_dfip.justification", }, - 'data.reserve.q1': { + "data.reserve.q1": { color_type: greenColumn, - accessorKey: 'data.reserve.q1', + accessorKey: "data.reserve.q1", }, - 'data.reserve.q2': { + "data.reserve.q2": { color_type: greenColumn, - accessorKey: 'data.reserve.q2', + accessorKey: "data.reserve.q2", }, - 'data.reserve.q3': { + "data.reserve.q3": { color_type: greenColumn, - accessorKey: 'data.reserve.q3', + accessorKey: "data.reserve.q3", }, - 'data.reserve.q4': { + "data.reserve.q4": { color_type: greenColumn, - accessorKey: 'data.reserve.q4', + accessorKey: "data.reserve.q4", }, - 'data.reserve.year': { + "data.reserve.year": { color_type: greenColumn, - accessorKey: 'data.reserve.year', + accessorKey: "data.reserve.year", }, - 'data.reserve.justification': { + "data.reserve.justification": { color_type: greenColumn, - accessorKey: 'data.reserve.justification', + accessorKey: "data.reserve.justification", }, - 'data.approved.q1': { + "data.approved.q1": { color_type: greenColumn, - accessorKey: 'data.approved.q1', + accessorKey: "data.approved.q1", }, - 'data.approved.q2': { + "data.approved.q2": { color_type: greenColumn, - accessorKey: 'data.approved.q2', + accessorKey: "data.approved.q2", }, - 'data.approved.q3': { + "data.approved.q3": { color_type: greenColumn, - accessorKey: 'data.approved.q3', + accessorKey: "data.approved.q3", }, - 'data.approved.q4': { + "data.approved.q4": { color_type: greenColumn, - accessorKey: 'data.approved.q4', + accessorKey: "data.approved.q4", }, - 'data.approved.year': { + "data.approved.year": { color_type: greenColumn, - accessorKey: 'data.approved.year', + accessorKey: "data.approved.year", }, - 'data.collegial.amount': { + "data.collegial.amount": { color_type: orangeColumn, - accessorKey: 'data.collegial.amount', + accessorKey: "data.collegial.amount", }, - 'data.collegial.protocol_reference': { + "data.collegial.protocol_reference": { color_type: orangeColumn, - accessorKey: 'data.collegial.protocol_reference', + accessorKey: "data.collegial.protocol_reference", }, field_kollegialnye_organy_field: { color_type: orangeColumn, - accessorKey: 'field_kollegialnye_organy_field', + accessorKey: "field_kollegialnye_organy_field", }, - 'data.collegial.note': { + "data.collegial.note": { color_type: orangeColumn, - accessorKey: 'data.collegial.note', + accessorKey: "data.collegial.note", }, field_field_field: { color_type: whiteColumn, - accessorKey: 'field_field_field', + accessorKey: "field_field_field", }, - 'data.ckk.ceiling': { + "data.ckk.ceiling": { color_type: orangeColumn, - accessorKey: 'data.ckk.ceiling', + accessorKey: "data.ckk.ceiling", }, - 'data.ckk.expenses_q1': { + "data.ckk.expenses_q1": { color_type: greenColumn, - accessorKey: 'data.ckk.expenses_q1', + accessorKey: "data.ckk.expenses_q1", }, - 'data.ckk.expenses_q2': { + "data.ckk.expenses_q2": { color_type: greenColumn, - accessorKey: 'data.ckk.expenses_q2', + accessorKey: "data.ckk.expenses_q2", }, - 'data.ckk.expenses_q3': { + "data.ckk.expenses_q3": { color_type: greenColumn, - accessorKey: 'data.ckk.expenses_q3', + accessorKey: "data.ckk.expenses_q3", }, - 'data.ckk.expenses_q4': { + "data.ckk.expenses_q4": { color_type: greenColumn, - accessorKey: 'data.ckk.expenses_q4', + accessorKey: "data.ckk.expenses_q4", }, - 'data.ckk.rf_schedule': { + "data.ckk.rf_schedule": { color_type: orangeColumn, - accessorKey: 'data.ckk.rf_schedule', + accessorKey: "data.ckk.rf_schedule", }, - 'data.ckk.delivery_deadline': { + "data.ckk.delivery_deadline": { color_type: orangeColumn, - accessorKey: 'data.ckk.delivery_deadline', + accessorKey: "data.ckk.delivery_deadline", }, - 'data.ckk.procurement_plan': { + "data.ckk.procurement_plan": { color_type: orangeColumn, - accessorKey: 'data.ckk.procurement_plan', + accessorKey: "data.ckk.procurement_plan", }, - 'data.ckk.procurement_method': { + "data.ckk.procurement_method": { color_type: orangeColumn, - accessorKey: 'data.ckk.procurement_method', + accessorKey: "data.ckk.procurement_method", }, - 'data.ckk.comment': { + "data.ckk.comment": { color_type: orangeColumn, - accessorKey: 'data.ckk.comment', + accessorKey: "data.ckk.comment", }, - 'data.contract.counterparty': { + "data.contract.counterparty": { color_type: orangeColumn, - accessorKey: 'data.contract.counterparty', + accessorKey: "data.contract.counterparty", }, - 'data.contract.reference': { + "data.contract.reference": { color_type: orangeColumn, - accessorKey: 'data.contract.reference', + accessorKey: "data.contract.reference", }, - 'data.contract.addenda': { + "data.contract.addenda": { color_type: orangeColumn, - accessorKey: 'data.contract.addenda', + accessorKey: "data.contract.addenda", }, - 'data.contract.subject': { + "data.contract.subject": { color_type: orangeColumn, - accessorKey: 'data.contract.subject', + accessorKey: "data.contract.subject", }, - 'data.contract.currency': { + "data.contract.currency": { color_type: orangeColumn, - accessorKey: 'data.contract.currency', + accessorKey: "data.contract.currency", }, - 'data.contract.ceiling': { + "data.contract.ceiling": { color_type: orangeColumn, - accessorKey: 'data.contract.ceiling', + accessorKey: "data.contract.ceiling", }, - 'data.contract.expenses_q1': { + "data.contract.expenses_q1": { color_type: greenColumn, - accessorKey: 'data.contract.expenses_q1', + accessorKey: "data.contract.expenses_q1", }, - 'data.contract.expenses_q2': { + "data.contract.expenses_q2": { color_type: greenColumn, - accessorKey: 'data.contract.expenses_q2', + accessorKey: "data.contract.expenses_q2", }, - 'data.contract.expenses_q3': { + "data.contract.expenses_q3": { color_type: greenColumn, - accessorKey: 'data.contract.expenses_q3', + accessorKey: "data.contract.expenses_q3", }, - 'data.contract.expenses_q4': { + "data.contract.expenses_q4": { color_type: greenColumn, - accessorKey: 'data.contract.expenses_q4', + accessorKey: "data.contract.expenses_q4", }, - 'data.contract.rf_schedule': { + "data.contract.rf_schedule": { color_type: orangeColumn, - accessorKey: 'data.contract.rf_schedule', + accessorKey: "data.contract.rf_schedule", }, - 'data.contract.vat_rate': { + "data.contract.vat_rate": { color_type: orangeColumn, - accessorKey: 'data.contract.vat_rate', + accessorKey: "data.contract.vat_rate", }, - 'data.contract.exchange_rate': { + "data.contract.exchange_rate": { color_type: orangeColumn, - accessorKey: 'data.contract.exchange_rate', + accessorKey: "data.contract.exchange_rate", }, - 'data.contract.amount_foreign': { + "data.contract.amount_foreign": { color_type: orangeColumn, - accessorKey: 'data.contract.amount_foreign', + accessorKey: "data.contract.amount_foreign", }, - 'data.contract.deadline': { + "data.contract.deadline": { color_type: orangeColumn, - accessorKey: 'data.contract.deadline', + accessorKey: "data.contract.deadline", }, - 'data.contract.scheme': { + "data.contract.scheme": { color_type: orangeColumn, - accessorKey: 'data.contract.scheme', + accessorKey: "data.contract.scheme", }, - 'data.contract.act': { + "data.contract.act": { color_type: orangeColumn, - accessorKey: 'data.contract.act', + accessorKey: "data.contract.act", }, - 'data.contract.comment': { + "data.contract.comment": { color_type: orangeColumn, - accessorKey: 'data.contract.comment', + accessorKey: "data.contract.comment", }, - 'data.q1.adj_current': { + "data.q1.adj_current": { color_type: yellowColumn, - accessorKey: 'data.q1.adj_current', + accessorKey: "data.q1.adj_current", }, - 'data.q1.adj_ssp': { + "data.q1.adj_ssp": { color_type: yellowColumn, - accessorKey: 'data.q1.adj_ssp', + accessorKey: "data.q1.adj_ssp", }, - 'data.q1.adj_rf': { + "data.q1.adj_rf": { color_type: yellowColumn, - accessorKey: 'data.q1.adj_rf', + accessorKey: "data.q1.adj_rf", }, - 'data.q1.adj_reserve': { + "data.q1.adj_reserve": { color_type: yellowColumn, - accessorKey: 'data.q1.adj_reserve', + accessorKey: "data.q1.adj_reserve", }, - '1_kvartal_2026_perenos_vo_2_kv_26_summa_tys_rub_bez_nds': { + "1_kvartal_2026_perenos_vo_2_kv_26_summa_tys_rub_bez_nds": { color_type: redColumn, - accessorKey: '1_kvartal_2026_perenos_vo_2_kv_26_summa_tys_rub_bez_nds', + accessorKey: "1_kvartal_2026_perenos_vo_2_kv_26_summa_tys_rub_bez_nds", }, - 'data.q1.adj_comment': { + "data.q1.adj_comment": { color_type: yellowColumn, - accessorKey: 'data.q1.adj_comment', + accessorKey: "data.q1.adj_comment", }, - 'data.q1.corrected_plan': { + "data.q1.corrected_plan": { color_type: yellowColumn, - accessorKey: 'data.q1.corrected_plan', + accessorKey: "data.q1.corrected_plan", }, - '1_kvartal_2026_field_field': { + "1_kvartal_2026_field_field": { color_type: whiteColumn, - accessorKey: '1_kvartal_2026_field_field', + accessorKey: "1_kvartal_2026_field_field", }, - 'data.q1.pay_date': { + "data.q1.pay_date": { color_type: blueColumn, - accessorKey: 'data.q1.pay_date', + accessorKey: "data.q1.pay_date", }, - 'data.q1.pay_amount': { + "data.q1.pay_amount": { color_type: blueColumn, - accessorKey: 'data.q1.pay_amount', + accessorKey: "data.q1.pay_amount", }, - 'data.q1.pay_ho': { + "data.q1.pay_ho": { color_type: blueColumn, - accessorKey: 'data.q1.pay_ho', + accessorKey: "data.q1.pay_ho", }, - 'data.q1.pay_rf': { + "data.q1.pay_rf": { color_type: blueColumn, - accessorKey: 'data.q1.pay_rf', + accessorKey: "data.q1.pay_rf", }, - 'data.q1.pay_comment': { + "data.q1.pay_comment": { color_type: blueColumn, - accessorKey: 'data.q1.pay_comment', + accessorKey: "data.q1.pay_comment", }, - 'data.q1.pay_act': { + "data.q1.pay_act": { color_type: blueColumn, - accessorKey: 'data.q1.pay_act', + accessorKey: "data.q1.pay_act", }, - 'data.q1.booking': { + "data.q1.booking": { color_type: orangeColumn, - accessorKey: 'data.q1.booking', + accessorKey: "data.q1.booking", }, - 'data.q1.actual_m1': { + "data.q1.actual_m1": { color_type: greenColumn, - accessorKey: 'data.q1.actual_m1', + accessorKey: "data.q1.actual_m1", }, - 'data.q1.actual_m2': { + "data.q1.actual_m2": { color_type: greenColumn, - accessorKey: 'data.q1.actual_m2', + accessorKey: "data.q1.actual_m2", }, - 'data.q1.actual_m3': { + "data.q1.actual_m3": { color_type: greenColumn, - accessorKey: 'data.q1.actual_m3', + accessorKey: "data.q1.actual_m3", }, - 'data.q1.actual_quarter': { + "data.q1.actual_quarter": { color_type: greenColumn, - accessorKey: 'data.q1.actual_quarter', + accessorKey: "data.q1.actual_quarter", }, - 'data.q1.residual_after_booking': { + "data.q1.residual_after_booking": { color_type: orangeColumn, - accessorKey: 'data.q1.residual_after_booking', + accessorKey: "data.q1.residual_after_booking", }, - 'data.q1.residual_after_actual': { + "data.q1.residual_after_actual": { color_type: greenColumn, - accessorKey: 'data.q1.residual_after_actual', + accessorKey: "data.q1.residual_after_actual", }, - 'data.q1.transfer_q2': { + "data.q1.transfer_q2": { color_type: redColumn, - accessorKey: 'data.q1.transfer_q2', + accessorKey: "data.q1.transfer_q2", }, - 'data.q1.transfer_q3': { + "data.q1.transfer_q3": { color_type: redColumn, - accessorKey: 'data.q1.transfer_q3', + accessorKey: "data.q1.transfer_q3", }, - 'data.q1.transfer_q4': { + "data.q1.transfer_q4": { color_type: redColumn, - accessorKey: 'data.q1.transfer_q4', + accessorKey: "data.q1.transfer_q4", }, - 'data.q1.transfer_econ': { + "data.q1.transfer_econ": { color_type: redColumn, - accessorKey: 'data.q1.transfer_econ', + accessorKey: "data.q1.transfer_econ", }, - 'data.q1.total': { + "data.q1.total": { color_type: redColumn, - accessorKey: 'data.q1.total', + accessorKey: "data.q1.total", }, - 'data.q2.target_change': { + "data.q2.target_change": { color_type: redColumn, - accessorKey: 'data.q2.target_change', + accessorKey: "data.q2.target_change", }, - 'data.q2.base_correction': { + "data.q2.base_correction": { color_type: redColumn, - accessorKey: 'data.q2.base_correction', + accessorKey: "data.q2.base_correction", }, - 'data.q2.revision_inc': { + "data.q2.revision_inc": { color_type: redColumn, - accessorKey: 'data.q2.revision_inc', + accessorKey: "data.q2.revision_inc", }, - 'data.q2.revision_seq': { + "data.q2.revision_seq": { color_type: redColumn, - accessorKey: 'data.q2.revision_seq', + accessorKey: "data.q2.revision_seq", }, - 'data.q2.revision_comment': { + "data.q2.revision_comment": { color_type: redColumn, - accessorKey: 'data.q2.revision_comment', + accessorKey: "data.q2.revision_comment", }, - 'data.q2.new_plan': { + "data.q2.new_plan": { color_type: yellowColumn, - accessorKey: 'data.q2.new_plan', + accessorKey: "data.q2.new_plan", }, - '2_kvartal_2026_field_field': { + "2_kvartal_2026_field_field": { color_type: whiteColumn, - accessorKey: '2_kvartal_2026_field_field', + accessorKey: "2_kvartal_2026_field_field", }, - 'data.q2.adj_current': { + "data.q2.adj_current": { color_type: yellowColumn, - accessorKey: 'data.q2.adj_current', + accessorKey: "data.q2.adj_current", }, - 'data.q2.adj_ssp': { + "data.q2.adj_ssp": { color_type: yellowColumn, - accessorKey: 'data.q2.adj_ssp', + accessorKey: "data.q2.adj_ssp", }, - 'data.q2.adj_rf': { + "data.q2.adj_rf": { color_type: yellowColumn, - accessorKey: 'data.q2.adj_rf', + accessorKey: "data.q2.adj_rf", }, - 'data.q2.adj_reserve': { + "data.q2.adj_reserve": { color_type: yellowColumn, - accessorKey: 'data.q2.adj_reserve', + accessorKey: "data.q2.adj_reserve", }, - 'data.q2.adj_comment': { + "data.q2.adj_comment": { color_type: yellowColumn, - accessorKey: 'data.q2.adj_comment', + accessorKey: "data.q2.adj_comment", }, - '2_kvartal_2026_perenos_v_3_kv_26_summa_tys_rub_bez_nds': { + "2_kvartal_2026_perenos_v_3_kv_26_summa_tys_rub_bez_nds": { color_type: redColumn, - accessorKey: '2_kvartal_2026_perenos_v_3_kv_26_summa_tys_rub_bez_nds', + accessorKey: "2_kvartal_2026_perenos_v_3_kv_26_summa_tys_rub_bez_nds", }, - 'data.q2.corrected_plan': { + "data.q2.corrected_plan": { color_type: yellowColumn, - accessorKey: 'data.q2.corrected_plan', + accessorKey: "data.q2.corrected_plan", }, - 'data.q2.pay_date': { + "data.q2.pay_date": { color_type: blueColumn, - accessorKey: 'data.q2.pay_date', + accessorKey: "data.q2.pay_date", }, - 'data.q2.pay_amount': { + "data.q2.pay_amount": { color_type: blueColumn, - accessorKey: 'data.q2.pay_amount', + accessorKey: "data.q2.pay_amount", }, - 'data.q2.pay_ho': { + "data.q2.pay_ho": { color_type: blueColumn, - accessorKey: 'data.q2.pay_ho', + accessorKey: "data.q2.pay_ho", }, - 'data.q2.pay_rf': { + "data.q2.pay_rf": { color_type: blueColumn, - accessorKey: 'data.q2.pay_rf', + accessorKey: "data.q2.pay_rf", }, - 'data.q2.pay_comment': { + "data.q2.pay_comment": { color_type: blueColumn, - accessorKey: 'data.q2.pay_comment', + accessorKey: "data.q2.pay_comment", }, - 'data.q2.pay_act': { + "data.q2.pay_act": { color_type: blueColumn, - accessorKey: 'data.q2.pay_act', + accessorKey: "data.q2.pay_act", }, - 'data.q2.booking': { + "data.q2.booking": { color_type: orangeColumn, - accessorKey: 'data.q2.booking', + accessorKey: "data.q2.booking", }, - 'data.q2.actual_m1': { + "data.q2.actual_m1": { color_type: greenColumn, - accessorKey: 'data.q2.actual_m1', + accessorKey: "data.q2.actual_m1", }, - 'data.q2.actual_m2': { + "data.q2.actual_m2": { color_type: greenColumn, - accessorKey: 'data.q2.actual_m2', + accessorKey: "data.q2.actual_m2", }, - 'data.q2.actual_m3': { + "data.q2.actual_m3": { color_type: greenColumn, - accessorKey: 'data.q2.actual_m3', + accessorKey: "data.q2.actual_m3", }, - 'data.q2.actual_quarter': { + "data.q2.actual_quarter": { color_type: greenColumn, - accessorKey: 'data.q2.actual_quarter', + accessorKey: "data.q2.actual_quarter", }, - 'data.q2.residual_after_booking': { + "data.q2.residual_after_booking": { color_type: orangeColumn, - accessorKey: 'data.q2.residual_after_booking', + accessorKey: "data.q2.residual_after_booking", }, - 'data.q2.residual_after_actual': { + "data.q2.residual_after_actual": { color_type: greenColumn, - accessorKey: 'data.q2.residual_after_actual', + accessorKey: "data.q2.residual_after_actual", }, - 'data.q2.transfer_q3': { + "data.q2.transfer_q3": { color_type: redColumn, - accessorKey: 'data.q2.transfer_q3', + accessorKey: "data.q2.transfer_q3", }, - 'data.q2.transfer_q4': { + "data.q2.transfer_q4": { color_type: redColumn, - accessorKey: 'data.q2.transfer_q4', + accessorKey: "data.q2.transfer_q4", }, - 'data.q2.transfer_econ': { + "data.q2.transfer_econ": { color_type: redColumn, - accessorKey: 'data.q2.transfer_econ', + accessorKey: "data.q2.transfer_econ", }, - 'data.q2.total': { + "data.q2.total": { color_type: redColumn, - accessorKey: 'data.q2.total', + accessorKey: "data.q2.total", }, - 'data.q3.target_change': { + "data.q3.target_change": { color_type: redColumn, - accessorKey: 'data.q3.target_change', + accessorKey: "data.q3.target_change", }, - 'data.q3.base_correction': { + "data.q3.base_correction": { color_type: redColumn, - accessorKey: 'data.q3.base_correction', + accessorKey: "data.q3.base_correction", }, - 'data.q3.revision_inc': { + "data.q3.revision_inc": { color_type: redColumn, - accessorKey: 'data.q3.revision_inc', + accessorKey: "data.q3.revision_inc", }, - 'data.q3.revision_seq': { + "data.q3.revision_seq": { color_type: redColumn, - accessorKey: 'data.q3.revision_seq', + accessorKey: "data.q3.revision_seq", }, - 'data.q3.revision_comment': { + "data.q3.revision_comment": { color_type: redColumn, - accessorKey: 'data.q3.revision_comment', + accessorKey: "data.q3.revision_comment", }, - 'data.q3.new_plan': { + "data.q3.new_plan": { color_type: yellowColumn, - accessorKey: 'data.q3.new_plan', + accessorKey: "data.q3.new_plan", }, - '3_kvartal_2026_field_field': { + "3_kvartal_2026_field_field": { color_type: whiteColumn, - accessorKey: '3_kvartal_2026_field_field', + accessorKey: "3_kvartal_2026_field_field", }, - 'data.q3.adj_current': { + "data.q3.adj_current": { color_type: yellowColumn, - accessorKey: 'data.q3.adj_current', + accessorKey: "data.q3.adj_current", }, - 'data.q3.adj_ssp': { + "data.q3.adj_ssp": { color_type: yellowColumn, - accessorKey: 'data.q3.adj_ssp', + accessorKey: "data.q3.adj_ssp", }, - 'data.q3.adj_rf': { + "data.q3.adj_rf": { color_type: yellowColumn, - accessorKey: 'data.q3.adj_rf', + accessorKey: "data.q3.adj_rf", }, - 'data.q3.adj_reserve': { + "data.q3.adj_reserve": { color_type: yellowColumn, - accessorKey: 'data.q3.adj_reserve', + accessorKey: "data.q3.adj_reserve", }, - 'data.q3.adj_comment': { + "data.q3.adj_comment": { color_type: yellowColumn, - accessorKey: 'data.q3.adj_comment', + accessorKey: "data.q3.adj_comment", }, - '3_kvartal_2026_perenos_v_4_kv_26_summa_tys_rub_bez_nds': { + "3_kvartal_2026_perenos_v_4_kv_26_summa_tys_rub_bez_nds": { color_type: redColumn, - accessorKey: '3_kvartal_2026_perenos_v_4_kv_26_summa_tys_rub_bez_nds', + accessorKey: "3_kvartal_2026_perenos_v_4_kv_26_summa_tys_rub_bez_nds", }, - 'data.q3.corrected_plan': { + "data.q3.corrected_plan": { color_type: yellowColumn, - accessorKey: 'data.q3.corrected_plan', + accessorKey: "data.q3.corrected_plan", }, - 'data.q3.pay_date': { + "data.q3.pay_date": { color_type: blueColumn, - accessorKey: 'data.q3.pay_date', + accessorKey: "data.q3.pay_date", }, - 'data.q3.pay_amount': { + "data.q3.pay_amount": { color_type: blueColumn, - accessorKey: 'data.q3.pay_amount', + accessorKey: "data.q3.pay_amount", }, - 'data.q3.pay_ho': { + "data.q3.pay_ho": { color_type: blueColumn, - accessorKey: 'data.q3.pay_ho', + accessorKey: "data.q3.pay_ho", }, - 'data.q3.pay_rf': { + "data.q3.pay_rf": { color_type: blueColumn, - accessorKey: 'data.q3.pay_rf', + accessorKey: "data.q3.pay_rf", }, - 'data.q3.pay_comment': { + "data.q3.pay_comment": { color_type: blueColumn, - accessorKey: 'data.q3.pay_comment', + accessorKey: "data.q3.pay_comment", }, - 'data.q3.pay_act': { + "data.q3.pay_act": { color_type: blueColumn, - accessorKey: 'data.q3.pay_act', + accessorKey: "data.q3.pay_act", }, - 'data.q3.booking': { + "data.q3.booking": { color_type: orangeColumn, - accessorKey: 'data.q3.booking', + accessorKey: "data.q3.booking", }, - 'data.q3.actual_m1': { + "data.q3.actual_m1": { color_type: greenColumn, - accessorKey: 'data.q3.actual_m1', + accessorKey: "data.q3.actual_m1", }, - 'data.q3.actual_m2': { + "data.q3.actual_m2": { color_type: greenColumn, - accessorKey: 'data.q3.actual_m2', + accessorKey: "data.q3.actual_m2", }, - 'data.q3.actual_m3': { + "data.q3.actual_m3": { color_type: greenColumn, - accessorKey: 'data.q3.actual_m3', + accessorKey: "data.q3.actual_m3", }, - 'data.q3.actual_quarter': { + "data.q3.actual_quarter": { color_type: greenColumn, - accessorKey: 'data.q3.actual_quarter', + accessorKey: "data.q3.actual_quarter", }, - 'data.q3.residual_after_booking': { + "data.q3.residual_after_booking": { color_type: orangeColumn, - accessorKey: 'data.q3.residual_after_booking', + accessorKey: "data.q3.residual_after_booking", }, - 'data.q3.residual_after_actual': { + "data.q3.residual_after_actual": { color_type: greenColumn, - accessorKey: 'data.q3.residual_after_actual', + accessorKey: "data.q3.residual_after_actual", }, - 'data.q3.transfer_q4': { + "data.q3.transfer_q4": { color_type: redColumn, - accessorKey: 'data.q3.transfer_q4', + accessorKey: "data.q3.transfer_q4", }, - 'data.q3.transfer_econ': { + "data.q3.transfer_econ": { color_type: redColumn, - accessorKey: 'data.q3.transfer_econ', + accessorKey: "data.q3.transfer_econ", }, - 'data.q3.total': { + "data.q3.total": { color_type: redColumn, - accessorKey: 'data.q3.total', + accessorKey: "data.q3.total", }, - 'data.q4.target_change': { + "data.q4.target_change": { color_type: redColumn, - accessorKey: 'data.q4.target_change', + accessorKey: "data.q4.target_change", }, - 'data.q4.base_correction': { + "data.q4.base_correction": { color_type: redColumn, - accessorKey: 'data.q4.base_correction', + accessorKey: "data.q4.base_correction", }, - 'data.q4.revision_inc': { + "data.q4.revision_inc": { color_type: redColumn, - accessorKey: 'data.q4.revision_inc', + accessorKey: "data.q4.revision_inc", }, - 'data.q4.revision_seq': { + "data.q4.revision_seq": { color_type: redColumn, - accessorKey: 'data.q4.revision_seq', + accessorKey: "data.q4.revision_seq", }, - 'data.q4.revision_comment': { + "data.q4.revision_comment": { color_type: redColumn, - accessorKey: 'data.q4.revision_comment', + accessorKey: "data.q4.revision_comment", }, - 'data.q4.adj_comment': { + "data.q4.adj_comment": { color_type: yellowColumn, - accessorKey: 'data.q4.adj_comment', + accessorKey: "data.q4.adj_comment", }, - 'data.q4.new_plan': { + "data.q4.new_plan": { color_type: yellowColumn, - accessorKey: 'data.q4.new_plan', + accessorKey: "data.q4.new_plan", }, - '4_kvartal_2026_field_field': { + "4_kvartal_2026_field_field": { color_type: whiteColumn, - accessorKey: '4_kvartal_2026_field_field', + accessorKey: "4_kvartal_2026_field_field", }, - 'data.q4.adj_current': { + "data.q4.adj_current": { color_type: yellowColumn, - accessorKey: 'data.q4.adj_current', + accessorKey: "data.q4.adj_current", }, - 'data.q4.adj_ssp': { + "data.q4.adj_ssp": { color_type: yellowColumn, - accessorKey: 'data.q4.adj_ssp', + accessorKey: "data.q4.adj_ssp", }, - 'data.q4.adj_rf': { + "data.q4.adj_rf": { color_type: yellowColumn, - accessorKey: 'data.q4.adj_rf', + accessorKey: "data.q4.adj_rf", }, - 'data.q4.adj_reserve': { + "data.q4.adj_reserve": { color_type: yellowColumn, - accessorKey: 'data.q4.adj_reserve', + accessorKey: "data.q4.adj_reserve", }, - 'data.q4.corrected_plan': { + "data.q4.corrected_plan": { color_type: yellowColumn, - accessorKey: 'data.q4.corrected_plan', + accessorKey: "data.q4.corrected_plan", }, - 'data.q4.pay_date': { + "data.q4.pay_date": { color_type: blueColumn, - accessorKey: 'data.q4.pay_date', + accessorKey: "data.q4.pay_date", }, - 'data.q4.pay_amount': { + "data.q4.pay_amount": { color_type: blueColumn, - accessorKey: 'data.q4.pay_amount', + accessorKey: "data.q4.pay_amount", }, - 'data.q4.pay_ho': { + "data.q4.pay_ho": { color_type: blueColumn, - accessorKey: 'data.q4.pay_ho', + accessorKey: "data.q4.pay_ho", }, - 'data.q4.pay_rf': { + "data.q4.pay_rf": { color_type: blueColumn, - accessorKey: 'data.q4.pay_rf', + accessorKey: "data.q4.pay_rf", }, - 'data.q4.pay_comment': { + "data.q4.pay_comment": { color_type: blueColumn, - accessorKey: 'data.q4.pay_comment', + accessorKey: "data.q4.pay_comment", }, - 'data.q4.pay_act': { + "data.q4.pay_act": { color_type: blueColumn, - accessorKey: 'data.q4.pay_act', + accessorKey: "data.q4.pay_act", }, - 'data.q4.booking': { + "data.q4.booking": { color_type: orangeColumn, - accessorKey: 'data.q4.booking', + accessorKey: "data.q4.booking", }, - 'data.q4.actual_m1': { + "data.q4.actual_m1": { color_type: greenColumn, - accessorKey: 'data.q4.actual_m1', + accessorKey: "data.q4.actual_m1", }, - 'data.q4.actual_m2': { + "data.q4.actual_m2": { color_type: greenColumn, - accessorKey: 'data.q4.actual_m2', + accessorKey: "data.q4.actual_m2", }, - 'data.q4.actual_m3': { + "data.q4.actual_m3": { color_type: greenColumn, - accessorKey: 'data.q4.actual_m3', + accessorKey: "data.q4.actual_m3", }, - 'data.q4.actual_quarter': { + "data.q4.actual_quarter": { color_type: greenColumn, - accessorKey: 'data.q4.actual_quarter', + accessorKey: "data.q4.actual_quarter", }, - 'data.q4.actual_spod': { + "data.q4.actual_spod": { color_type: greenColumn, - accessorKey: 'data.q4.actual_spod', + accessorKey: "data.q4.actual_spod", }, - 'data.q4.residual_after_booking': { + "data.q4.residual_after_booking": { color_type: orangeColumn, - accessorKey: 'data.q4.residual_after_booking', + accessorKey: "data.q4.residual_after_booking", }, - 'data.q4.residual_after_actual': { + "data.q4.residual_after_actual": { color_type: greenColumn, - accessorKey: 'data.q4.residual_after_actual', + accessorKey: "data.q4.residual_after_actual", }, - '4_kvartal_2026_zakrytie_4_go_kvartala_field': { + "4_kvartal_2026_zakrytie_4_go_kvartala_field": { color_type: redColumn, - accessorKey: '4_kvartal_2026_zakrytie_4_go_kvartala_field', + accessorKey: "4_kvartal_2026_zakrytie_4_go_kvartala_field", }, - 'data.q4.transfer_econ': { + "data.q4.transfer_econ": { color_type: redColumn, - accessorKey: 'data.q4.transfer_econ', + accessorKey: "data.q4.transfer_econ", }, - 'data.q4.total': { + "data.q4.total": { color_type: redColumn, - accessorKey: 'data.q4.total', + accessorKey: "data.q4.total", }, - 'data.totals.fact_year': { + "data.totals.fact_year": { color_type: greenColumn, - accessorKey: 'data.totals.fact_year', + accessorKey: "data.totals.fact_year", }, - 'data.totals.pay_year': { + "data.totals.pay_year": { color_type: blueColumn, - accessorKey: 'data.totals.pay_year', + accessorKey: "data.totals.pay_year", }, field_field_field_3: { color_type: whiteColumn, - accessorKey: 'field_field_field_3', + accessorKey: "field_field_field_3", }, field_summa_oplaty_field: { color_type: blueColumn, - accessorKey: 'field_summa_oplaty_field', + accessorKey: "field_summa_oplaty_field", }, }, columns: [ @@ -2602,21 +2602,21 @@ export const config = { }, { - header: 'Комментарий', - accessorKey: '2_kvartal_2026_kommentariy_adj', + header: "Комментарий", + accessorKey: "2_kvartal_2026_kommentariy_adj", columns: [ { - header: 'Сумма (без НДС)', - accessorKey: 'data.q2.adj_comment', - columnLetter: 'DP', + header: "Сумма (без НДС)", + accessorKey: "data.q2.adj_comment", + columnLetter: "DP", size: 150, - filterFn: 'contains', + filterFn: "contains", }, ], muiTableHeadCellProps: { sx: { - backgroundColor: '#FFFF99', - color: '#000000', + backgroundColor: "#FFFF99", + color: "#000000", }, }, }, @@ -3151,21 +3151,21 @@ export const config = { }, { - header: 'Комментарий', - accessorKey: '3_kvartal_2026_kommentariy_adj', + header: "Комментарий", + accessorKey: "3_kvartal_2026_kommentariy_adj", columns: [ { - header: 'Сумма (без НДС)', - accessorKey: 'data.q3.adj_comment', - columnLetter: 'EY', + header: "Сумма (без НДС)", + accessorKey: "data.q3.adj_comment", + columnLetter: "EY", size: 150, - filterFn: 'contains', + filterFn: "contains", }, ], muiTableHeadCellProps: { sx: { - backgroundColor: '#FFFF99', - color: '#000000', + backgroundColor: "#FFFF99", + color: "#000000", }, }, }, @@ -4022,15 +4022,21 @@ export const config = { accessorKey: "field_40", columns: [ { - header: "Факт {year:short}", + header: " ", accessorKey: "field_fakt_26", columns: [ { - header: "", + header: "Факт {year:short}", accessorKey: "data.totals.fact_year", columnLetter: "HE", size: 150, filterFn: "contains", + muiTableHeadCellProps: { + sx: { + backgroundColor: "#C2D69B", + color: "#000000", + }, + }, }, { header: "Сумма оплаты", @@ -4046,18 +4052,12 @@ export const config = { }, }, ], - muiTableHeadCellProps: { - sx: { - backgroundColor: "#C2D69B", - color: "#000000", - }, - }, }, ], muiTableHeadCellProps: { sx: { backgroundColor: "#FFFFFF", - color: "#000000" , + color: "#000000", }, }, }, diff --git a/web/src/components/RealtimeTable/hooks/useRealtimeData.js b/web/src/components/RealtimeTable/hooks/useRealtimeData.js index 04816b9..df45906 100644 --- a/web/src/components/RealtimeTable/hooks/useRealtimeData.js +++ b/web/src/components/RealtimeTable/hooks/useRealtimeData.js @@ -4,43 +4,7 @@ import { FormsSheetApi } from '../../../api/form_sheet'; import { ProjectsApi } from '../../../api/projects'; import { useRealtimeActions, useRealtimeConnection } from '../contexts/RealtimeContext'; import { addRootRow, deleteRow, insertCell, insertProjectRow, updateCells } from '../utils/cellUtils'; -import { getParentId, isVspNewRow } from '../utils/rowUtils'; - -const ROW_TYPE_LEVELS = { - ROOT: 0, - GROUP: 1, - ITEM: 2, - SUB_ITEM: 3, - INPUT: 4, -}; - -const buildHierarchy = (items) => { - const result = []; - const stack = []; - - for (const item of items) { - const currentLevel = ROW_TYPE_LEVELS[item.row_type] ?? 999; - - while (stack.length > 0 && (ROW_TYPE_LEVELS[stack.at(-1).row_type] ?? 999) >= currentLevel) { - stack.pop(); - } - - const parent = stack.at(-1); - const newNode = { ...item, subRows: [] }; - - if (parent) { - parent.subRows.push(newNode); - } else { - result.push(newNode); - } - - if (item.row_type !== 'INPUT') { - stack.push(newNode); - } - } - - return result; -}; +import { buildRowHierarchy, getParentId, isVspNewRow } from '../utils/rowUtils'; const useRealtimeData = (formId, sheetName, direction, formType, year) => { const [data, setData] = useState([]); @@ -91,7 +55,7 @@ const useRealtimeData = (formId, sheetName, direction, formType, year) => { return; } - const hierarchicalData = buildHierarchy(data); + const hierarchicalData = buildRowHierarchy(data); setData(hierarchicalData); } catch (err) { if (!isCancelled) console.error('Failed to load initial data:', err); diff --git a/web/src/components/RealtimeTable/utils/rowUtils.js b/web/src/components/RealtimeTable/utils/rowUtils.js index fb4e323..af5efcb 100644 --- a/web/src/components/RealtimeTable/utils/rowUtils.js +++ b/web/src/components/RealtimeTable/utils/rowUtils.js @@ -1,3 +1,34 @@ +const ROW_TYPE_LEVELS = { + ROOT: 0, + GROUP: 1, + ITEM: 2, + SUB_ITEM: 3, + INPUT: 4, +}; + +export function buildRowHierarchy(items, mapItem = (item) => item) { + const result = []; + const stack = []; + + for (const [index, item] of items.entries()) { + const currentLevel = ROW_TYPE_LEVELS[item.row_type] ?? 999; + + while (stack.length > 0 && (ROW_TYPE_LEVELS[stack.at(-1).row_type] ?? 999) >= currentLevel) { + stack.pop(); + } + + const parent = stack.at(-1); + const newNode = { ...mapItem(item, index), subRows: [] }; + + if (parent) parent.subRows.push(newNode); + else result.push(newNode); + + if (item.row_type !== 'INPUT') stack.push(newNode); + } + + return result; +} + export function getDataRowId(data) { return data?.id || data?.line_id; } diff --git a/web/src/components/RealtimeTable/utils/rowUtils.test.js b/web/src/components/RealtimeTable/utils/rowUtils.test.js new file mode 100644 index 0000000..0c40434 --- /dev/null +++ b/web/src/components/RealtimeTable/utils/rowUtils.test.js @@ -0,0 +1,21 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { buildRowHierarchy } from './rowUtils.js'; + +test('row hierarchy uses row types when depth skips a level and keeps INPUT rows as siblings', () => { + const rows = [ + { row_type: 'ROOT', depth: 0, id: 'root' }, + { row_type: 'ITEM', depth: 2, id: 'item-1' }, + { row_type: 'INPUT', depth: 4, id: 'input-1' }, + { row_type: 'INPUT', depth: 4, id: 'input-2' }, + { row_type: 'ITEM', depth: 2, id: 'item-2' }, + { row_type: 'ROOT', depth: 0, id: 'next-root' }, + ]; + + const tree = buildRowHierarchy(rows); + + assert.deepEqual(tree.map(({ id }) => id), ['root', 'next-root']); + assert.deepEqual(tree[0].subRows.map(({ id }) => id), ['item-1', 'item-2']); + assert.deepEqual(tree[0].subRows[0].subRows.map(({ id }) => id), ['input-1', 'input-2']); + assert.deepEqual(tree[0].subRows[0].subRows[0].subRows, []); +}); diff --git a/web/src/pages/ProjectPages/ProjectSummariesPage.jsx b/web/src/pages/ProjectPages/ProjectSummariesPage.jsx index 7812438..6c2ffee 100644 --- a/web/src/pages/ProjectPages/ProjectSummariesPage.jsx +++ b/web/src/pages/ProjectPages/ProjectSummariesPage.jsx @@ -224,7 +224,7 @@ export default function ProjectSummariesPage() { - setSheet(value)} sx={{ px: '0.5rem', minHeight: '3rem', borderBottom: '0.0625rem solid #edf0f2' }}> + setSheet(value)} sx={{ px: '1rem', minHeight: '3rem', borderBottom: '0.0625rem solid #edf0f2' }}> {SHEETS.map(({ value, label }) => )} Повторить}>{error} ) : ( - + )} ); diff --git a/web/src/pages/Svod2Page/Svod2Page.jsx b/web/src/pages/Svod2Page/Svod2Page.jsx index 99a1f8a..c359714 100644 --- a/web/src/pages/Svod2Page/Svod2Page.jsx +++ b/web/src/pages/Svod2Page/Svod2Page.jsx @@ -3,6 +3,7 @@ import { Alert, Box, Button, Paper, Tab, Tabs, Typography } from '@mui/material' import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'; import { MRT_Localization_RU } from 'material-react-table/locales/ru'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import { HeaderSwitch } from '../../components/HeaderMenu/HeaderSwitch'; import { PrimaryButton } from '../../components/common/Buttons/Buttons'; @@ -355,6 +356,7 @@ const matchesSearch = (row, query) => { }; export default function Svod2Page() { + const navigate = useNavigate(); const { getSheetFilters, updateSheetFilters, getSummary, invalidateSummary } = useSvod(); const [sheet, setSheet] = useState('GO'); const [tableStateBySheet, setTableStateBySheet] = useState(createInitialTableState); @@ -436,6 +438,11 @@ export default function Svod2Page() { invalidateSummary(sheet, year, selectedOrganizationIds); loadSummary(); }, [invalidateSummary, loadSummary, selectedOrganizationIds, sheet, year]); + const openFilteredTasks = useCallback(() => { + const params = new URLSearchParams({ year: String(year), form_type: 'FORM_2' }); + if (selectedOrganizationIds.length) params.set('org_units', selectedOrganizationIds.join(',')); + navigate(`/tasks?${params.toString()}`); + }, [navigate, selectedOrganizationIds, year]); const filteredRows = useMemo(() => { if (!hasCurrentData) return []; @@ -571,9 +578,9 @@ export default function Svod2Page() { setSheet(value)} - sx={{ px: '0.5rem', minHeight: '3rem', borderBottom: '0.0625rem solid #edf0f2' }}> + sx={{ px: '1rem', minHeight: '3rem', borderBottom: '0.0625rem solid #edf0f2' }}> {SHEETS.map((item) => ( - + ))} )} + + Перейти к задачам + {hasCurrentData ? ( ) : ( @@ -605,7 +615,7 @@ export default function Svod2Page() { color='default' disabled={loading || selectedOrganizations.length === 0} onClick={refreshSummary} - sx={{ ml: 'auto', height: '2.5rem', flexShrink: 0 }}> + sx={{ height: '2.5rem', flexShrink: 0 }}> Загрузить )} diff --git a/web/src/pages/SvodPage/SummaryTable.jsx b/web/src/pages/SvodPage/SummaryTable.jsx index a88c357..3d048d4 100644 --- a/web/src/pages/SvodPage/SummaryTable.jsx +++ b/web/src/pages/SvodPage/SummaryTable.jsx @@ -1,7 +1,8 @@ import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'; import { memo } from 'react'; -import { blueColumn } from '../../components/RealtimeTable/constants/columnColors'; +import { blueColumn, greenColumn, orangeColumn } from '../../components/RealtimeTable/constants/columnColors'; import { sectionCodeColor } from '../../components/RealtimeTable/constants/columnConfig'; +import { buildRowHierarchy } from '../../components/RealtimeTable/utils/rowUtils'; const tableSize = (rem) => rem * 16; const ROW_VIRTUALIZER_OPTIONS = { @@ -10,8 +11,14 @@ const ROW_VIRTUALIZER_OPTIONS = { measureElement: (element) => element?.offsetHeight || 37, }; -const getSummaryRowColor = (row) => { +const SOURCE_COLORS = { ahr: greenColumn, oper: blueColumn, cap: orangeColumn }; + +const getSummaryRowColor = (row, colorBySource) => { const rowType = row.original?.row_type || row.row_type; + if (colorBySource) { + const source = row.original?.data?.header?.source?.toLowerCase(); + if (SOURCE_COLORS[source]) return SOURCE_COLORS[source][rowType]; + } const sectionCodeValue = row.original?.data?.section_code ?? row.original?.data?.header?.section_code; if (sectionCodeValue === null || sectionCodeValue === undefined || sectionCodeValue === '') return undefined; const sectionCode = String(sectionCodeValue)[0]; @@ -26,27 +33,11 @@ const getTextColor = (backgroundColor) => { return 0.299 * red + 0.587 * green + 0.114 * blue < 128 ? '#fff' : '#000'; }; -export const buildSummaryTree = (sourceRows) => { - const roots = []; - const parents = []; - - for (const [index, sourceRow] of sourceRows.entries()) { - const row = { - ...sourceRow, - _rowId: `${sourceRow.sort_order ?? index}-${sourceRow.data?.section_code ?? sourceRow.data?.header?.section_code ?? index}`, - subRows: [], - }; - - while (parents.length > row.depth) parents.pop(); - if (row.depth > 0 && parents[row.depth - 1]) parents[row.depth - 1].subRows.push(row); - else roots.push(row); - - parents[row.depth] = row; - parents.length = row.depth + 1; - } - - return roots; -}; +export const buildSummaryTree = (sourceRows) => + buildRowHierarchy(sourceRows, (row, index) => ({ + ...row, + _rowId: `${row.sort_order ?? index}-${row.data?.section_code ?? row.data?.header?.section_code ?? index}`, + })); export const filterSummaryTree = (tree, query) => tree.flatMap((row) => { @@ -64,7 +55,7 @@ export const filterSummaryTree = (tree, query) => export const countSummaryTree = (tree) => tree.reduce((count, row) => count + 1 + countSummaryTree(row.subRows), 0); -export const SummaryTable = memo(function SummaryTable({ columns, data, loading }) { +export const SummaryTable = memo(function SummaryTable({ columns, data, loading, colorBySource = false }) { const table = useMaterialReactTable({ columns, data, @@ -141,7 +132,7 @@ export const SummaryTable = memo(function SummaryTable({ columns, data, loading }, }, muiTableBodyCellProps: ({ row, column }) => { - const backgroundColor = getSummaryRowColor(row); + const backgroundColor = getSummaryRowColor(row, colorBySource); return { sx: { backgroundColor, diff --git a/web/src/pages/SvodPage/SvodPage.jsx b/web/src/pages/SvodPage/SvodPage.jsx index e98cbd0..e323eec 100644 --- a/web/src/pages/SvodPage/SvodPage.jsx +++ b/web/src/pages/SvodPage/SvodPage.jsx @@ -259,9 +259,9 @@ export default function SvodPage() { onChange={(_event, value) => setSheet(value)} variant='scrollable' scrollButtons='auto' - sx={{ px: '0.5rem', minHeight: '3rem', borderBottom: '0.0625rem solid #edf0f2' }}> + sx={{ px: '1rem', minHeight: '3rem', borderBottom: '0.0625rem solid #edf0f2' }}> {SHEETS.map((item) => ( - + ))}