diff --git a/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx b/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx
index 472c89c..ffb644f 100644
--- a/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx
+++ b/web/src/components/RealtimeTable/Cell/Cell/Cell.jsx
@@ -1,214 +1,228 @@
-import React, { memo, useMemo, useCallback } from 'react';
+import React, { useMemo, useCallback } from 'react';
import { useRealtime } from '../../contexts/RealtimeContext';
// Константы вне компонента
const BASE_CELL_STYLES = {
- width: '100%',
- height: '100%',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- boxSizing: 'border-box',
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
- border: '2px solid transparent',
- padding: '8px',
+ width: '100%',
+ height: '100%',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ boxSizing: 'border-box',
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ border: '2px solid transparent',
+ padding: '8px',
};
const LOCKED_STYLES = {
- border: '2px solid #e0e0e0',
- backgroundColor: '#f5f5f5',
- cursor: 'not-allowed',
- opacity: 0.85,
+ border: '2px solid #e0e0e0',
+ backgroundColor: '#f5f5f5',
+ cursor: 'not-allowed',
+ opacity: 0.85,
};
const INVALID_STYLES = {
- border: '2px solid #D32F2F',
- backgroundColor: '#FDEDED',
- color: '#C60C0C',
+ border: '2px solid #D32F2F',
+ backgroundColor: '#FDEDED',
+ color: '#C60C0C',
};
const LOCK_BADGE_STYLES = {
- position: 'absolute',
- top: '2px',
- right: '2px',
- background: 'rgba(0, 0, 0, 0.7)',
- color: 'white',
- fontSize: '9px',
- padding: '1px 4px',
- borderRadius: '3px',
- pointerEvents: 'none',
- zIndex: 10,
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
- letterSpacing: '0.3px',
- backdropFilter: 'blur(4px)',
- border: '1px solid rgba(255, 255, 255, 0.1)',
+ position: 'absolute',
+ top: '2px',
+ right: '2px',
+ background: 'rgba(0, 0, 0, 0.7)',
+ color: 'white',
+ fontSize: '9px',
+ padding: '1px 4px',
+ borderRadius: '3px',
+ pointerEvents: 'none',
+ zIndex: 10,
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
+ letterSpacing: '0.3px',
+ backdropFilter: 'blur(4px)',
+ border: '1px solid rgba(255, 255, 255, 0.1)',
};
const CONTAINER_STYLES = {
- display: '-webkit-box',
- WebkitBoxOrient: 'vertical',
- WebkitLineClamp: 3,
- overflow: 'hidden',
- whiteSpace: 'pre-wrap',
- wordBreak: 'break-word',
+ display: '-webkit-box',
+ WebkitBoxOrient: 'vertical',
+ WebkitLineClamp: 3,
+ overflow: 'hidden',
+ whiteSpace: 'pre-wrap',
+ wordBreak: 'break-word',
};
const INTEGER_COLUMN_IDS = new Set([
- 'data.header.num_group',
- 'data.nomenclature_group_id',
- 'data.header.item_id',
- 'data.article_id',
- 'data.code_razdela',
+ 'data.header.num_group',
+ 'data.nomenclature_group_id',
+ 'data.header.item_id',
+ 'data.article_id',
+ 'data.code_razdela',
]);
const getColorBrightness = (hexColor) => {
- if (!hexColor) return 255;
- const color = hexColor.replace('#', '');
- let r, g, b;
- if (color.length === 3) {
- r = parseInt(color[0] + color[0], 16);
- g = parseInt(color[1] + color[1], 16);
- b = parseInt(color[2] + color[2], 16);
- } else if (color.length === 6) {
- r = parseInt(color.substring(0, 2), 16);
- g = parseInt(color.substring(2, 4), 16);
- b = parseInt(color.substring(4, 6), 16);
- } else {
- return 255;
- }
- return (0.299 * r + 0.587 * g + 0.114 * b);
+ if (!hexColor) return 255;
+ const color = hexColor.replace('#', '');
+ let r;
+ let g;
+ let b;
+ if (color.length === 3) {
+ r = Number.parseInt(color[0] + color[0], 16);
+ g = Number.parseInt(color[1] + color[1], 16);
+ b = Number.parseInt(color[2] + color[2], 16);
+ } else if (color.length === 6) {
+ r = Number.parseInt(color.substring(0, 2), 16);
+ g = Number.parseInt(color.substring(2, 4), 16);
+ b = Number.parseInt(color.substring(4, 6), 16);
+ } else {
+ return 255;
+ }
+ return 0.299 * r + 0.587 * g + 0.114 * b;
};
const formatNumber = (value, asInteger = false) => {
- if (value === null || value === undefined || value === '') return String(value || '');
- const num = Number(value);
- if (isNaN(num)) return String(value);
- return num.toLocaleString('ru-RU', {
- minimumFractionDigits: asInteger ? 0 : 1,
- maximumFractionDigits: asInteger ? 0 : 1,
- useGrouping: true,
- });
+ if (value === null || value === undefined || value === '') return String(value || '');
+ const num = Number(value);
+ if (Number.isNaN(num)) return String(value);
+ return num.toLocaleString('ru-RU', {
+ minimumFractionDigits: asInteger ? 0 : 1,
+ maximumFractionDigits: asInteger ? 0 : 1,
+ useGrouping: true,
+ });
};
// Оптимизированная функция подсветки
const createHighlightedContent = (originalValue, displayValue, searchQueries) => {
- const cleanQueries = searchQueries.filter(Boolean);
- if (cleanQueries.length === 0) return displayValue;
+ const cleanQueries = searchQueries.filter(Boolean);
+ if (cleanQueries.length === 0) return displayValue;
- const searchStr = String(originalValue ?? displayValue);
- const escapedQueries = cleanQueries.map(q => q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
- const regex = new RegExp(`(${escapedQueries.join('|')})`, 'gi');
+ const searchStr = String(originalValue ?? displayValue);
+ const escapedQueries = cleanQueries.map((q) => q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
+ const regex = new RegExp(`(${escapedQueries.join('|')})`, 'gi');
- if (!regex.test(searchStr)) return displayValue;
+ if (!regex.test(searchStr)) return displayValue;
- const parts = searchStr.split(regex);
- return parts.map((part, index) => {
- if (!regex.test(part)) return part;
- return React.createElement('mark', {
- key: index,
- style: {
- backgroundColor: '#ffeb3b',
- color: '#000',
- fontWeight: 'bold',
- padding: '0 2px',
- borderRadius: '2px',
- },
- }, part);
- });
+ const parts = searchStr.split(regex);
+ return parts.map((part, index) => {
+ if (!regex.test(part)) return part;
+ return React.createElement(
+ 'mark',
+ {
+ key: index,
+ style: {
+ backgroundColor: '#ffeb3b',
+ color: '#000',
+ fontWeight: 'bold',
+ padding: '0 2px',
+ borderRadius: '2px',
+ },
+ },
+ part,
+ );
+ });
};
const CellComponent = ({
- cell,
- row,
- column,
- onClick,
- globalFilter,
- columnFilter,
- backgroundColor,
- color,
- isEditable,
- isUpdating,
- onCellNumberClick,
- isInvalid,
+ cell,
+ row,
+ column,
+ onClick,
+ globalFilter,
+ columnFilter,
+ backgroundColor,
+ color,
+ isEditable,
+ isUpdating,
+ onCellNumberClick,
+ isInvalid,
+ vspOptions,
}) => {
- const { lockedCells } = useRealtime();
- const cellKey = `${row.id}_${column.id}`;
- const isLocked = lockedCells.includes(cellKey);
+ const { lockedCells } = useRealtime();
+ const cellKey = `${row.id}_${column.id}`;
+ const isLocked = lockedCells.includes(cellKey);
- // Мемоизация значения
- const { rawValue, displayValue, isNumeric } = useMemo(() => {
- const value = cell.getValue();
- const isNum = !isNaN(Number(value)) && value !== null && value !== undefined && value !== '';
- let display = String(value || '');
+ const isVspDropdown = column?.columnDef?.editType === 'vsp_dropdown';
- if (isNum) {
- const asInteger = INTEGER_COLUMN_IDS.has(column.id);
- display = formatNumber(value, asInteger);
- }
+ const { rawValue, displayValue, isNumeric } = useMemo(() => {
+ const value = cell.getValue();
+ const isNum = !Number.isNaN(Number(value)) && value !== null && value !== undefined && value !== '';
+ let display = String(value || '');
- return { rawValue: value, displayValue: display, isNumeric: isNum };
- }, [cell, column.id]);
+ if (isVspDropdown && value != null) {
+ const vsp = vspOptions?.find((v) => v.id === Number(value));
+ if (vsp) {
+ return { rawValue: value, displayValue: vsp.registration_number, isNumeric: false };
+ }
+ }
- const highlightedContent = useMemo(() => {
- const searchQueries = [globalFilter, columnFilter];
- return createHighlightedContent(rawValue, displayValue, searchQueries);
- }, [rawValue, displayValue, globalFilter, columnFilter]);
+ if (isNum) {
+ const asInteger = INTEGER_COLUMN_IDS.has(column.id);
+ display = formatNumber(value, asInteger);
+ }
- const textColor = useMemo(() => {
- if (isLocked) return '#999999';
- const brightness = getColorBrightness(backgroundColor);
- return brightness < 128 ? '#ffffff' : '#000000';
- }, [backgroundColor, isLocked]);
+ return { rawValue: value, displayValue: display, isNumeric: isNum };
+ }, [cell, column.id, isVspDropdown, vspOptions]);
- const cellStyles = useMemo(() => ({
- ...BASE_CELL_STYLES,
- backgroundColor: isLocked ? '#f5f5f5' : backgroundColor,
- color: textColor,
- ...(isLocked ? LOCKED_STYLES : {}),
- ...(isInvalid ? INVALID_STYLES : {}),
- }), [backgroundColor, isInvalid, isLocked, textColor]);
+ const highlightedContent = useMemo(() => {
+ const searchQueries = [globalFilter, columnFilter];
+ return createHighlightedContent(rawValue, displayValue, searchQueries);
+ }, [rawValue, displayValue, globalFilter, columnFilter]);
- const lockBadge = useMemo(() => {
- if (!isLocked) return null;
- return
🔒
;
- }, [isLocked]);
+ const textColor = useMemo(() => {
+ if (isLocked) return '#999999';
+ const brightness = getColorBrightness(backgroundColor);
+ return brightness < 128 ? '#ffffff' : '#000000';
+ }, [backgroundColor, isLocked]);
- const handleClick = useCallback(() => {
- if (!isLocked && onClick) {
- onClick();
- }
- }, [isLocked, onClick]);
+ const cellStyles = useMemo(
+ () => ({
+ ...BASE_CELL_STYLES,
+ backgroundColor: isLocked ? '#f5f5f5' : backgroundColor,
+ color: textColor,
+ ...(isLocked ? LOCKED_STYLES : {}),
+ ...(isInvalid ? INVALID_STYLES : {}),
+ }),
+ [backgroundColor, isInvalid, isLocked, textColor],
+ );
- return (
-
- {highlightedContent}
- {lockBadge}
-
- );
+ const lockBadge = useMemo(() => {
+ if (!isLocked) return null;
+ return 🔒
;
+ }, [isLocked]);
+
+ const handleClick = useCallback(() => {
+ if (!isLocked && onClick) {
+ onClick();
+ }
+ }, [isLocked, onClick]);
+
+ return (
+
+ {highlightedContent}
+ {lockBadge}
+
+ );
};
const Cell = React.memo(CellComponent, (prevProps, nextProps) => {
- // Возвращаем true если пропсы равны (не нужно перерендеривать)
- return (
- prevProps.cell.getValue() === nextProps.cell.getValue() &&
- prevProps.row.id === nextProps.row.id &&
- prevProps.column.id === nextProps.column.id &&
- prevProps.globalFilter === nextProps.globalFilter &&
- prevProps.columnFilter === nextProps.columnFilter &&
- prevProps.backgroundColor === nextProps.backgroundColor &&
- prevProps.isInvalid === nextProps.isInvalid &&
- prevProps.isEditable === nextProps.isEditable &&
- prevProps.isUpdating === nextProps.isUpdating &&
- prevProps.onCellNumberClick === nextProps.onCellNumberClick
- );
+ return (
+ prevProps.cell.getValue() === nextProps.cell.getValue() &&
+ prevProps.row.id === nextProps.row.id &&
+ prevProps.column.id === nextProps.column.id &&
+ prevProps.globalFilter === nextProps.globalFilter &&
+ prevProps.columnFilter === nextProps.columnFilter &&
+ prevProps.backgroundColor === nextProps.backgroundColor &&
+ prevProps.isInvalid === nextProps.isInvalid &&
+ prevProps.isEditable === nextProps.isEditable &&
+ prevProps.isUpdating === nextProps.isUpdating &&
+ prevProps.onCellNumberClick === nextProps.onCellNumberClick &&
+ prevProps.vspOptions === nextProps.vspOptions
+ );
});
-export default Cell;
\ No newline at end of file
+export default Cell;
diff --git a/web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx b/web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx
new file mode 100644
index 0000000..172c31d
--- /dev/null
+++ b/web/src/components/RealtimeTable/Cell/EditCell/VspDropdownEditCell.jsx
@@ -0,0 +1,121 @@
+import { FormControl, MenuItem, Select } from '@mui/material';
+import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
+import { useRealtime } from '../../contexts/RealtimeContext';
+
+const EDITOR_STYLES = {
+ position: 'absolute',
+ zIndex: 12,
+ top: 0,
+};
+
+const VspDropdownEditCell = memo(({ refCell, onChange, disabled, value, table }) => {
+ const { endEditing: contextEndEditing, vspOptions } = useRealtime();
+
+ const [selectedValue, setSelectedValue] = useState(() => value ?? '');
+ const [position, setPosition] = useState();
+ const [open, setOpen] = useState(false);
+
+ const refFinished = useRef(false);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setOpen(true);
+ }, 80);
+ return () => clearTimeout(timer);
+ }, []);
+
+ useLayoutEffect(() => {
+ if (!refCell?.current) return;
+
+ const td = refCell.current.offsetParent;
+ const tr = td?.offsetParent;
+
+ if (td && tr) {
+ setPosition({
+ left: td.offsetLeft,
+ width: td.offsetWidth,
+ translateY: tr.style.transform || '',
+ });
+ }
+ }, [refCell]);
+
+ const finishEditing = useCallback(() => {
+ if (refFinished.current) return;
+ refFinished.current = true;
+ table.setEditingCell(null);
+ const editingCell = table.getState().editingCell;
+ if (editingCell) {
+ contextEndEditing?.(editingCell.row, editingCell.column);
+ }
+ }, [table, contextEndEditing]);
+
+ const handleSelectChange = useCallback(
+ (e) => {
+ const val = e.target.value;
+ if (val == null || val === '') return;
+ refFinished.current = true;
+ setSelectedValue(val);
+ onChange?.(val);
+ const editingCell = table.getState().editingCell;
+ if (editingCell) {
+ contextEndEditing?.(editingCell.row, editingCell.column);
+ }
+ },
+ [onChange, table, contextEndEditing],
+ );
+
+ const handleSelectClose = useCallback(
+ (_event, reason) => {
+ if (reason === 'selectOption') return;
+ finishEditing();
+ },
+ [finishEditing],
+ );
+
+ const editorStyles = useMemo(
+ () => ({
+ ...EDITOR_STYLES,
+ left: position?.left || 0,
+ width: position?.width || 0,
+ transform: position?.translateY || 0,
+ }),
+ [position],
+ );
+
+ return (
+
+ |
+ {position && (
+
+
+
+
+
+ )}
+ |
+
+ );
+});
+
+VspDropdownEditCell.displayName = 'VspDropdownEditCell';
+
+export default VspDropdownEditCell;
diff --git a/web/src/components/RealtimeTable/RealtimeTable.jsx b/web/src/components/RealtimeTable/RealtimeTable.jsx
index 2711f3f..30d66f7 100644
--- a/web/src/components/RealtimeTable/RealtimeTable.jsx
+++ b/web/src/components/RealtimeTable/RealtimeTable.jsx
@@ -1,627 +1,642 @@
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
import React, { useState, useMemo, useRef, useEffect, useCallback, useTransition } from 'react';
import { createPortal } from 'react-dom';
-import {
- useMaterialReactTable,
- MaterialReactTable,
-} from 'material-react-table';
-import useRealtimeData from './hooks/useRealtimeData';
-import { getTableColumns } from './tableColumns';
-import { Cell, EditCell } from './index';
-import { TableHead } from './TableHead/TableHead';
-import SettingsPanel from './SettingPanel/SettingPanel';
import { ColumnSelectionOverlay } from './ColumnSelectionOverlay/ColumnSelectionOverlay';
+import SettingsPanel from './SettingPanel/SettingPanel';
+import { TableHead } from './TableHead/TableHead';
+import useRealtimeData from './hooks/useRealtimeData';
+import { Cell, EditCell } from './index';
+import { getTableColumns } from './tableColumns';
-import { useColumnSettings } from './hooks/useColumnSettings';
-import { useTableScale } from './hooks/useTableScale';
-import { useHeaderPortal } from './hooks/useHeaderPortal';
-import { useValidationRules } from './hooks/useValidationRules';
-import {
- BASE_TABLE_CONFIG,
- getTableBodyCellProps,
- getTablePaperStyles,
- TABLE_ROW_HEIGHT,
-} from './constants/tableConfig';
-import { useRealtime } from './contexts/RealtimeContext';
-import { toast } from 'react-toastify';
import { CircularProgress } from '@mui/material';
-import { additionExpenseRowTable, additionVspRowTable } from './constants/addingRowConfig';
-import { SelectVspModal } from './Modals/SelectVspModal';
-import { SelectExpenseItemModal } from './Modals/SelectExpenseItemModal';
-import { getRowId } from './utils/rowUtils';
-import { FORM_TYPE_OPTIONS } from '../../constants/constants';
import { debounce } from '@mui/material';
+import { toast } from 'react-toastify';
+import { DictVspApi } from '../../api/dict-vsp';
import { CreateProgramModal } from './Modals/CreateProgramProjectModal';
+import { SelectExpenseItemModal } from './Modals/SelectExpenseItemModal';
+import { SelectVspModal } from './Modals/SelectVspModal';
+import { additionExpenseRowTable, additionVspRowTable } from './constants/addingRowConfig';
+import { BASE_TABLE_CONFIG, TABLE_ROW_HEIGHT, getTableBodyCellProps, getTablePaperStyles } from './constants/tableConfig';
+import { useRealtime } from './contexts/RealtimeContext';
+import { useColumnSettings } from './hooks/useColumnSettings';
+import { useHeaderPortal } from './hooks/useHeaderPortal';
+import { useTableScale } from './hooks/useTableScale';
+import { useValidationRules } from './hooks/useValidationRules';
+import { getRowId } from './utils/rowUtils';
const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
- const { data, setData, isLoading: isTableLoading, editingCells: dataEditingCells } = useRealtimeData(formId, sheetName, direction, formType, year);
- const [globalFilter, setGlobalFilter] = useState('');
- const [showColumnFilters, setShowColumnFilters] = useState(false);
- const [selectedColumnId, setSelectedColumnId] = useState();
- const [rowSelection, setRowSelection] = useState({});
- const [isLoadingData, setIsLoadingData] = useState(false);
- const [isPending, startTransition] = useTransition();
- const [editingCell, setEditingCell] = useState(null);
- const [columnsConfig, setColumnsConfig] = useState(null);
- const { errors: validationErrors, isCellInvalid } = useValidationRules(
- data,
- columnsConfig?.columns,
- );
+ const {
+ data,
+ setData,
+ isLoading: isTableLoading,
+ editingCells: dataEditingCells,
+ } = useRealtimeData(formId, sheetName, direction, formType, year);
+ const [globalFilter, setGlobalFilter] = useState('');
+ const [showColumnFilters, setShowColumnFilters] = useState(false);
+ const [selectedColumnId, setSelectedColumnId] = useState();
+ const [rowSelection, setRowSelection] = useState({});
+ const [isLoadingData, setIsLoadingData] = useState(false);
+ const [_isPending, startTransition] = useTransition();
+ const [editingCell, setEditingCell] = useState(null);
+ const [columnsConfig, setColumnsConfig] = useState(null);
+ const { errors: validationErrors, isCellInvalid } = useValidationRules(data, columnsConfig?.columns);
- const [isOpenModalSelectVsp, setIsOpenModalSelectVsp] = useState(false);
- const [isOpenModalSelectExpenseItem, setIsOpenModalSelectExpenseItem] = useState(false);
- const [isOpenModalCreateProgram, setIsOpenModalCreateProgram] = useState(false);
- const [isOpenModalCreateProject, setIsOpenModalCreateProject] = useState(false);
- const [isProgramCreate, setIsProgramCreate] = useState(false)
+ const [isOpenModalSelectVsp, setIsOpenModalSelectVsp] = useState(false);
+ const [isOpenModalSelectExpenseItem, setIsOpenModalSelectExpenseItem] = useState(false);
+ const [isOpenModalCreateProgram, setIsOpenModalCreateProgram] = useState(false);
+ const [_isOpenModalCreateProject, _setIsOpenModalCreateProject] = useState(false);
+ const [isProgramCreate, setIsProgramCreate] = useState(false);
- const isVspAdditionRow = useMemo(() => {
- if (!formType || !sheetName) return false;
- if (!additionVspRowTable[formType]) return false;
- return additionVspRowTable[formType].includes(sheetName);
- }, [formType, sheetName]);
+ const isVspAdditionRow = useMemo(() => {
+ if (!formType || !sheetName) return false;
+ if (!additionVspRowTable[formType]) return false;
+ return additionVspRowTable[formType].includes(sheetName);
+ }, [formType, sheetName]);
- const isAdditionExpenseItem = useMemo(() => {
- if (!formType || !sheetName) return false;
- if (!additionExpenseRowTable[formType]) return false;
- return additionExpenseRowTable[formType].includes(sheetName);
- }, [formType, sheetName]);
+ const isAdditionExpenseItem = useMemo(() => {
+ if (!formType || !sheetName) return false;
+ if (!additionExpenseRowTable[formType]) return false;
+ return additionExpenseRowTable[formType].includes(sheetName);
+ }, [formType, sheetName]);
- const handleGlobalFilterChange = useCallback(
- debounce((value) => {
- startTransition(() => {
- setGlobalFilter(value);
- });
- }, 300),
- []
- );
+ const handleGlobalFilterChange = useCallback(
+ debounce((value) => {
+ startTransition(() => {
+ setGlobalFilter(value);
+ });
+ }, 300),
+ [],
+ );
- const {
- isConnected,
- isAuthenticated,
- subscribeToErrors,
- subscribeToAuthSuccess,
- error: wsError,
- updateCell: contextUpdateCell,
- addRow: contextAddRow,
- deleteRow: contextDeleteRow,
- startEditing: contextStartEditing,
- addProgram: contextAddProgram,
- addProject: contextAddProject,
- } = useRealtime();
+ const {
+ isConnected,
+ isAuthenticated,
+ subscribeToErrors,
+ subscribeToAuthSuccess,
+ error: wsError,
+ updateCell: contextUpdateCell,
+ addRow: contextAddRow,
+ deleteRow: contextDeleteRow,
+ startEditing: contextStartEditing,
+ addProgram: contextAddProgram,
+ addProject: contextAddProject,
+ setVspOptions,
+ } = useRealtime();
- const {
- columnSizing,
- columnPinning,
- columnVisibility,
- setColumnSizing,
- setColumnPinning,
- handlePinColumn,
- handleUnpinColumn,
- handleSetColumnWidth,
- handleToggleColumnVisibility,
- } = useColumnSettings(`${formId}_${formType}_${sheetName}_${direction}`);
+ const {
+ columnSizing,
+ columnPinning,
+ columnVisibility,
+ setColumnSizing,
+ setColumnPinning,
+ handlePinColumn,
+ handleUnpinColumn,
+ handleSetColumnWidth,
+ handleToggleColumnVisibility,
+ } = useColumnSettings(`${formId}_${formType}_${sheetName}_${direction}`);
- const { headerPortalRef, containerRef } = useHeaderPortal();
- const rowVirtualizerRef = useRef(null);
+ const { headerPortalRef, containerRef } = useHeaderPortal();
+ const rowVirtualizerRef = useRef(null);
- const { sizeMult, setSizeMult, tableScaleStyle, tableWrapperStyle } =
- useTableScale();
+ const { sizeMult, setSizeMult, tableScaleStyle, tableWrapperStyle } = useTableScale();
- useEffect(() => {
- rowVirtualizerRef.current?.measure?.();
- }, [sizeMult]);
+ useEffect(() => {
+ rowVirtualizerRef.current?.measure?.();
+ }, [sizeMult]);
- const configCache = useRef(new Map());
+ const configCache = useRef(new Map());
- useEffect(() => {
- if (!formType || !sheetName) return;
- const cacheKey = `${formType}_${sheetName}`;
+ useEffect(() => {
+ if (!formType || !sheetName) return;
+ const cacheKey = `${formType}_${sheetName}`;
- if (configCache.current.has(cacheKey)) {
- setColumnsConfig(configCache.current.get(cacheKey));
- return;
- }
+ if (configCache.current.has(cacheKey)) {
+ setColumnsConfig(configCache.current.get(cacheKey));
+ return;
+ }
- const loadConfig = async () => {
- try {
- const { config } = await import(`./constants/${formType}/${sheetName}.js`);
- configCache.current.set(cacheKey, config.config);
- setColumnsConfig(config.config);
- } catch (error) {
- console.error(`Failed to load config for ${formType}/${sheetName}:`, error);
- setColumnsConfig({ columns: [], colors: {} });
- }
- };
+ const loadConfig = async () => {
+ try {
+ const { config } = await import(`./constants/${formType}/${sheetName}.js`);
+ configCache.current.set(cacheKey, config.config);
+ setColumnsConfig(config.config);
+ } catch (_error) {
+ setColumnsConfig({ columns: [], colors: {} });
+ }
+ };
- loadConfig();
- }, [formType, sheetName]);
+ loadConfig();
+ }, [formType, sheetName]);
- const handleUpdateCell = useCallback(async (row, column, value) => {
- return await contextUpdateCell(row, column, value);
- }, [contextUpdateCell]);
+ useEffect(() => {
+ if (!formId || !columnsConfig?.columns) return;
- const handleClickRowCell = useCallback((rowId) => {
- setRowSelection((prev) => ({
- [rowId]: !prev[rowId],
- }));
- }, [])
+ const hasVspDropdown = (cols) => {
+ for (const col of cols) {
+ if (col.editType === 'vsp_dropdown') return true;
+ if (col.columns && hasVspDropdown(col.columns)) return true;
+ }
+ return false;
+ };
- const handleColumnSelect = useCallback((columnId) => {
- setSelectedColumnId((prev) => {
- const next = prev === columnId ? undefined : columnId;
- return next;
- });
- }, []);
+ if (!hasVspDropdown(columnsConfig.columns)) return;
- useEffect(() => {
- if (!selectedColumnId) return;
+ DictVspApi.getDropdownVsp({ form_id: formId }).then((data) => {
+ if (data.success) {
+ setVspOptions(data.result);
+ }
+ });
+ }, [formId, columnsConfig, setVspOptions]);
- const handleDocumentClick = (e) => {
- if (e.target.closest('[data-col-select-id]')) return;
- if (e.target.closest('[data-pin-panel]')) return;
- if (e.target.closest('[data-validation-errors-menu]')) return;
+ const handleUpdateCell = useCallback(
+ async (row, column, value) => {
+ return await contextUpdateCell(row, column, value);
+ },
+ [contextUpdateCell],
+ );
- setSelectedColumnId(undefined);
- };
+ const handleClickRowCell = useCallback((rowId) => {
+ setRowSelection((prev) => ({
+ [rowId]: !prev[rowId],
+ }));
+ }, []);
- document.addEventListener('mousedown', handleDocumentClick);
- return () => document.removeEventListener('mousedown', handleDocumentClick);
- }, [selectedColumnId]);
+ const handleColumnSelect = useCallback((columnId) => {
+ setSelectedColumnId((prev) => {
+ const next = prev === columnId ? undefined : columnId;
+ return next;
+ });
+ }, []);
- const handleCellUpdateError = useCallback((rowId, columnId, error) => {
- console.error(`Error updating cell ${rowId}_${columnId}:`, error);
- toast.error('Ошибка обновления ячейки');
- }, []);
+ useEffect(() => {
+ if (!selectedColumnId) return;
- const columns = useMemo(() => {
- if (!columnsConfig || !columnsConfig.columns) return [];
- try {
- return getTableColumns({
- Cell,
- EditCell,
- columnsConfig,
- onCellUpdate: handleUpdateCell,
- onCellNumberClick: handleClickRowCell,
- onCellUpdateError: handleCellUpdateError,
- isCellInvalid,
- });
- } catch (error) {
- console.error('Error creating columns:', error);
- return [];
- }
- }, [
- columnsConfig,
- handleCellUpdateError,
- handleClickRowCell,
- handleUpdateCell,
- isCellInvalid,
- ]);
+ const handleDocumentClick = (e) => {
+ if (e.target.closest('[data-col-select-id]')) return;
+ if (e.target.closest('[data-pin-panel]')) return;
+ if (e.target.closest('[data-validation-errors-menu]')) return;
- const selectedColumnIdRef = useRef(selectedColumnId);
+ setSelectedColumnId(undefined);
+ };
- useEffect(() => {
- selectedColumnIdRef.current = selectedColumnId;
- }, [selectedColumnId]);
+ document.addEventListener('mousedown', handleDocumentClick);
+ return () => document.removeEventListener('mousedown', handleDocumentClick);
+ }, [selectedColumnId]);
- const tableMeta = useMemo(() => ({
- updateCell: handleUpdateCell,
- getSelectedColumnId: () => selectedColumnIdRef.current,
- }), [handleUpdateCell]);
+ const handleCellUpdateError = useCallback((_rowId, _columnId, _error) => {
+ toast.error('Ошибка обновления ячейки');
+ }, []);
- const ROW_VIRTUALIZER_OPTIONS = {
- overscan: 5,
- scrollPaddingStart: 0,
- scrollPaddingEnd: 0,
- estimateSize: () => TABLE_ROW_HEIGHT,
- measureElement: (el) => el?.offsetHeight || TABLE_ROW_HEIGHT,
- };
+ const columns = useMemo(() => {
+ if (!columnsConfig || !columnsConfig.columns) return [];
+ try {
+ return getTableColumns({
+ Cell,
+ EditCell,
+ columnsConfig,
+ onCellUpdate: handleUpdateCell,
+ onCellNumberClick: handleClickRowCell,
+ onCellUpdateError: handleCellUpdateError,
+ isCellInvalid,
+ });
+ } catch (_error) {
+ return [];
+ }
+ }, [columnsConfig, handleCellUpdateError, handleClickRowCell, handleUpdateCell, isCellInvalid]);
- const createTableConfig = ({
- columns,
- data,
- columnSizing,
- columnPinning,
- columnVisibility,
- globalFilter,
- showColumnFilters,
- rowSelection,
- containerRef,
- tableMeta,
- setColumnSizing,
- setColumnPinning,
- editingCell,
- contextStartEditing,
- }) => ({
- ...BASE_TABLE_CONFIG,
- columns,
- data,
- enableRowVirtualization: true,
- enableColumnVirtualization: true,
- rowVirtualizerInstanceRef: rowVirtualizerRef,
- rowVirtualizerOptions: ROW_VIRTUALIZER_OPTIONS,
- onEditingCellChange: (cell) => {
- if (cell && !editingCell) {
- contextStartEditing?.(cell.row, cell.column);
- }
- },
- columnVirtualizerOptions: ({ table }) => ({
- overscan: 10,
- measureElement: (el) => {
- if (!el) return 150;
- const index = Number(el?.getAttribute?.('data-index'));
- const isPinned = Boolean(el?.getAttribute?.('data-pinned'));
- if (isPinned) {
- const colId = table.getState().columnPinning.left[index];
- const column = table.getColumn(colId);
- return column?.getSize() ?? 150;
- }
- const allCols = [...table.getLeftVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns()]
- return allCols[index]?.getSize() ?? 150;
- },
- }),
- enableRowSelection: true,
- onRowSelectionChange: setRowSelection,
- onColumnSizingChange: setColumnSizing,
- onColumnPinningChange: setColumnPinning,
- onGlobalFilterChange: handleGlobalFilterChange,
- state: {
- columnSizing,
- columnPinning,
- columnVisibility,
- globalFilter,
- showColumnFilters,
- rowSelection,
- editingCell,
- },
- initialState: {
- expanded: true,
- },
- meta: tableMeta,
- muiTableHeadCellProps: {
- sx: { boxSizing: 'border-box' },
- },
- muiTableBodyCellProps: getTableBodyCellProps,
- muiTableHeadProps: {
- sx: {
- display: 'table-header-group',
- height: '1px',
- minHeight: '1px',
- maxHeight: '1px',
- visibility: 'hidden',
- '& svg': {
- height: '1px',
- minHeight: '1px',
- maxHeight: '1px',
- visibility: 'hidden',
- }
- },
- },
- muiTablePaperProps: getTablePaperStyles(),
- muiTableContainerProps: {
- ref: containerRef,
- sx: {
- position: 'relative',
- contain: 'layout',
- minHeight: '100%',
- '& .MuiTable-root': { position: 'relative' },
- },
- },
- muiTableHeadCellFilterTextFieldProps: {
- placeholder: 'Поиск...',
- size: 'small',
- },
- });
+ const selectedColumnIdRef = useRef(selectedColumnId);
- // Конфигурация таблицы
- const tableConfig = useMemo(() => createTableConfig({
- columns,
- data,
- columnSizing,
- columnPinning,
- columnVisibility,
- globalFilter,
- showColumnFilters,
- rowSelection,
- containerRef,
- tableMeta,
- setColumnSizing,
- setColumnPinning,
- editingCell,
- contextStartEditing,
- }), [
- columns,
- data,
- columnSizing,
- columnPinning,
- columnVisibility,
- globalFilter,
- showColumnFilters,
- rowSelection,
- containerRef,
- tableMeta,
- setColumnSizing,
- setColumnPinning,
- editingCell,
- ]);
+ useEffect(() => {
+ selectedColumnIdRef.current = selectedColumnId;
+ }, [selectedColumnId]);
- const table = useMaterialReactTable(tableConfig);
+ const tableMeta = useMemo(
+ () => ({
+ updateCell: handleUpdateCell,
+ getSelectedColumnId: () => selectedColumnIdRef.current,
+ }),
+ [handleUpdateCell],
+ );
- const handleNavigateToColumn = useCallback((columnId) => {
- if (!columnId) return;
+ const ROW_VIRTUALIZER_OPTIONS = {
+ overscan: 5,
+ scrollPaddingStart: 0,
+ scrollPaddingEnd: 0,
+ estimateSize: () => TABLE_ROW_HEIGHT,
+ measureElement: (el) => el?.offsetHeight || TABLE_ROW_HEIGHT,
+ };
- setSelectedColumnId(columnId);
+ const createTableConfig = ({
+ columns,
+ data,
+ columnSizing,
+ columnPinning,
+ columnVisibility,
+ globalFilter,
+ showColumnFilters,
+ rowSelection,
+ containerRef,
+ tableMeta,
+ setColumnSizing,
+ setColumnPinning,
+ editingCell,
+ contextStartEditing,
+ }) => ({
+ ...BASE_TABLE_CONFIG,
+ columns,
+ data,
+ enableRowVirtualization: true,
+ enableColumnVirtualization: true,
+ rowVirtualizerInstanceRef: rowVirtualizerRef,
+ rowVirtualizerOptions: ROW_VIRTUALIZER_OPTIONS,
+ onEditingCellChange: (cell) => {
+ if (cell && !editingCell) {
+ contextStartEditing?.(cell.row, cell.column);
+ }
+ },
+ columnVirtualizerOptions: ({ table }) => ({
+ overscan: 10,
+ measureElement: (el) => {
+ if (!el) return 150;
+ const index = Number(el?.getAttribute?.('data-index'));
+ const isPinned = Boolean(el?.getAttribute?.('data-pinned'));
+ if (isPinned) {
+ const colId = table.getState().columnPinning.left[index];
+ const column = table.getColumn(colId);
+ return column?.getSize() ?? 150;
+ }
+ const allCols = [...table.getLeftVisibleLeafColumns(), ...table.getCenterVisibleLeafColumns()];
+ return allCols[index]?.getSize() ?? 150;
+ },
+ }),
+ enableRowSelection: true,
+ onRowSelectionChange: setRowSelection,
+ onColumnSizingChange: setColumnSizing,
+ onColumnPinningChange: setColumnPinning,
+ onGlobalFilterChange: handleGlobalFilterChange,
+ state: {
+ columnSizing,
+ columnPinning,
+ columnVisibility,
+ globalFilter,
+ showColumnFilters,
+ rowSelection,
+ editingCell,
+ },
+ initialState: {
+ expanded: true,
+ },
+ meta: tableMeta,
+ muiTableHeadCellProps: {
+ sx: { boxSizing: 'border-box' },
+ },
+ muiTableBodyCellProps: getTableBodyCellProps,
+ muiTableHeadProps: {
+ sx: {
+ display: 'table-header-group',
+ height: '1px',
+ minHeight: '1px',
+ maxHeight: '1px',
+ visibility: 'hidden',
+ '& svg': {
+ height: '1px',
+ minHeight: '1px',
+ maxHeight: '1px',
+ visibility: 'hidden',
+ },
+ },
+ },
+ muiTablePaperProps: getTablePaperStyles(),
+ muiTableContainerProps: {
+ ref: containerRef,
+ sx: {
+ position: 'relative',
+ contain: 'layout',
+ minHeight: '100%',
+ '& .MuiTable-root': { position: 'relative' },
+ },
+ },
+ muiTableHeadCellFilterTextFieldProps: {
+ placeholder: 'Поиск...',
+ size: 'small',
+ },
+ });
- const container = containerRef.current;
- if (!container) return;
+ // Конфигурация таблицы
+ const tableConfig = useMemo(
+ () =>
+ createTableConfig({
+ columns,
+ data,
+ columnSizing,
+ columnPinning,
+ columnVisibility,
+ globalFilter,
+ showColumnFilters,
+ rowSelection,
+ containerRef,
+ tableMeta,
+ setColumnSizing,
+ setColumnPinning,
+ editingCell,
+ contextStartEditing,
+ }),
+ [
+ columns,
+ data,
+ columnSizing,
+ columnPinning,
+ columnVisibility,
+ globalFilter,
+ showColumnFilters,
+ rowSelection,
+ containerRef,
+ tableMeta,
+ setColumnSizing,
+ setColumnPinning,
+ editingCell,
+ ],
+ );
- const pinnedIds = new Set(columnPinning?.left || []);
- if (pinnedIds.has(columnId)) return;
+ const table = useMaterialReactTable(tableConfig);
- const centerColumns = table
- .getVisibleLeafColumns()
- .filter((column) => !pinnedIds.has(column.id));
+ const handleNavigateToColumn = useCallback(
+ (columnId) => {
+ if (!columnId) return;
- let offset = 0;
- for (const column of centerColumns) {
- if (column.id === columnId) break;
- offset += column.getSize();
- }
+ setSelectedColumnId(columnId);
- container.scrollTo({
- left: Math.max(0, offset - 40),
- behavior: 'smooth',
- });
- }, [columnPinning, containerRef, table]);
+ const container = containerRef.current;
+ if (!container) return;
- useEffect(() => {
- if (!dataEditingCells?.line_id) {
- setEditingCell(null);
- return;
- }
- if (editingCell) return;
+ const pinnedIds = new Set(columnPinning?.left || []);
+ if (pinnedIds.has(columnId)) return;
- // Отложить поиск до следующего тика
- requestAnimationFrame(() => {
- try {
- const row = table.getRow(dataEditingCells.line_id);
- const cell = row?.getVisibleCells().find(
- c => c.column.id === dataEditingCells.column
- );
- if (cell) setEditingCell(cell);
- } catch (error) {
- console.error(error);
- }
- });
- }, [dataEditingCells, editingCell, table]);
+ const centerColumns = table.getVisibleLeafColumns().filter((column) => !pinnedIds.has(column.id));
- const [isFirstLoad, setIsFirstLoad] = useState(true);
+ let offset = 0;
+ for (const column of centerColumns) {
+ if (column.id === columnId) break;
+ offset += column.getSize();
+ }
- useEffect(() => {
- if (isFirstLoad && table && data && columns.length !== 0) {
- setIsFirstLoad(false);
- setIsLoadingData(true);
- }
- }, [data, columns, table, isFirstLoad]);
+ container.scrollTo({
+ left: Math.max(0, offset - 40),
+ behavior: 'smooth',
+ });
+ },
+ [columnPinning, containerRef, table],
+ );
- const handleAddRow = useCallback(() => {
- const allRows = table.getRowModel().rows;
+ useEffect(() => {
+ if (!dataEditingCells?.line_id) {
+ setEditingCell(null);
+ return;
+ }
+ if (editingCell) return;
- const selectedRows = allRows.filter(row => rowSelection[row.id]);
- if (selectedRows.length === 0) {
- toast.error('Выделите строку для вставки');
- return;
- }
- const row = selectedRows[0];
- const expense_item_id = row.original.data.header.expense_item_id;
- contextAddRow({ expense_item_id: expense_item_id })
- }, [rowSelection, table])
+ // Отложить поиск до следующего тика
+ requestAnimationFrame(() => {
+ try {
+ const row = table.getRow(dataEditingCells.line_id);
+ const cell = row?.getVisibleCells().find((c) => c.column.id === dataEditingCells.column);
+ if (cell) setEditingCell(cell);
+ } catch (_error) {}
+ });
+ }, [dataEditingCells, editingCell, table]);
- const handleAddVspRow = useCallback((vsp_id) => {
- contextAddRow({ vsp_id: vsp_id });
- }, []);
+ const [isFirstLoad, setIsFirstLoad] = useState(true);
- const handleAddExpenseItemRow = useCallback((expense_item) => {
- const allRows = table.getRowModel().rows;
- const selectedRows = allRows.filter(row => rowSelection[row.id]);
- const row = selectedRows[0];
- contextAddRow({ expense_item_id: expense_item.id, project_id: row.original.data.header.project_id });
- }, [rowSelection]);
+ useEffect(() => {
+ if (isFirstLoad && table && data && columns.length !== 0) {
+ setIsFirstLoad(false);
+ setIsLoadingData(true);
+ }
+ }, [data, columns, table, isFirstLoad]);
- const handleAddProgramRow = useCallback((name) => {
- contextAddProgram({ name: name });
- }, []);
+ const handleAddRow = useCallback(() => {
+ const allRows = table.getRowModel().rows;
- const handleAddProjectRow = useCallback((name) => {
- const allRows = table.getRowModel().rows;
- const selectedRows = allRows.filter(row => rowSelection[row.id]);
- const row = selectedRows[0];
- contextAddProject({ name: name, program_id: row.original.data.header.program_id });
- }, [rowSelection]);
+ const selectedRows = allRows.filter((row) => rowSelection[row.id]);
+ if (selectedRows.length === 0) {
+ toast.error('Выделите строку для вставки');
+ return;
+ }
+ const row = selectedRows[0];
+ const expense_item_id = row.original.data.header.expense_item_id;
+ contextAddRow({ expense_item_id: expense_item_id });
+ }, [rowSelection, table]);
- const handleOpenModalSelectVsp = useCallback(() => {
- setIsOpenModalSelectVsp(true);
- }, [])
+ const handleAddVspRow = useCallback((vsp_id) => {
+ contextAddRow({ vsp_id: vsp_id });
+ }, []);
- const handleOpenModalSelectExpenseItem = useCallback(() => {
- const allRows = table.getRowModel().rows;
+ const handleAddExpenseItemRow = useCallback(
+ (expense_item) => {
+ const allRows = table.getRowModel().rows;
+ const selectedRows = allRows.filter((row) => rowSelection[row.id]);
+ const row = selectedRows[0];
+ contextAddRow({ expense_item_id: expense_item.id, project_id: row.original.data.header.project_id });
+ },
+ [rowSelection],
+ );
- const selectedRows = allRows.filter(row => rowSelection[row.id]);
- if (selectedRows.length === 0) {
- toast.error('Выделите строку для вставки');
- return;
- }
- const row = selectedRows[0];
- if (row.original.row_type !== 'ITEM') {
- toast.error('Выделите строку проекта');
- return;
- }
- setIsOpenModalSelectExpenseItem(true);
- }, [rowSelection])
+ const handleAddProgramRow = useCallback((name) => {
+ contextAddProgram({ name: name });
+ }, []);
- const handleDeleteRow = useCallback(() => {
- const allRows = table.getRowModel().rows;
+ const handleAddProjectRow = useCallback(
+ (name) => {
+ const allRows = table.getRowModel().rows;
+ const selectedRows = allRows.filter((row) => rowSelection[row.id]);
+ const row = selectedRows[0];
+ contextAddProject({ name: name, program_id: row.original.data.header.program_id });
+ },
+ [rowSelection],
+ );
- const selectedRows = allRows.filter(row => rowSelection[row.id]);
- if (selectedRows.length === 0) {
- toast.error('Выделите строку для удаления');
- return;
- }
- const row = selectedRows[0];
- const rowId = getRowId(row);
- contextDeleteRow(rowId);
- setRowSelection({});
- }, [rowSelection, table])
+ const handleOpenModalSelectVsp = useCallback(() => {
+ setIsOpenModalSelectVsp(true);
+ }, []);
- const addRow = useCallback(() => {
+ const handleOpenModalSelectExpenseItem = useCallback(() => {
+ const allRows = table.getRowModel().rows;
- if (isVspAdditionRow) {
- return handleOpenModalSelectVsp();
- }
- if (isAdditionExpenseItem) {
- return handleOpenModalSelectExpenseItem();
- }
- return handleAddRow();
- }, [isVspAdditionRow, isAdditionExpenseItem, handleOpenModalSelectVsp, handleAddRow]);
+ const selectedRows = allRows.filter((row) => rowSelection[row.id]);
+ if (selectedRows.length === 0) {
+ toast.error('Выделите строку для вставки');
+ return;
+ }
+ const row = selectedRows[0];
+ if (row.original.row_type !== 'ITEM') {
+ toast.error('Выделите строку проекта');
+ return;
+ }
+ setIsOpenModalSelectExpenseItem(true);
+ }, [rowSelection]);
- const addProgram = useCallback(() => {
- setIsProgramCreate(true);
- setIsOpenModalCreateProgram(true);
- }, [setIsOpenModalCreateProgram])
+ const handleDeleteRow = useCallback(() => {
+ const allRows = table.getRowModel().rows;
- const addProject = useCallback(() => {
- setIsProgramCreate(false);
- const allRows = table.getRowModel().rows;
+ const selectedRows = allRows.filter((row) => rowSelection[row.id]);
+ if (selectedRows.length === 0) {
+ toast.error('Выделите строку для удаления');
+ return;
+ }
+ const row = selectedRows[0];
+ const rowId = getRowId(row);
+ contextDeleteRow(rowId);
+ setRowSelection({});
+ }, [rowSelection, table]);
- const selectedRows = allRows.filter(row => rowSelection[row.id]);
- if (selectedRows.length === 0) {
- toast.error('Выделите строку для вставки');
- return;
- }
- const row = selectedRows[0];
- if (row.original.row_type !== 'GROUP') {
- toast.error('Выделите строку программы');
- return;
- }
- setIsOpenModalCreateProgram(true);
- }, [setIsOpenModalCreateProgram, rowSelection])
+ const addRow = useCallback(() => {
+ if (isVspAdditionRow) {
+ return handleOpenModalSelectVsp();
+ }
+ if (isAdditionExpenseItem) {
+ return handleOpenModalSelectExpenseItem();
+ }
+ return handleAddRow();
+ }, [isVspAdditionRow, isAdditionExpenseItem, handleOpenModalSelectVsp, handleAddRow]);
- useEffect(() => {
- return () => {
- setData([]);
- setRowSelection({});
- setEditingCell(null);
- if (rowVirtualizerRef.current) {
- rowVirtualizerRef.current = null;
- }
- };
- }, []);
+ const addProgram = useCallback(() => {
+ setIsProgramCreate(true);
+ setIsOpenModalCreateProgram(true);
+ }, [setIsOpenModalCreateProgram]);
- return (
- <>
-
+ const addProject = useCallback(() => {
+ setIsProgramCreate(false);
+ const allRows = table.getRowModel().rows;
-
-
-
-
+ const selectedRows = allRows.filter((row) => rowSelection[row.id]);
+ if (selectedRows.length === 0) {
+ toast.error('Выделите строку для вставки');
+ return;
+ }
+ const row = selectedRows[0];
+ if (row.original.row_type !== 'GROUP') {
+ toast.error('Выделите строку программы');
+ return;
+ }
+ setIsOpenModalCreateProgram(true);
+ }, [setIsOpenModalCreateProgram, rowSelection]);
-
+ useEffect(() => {
+ return () => {
+ setData([]);
+ setRowSelection({});
+ setEditingCell(null);
+ if (rowVirtualizerRef.current) {
+ rowVirtualizerRef.current = null;
+ }
+ };
+ }, []);
- {isTableLoading && (
-
-
-
- )}
+ return (
+ <>
+
- {headerPortalRef.current &&
- createPortal(
-
theme.zIndex.modal - 1 }}
- selectedColumnId={selectedColumnId}
- onColumnSelect={handleColumnSelect}
- onChangeWidth={handleSetColumnWidth}
- isLoadingData={isLoadingData}
- />,
- headerPortalRef.current,
- )}
-
-
-
- setIsOpenModalSelectVsp(false)}
- formId={formId}
- onSelect={handleAddVspRow}
- title="Выбор ВСП"
- />
- setIsOpenModalSelectExpenseItem(false)}
- formId={formId}
- onSelect={handleAddExpenseItemRow}
- title="Добавление строки"
- sheet={sheetName}
- />
- setIsOpenModalCreateProgram(false)}
- title={isProgramCreate ? "Создание программы" : "Создание проекта"}
- onCreate={isProgramCreate ? handleAddProgramRow : handleAddProjectRow}
- />
- >
- );
+
+
+
+
+
+
+
+ {isTableLoading && (
+
+
+
+ )}
+
+ {headerPortalRef.current &&
+ createPortal(
+
theme.zIndex.modal - 1 }}
+ selectedColumnId={selectedColumnId}
+ onColumnSelect={handleColumnSelect}
+ onChangeWidth={handleSetColumnWidth}
+ isLoadingData={isLoadingData}
+ />,
+ headerPortalRef.current,
+ )}
+
+
+
+ setIsOpenModalSelectVsp(false)}
+ formId={formId}
+ onSelect={handleAddVspRow}
+ title='Выбор ВСП'
+ />
+ setIsOpenModalSelectExpenseItem(false)}
+ formId={formId}
+ onSelect={handleAddExpenseItemRow}
+ title='Добавление строки'
+ sheet={sheetName}
+ />
+ setIsOpenModalCreateProgram(false)}
+ title={isProgramCreate ? 'Создание программы' : 'Создание проекта'}
+ onCreate={isProgramCreate ? handleAddProgramRow : handleAddProjectRow}
+ />
+ >
+ );
};
-export default React.memo(RealtimeTable);
\ No newline at end of file
+export default React.memo(RealtimeTable);
diff --git a/web/src/components/RealtimeTable/constants/FORM_2/AHR.js b/web/src/components/RealtimeTable/constants/FORM_2/AHR.js
index a6cf4b5..d0dceb3 100644
--- a/web/src/components/RealtimeTable/constants/FORM_2/AHR.js
+++ b/web/src/components/RealtimeTable/constants/FORM_2/AHR.js
@@ -1,3200 +1,3194 @@
-import {
- greenColumn,
- whiteColumn,
- orangeColumn,
- yellowColumn,
- redColumn,
- blueColumn,
-} from "../columnColors";
+import { blueColumn, greenColumn, orangeColumn, redColumn, whiteColumn, yellowColumn } from '../columnColors';
export const config = {
- config: {
- colors: {
- "data.header.section_code": {
- color_type: greenColumn,
- accessorKey: "data.header.section_code",
- },
- "data.header.item_id": {
- color_type: greenColumn,
- accessorKey: "data.header.item_id",
- },
- "data.header.num_group": {
- color_type: greenColumn,
- accessorKey: "data.header.num_group",
- },
- "data.header.name": {
- color_type: greenColumn,
- accessorKey: "data.header.name",
- },
- "data.header.vsp_id": {
- color_type: greenColumn,
- accessorKey: "data.header.vsp_id",
- },
- "data.plan.q1": {
- color_type: greenColumn,
- accessorKey: "data.plan.q1",
- },
- "data.plan.q2": {
- color_type: greenColumn,
- accessorKey: "data.plan.q2",
- },
- "data.plan.q3": {
- color_type: greenColumn,
- accessorKey: "data.plan.q3",
- },
- "data.plan.q4": {
- color_type: greenColumn,
- accessorKey: "data.plan.q4",
- },
- "data.plan.year": {
- color_type: greenColumn,
- accessorKey: "data.plan.year",
- },
- "data.plan.comment": {
- color_type: greenColumn,
- accessorKey: "data.plan.comment",
- },
- "2026_god_field_field": {
- color_type: whiteColumn,
- accessorKey: "2026_god_field_field",
- },
- "data.seq_dfip.q1": {
- color_type: greenColumn,
- accessorKey: "data.seq_dfip.q1",
- },
- "data.seq_dfip.q2": {
- color_type: greenColumn,
- accessorKey: "data.seq_dfip.q2",
- },
- "data.seq_dfip.q3": {
- color_type: greenColumn,
- accessorKey: "data.seq_dfip.q3",
- },
- "data.seq_dfip.q4": {
- color_type: greenColumn,
- accessorKey: "data.seq_dfip.q4",
- },
- "data.seq_dfip.year": {
- color_type: greenColumn,
- accessorKey: "data.seq_dfip.year",
- },
- "data.seq_dfip.justification": {
- color_type: greenColumn,
- accessorKey: "data.seq_dfip.justification",
- },
- "data.seq_ssp.q1": {
- color_type: greenColumn,
- accessorKey: "data.seq_ssp.q1",
- },
- "data.seq_ssp.q2": {
- color_type: greenColumn,
- accessorKey: "data.seq_ssp.q2",
- },
- "data.seq_ssp.q3": {
- color_type: greenColumn,
- accessorKey: "data.seq_ssp.q3",
- },
- "data.seq_ssp.q4": {
- color_type: greenColumn,
- accessorKey: "data.seq_ssp.q4",
- },
- "data.seq_ssp.year": {
- color_type: greenColumn,
- accessorKey: "data.seq_ssp.year",
- },
- "data.seq_ssp.justification": {
- color_type: greenColumn,
- accessorKey: "data.seq_ssp.justification",
- },
- "data.approved.q1": {
- color_type: greenColumn,
- accessorKey: "data.approved.q1",
- },
- "data.approved.q2": {
- color_type: greenColumn,
- accessorKey: "data.approved.q2",
- },
- "data.approved.q3": {
- color_type: greenColumn,
- accessorKey: "data.approved.q3",
- },
- "data.approved.q4": {
- color_type: greenColumn,
- accessorKey: "data.approved.q4",
- },
- "data.approved.year": {
- color_type: greenColumn,
- accessorKey: "data.approved.year",
- },
- "data.contract.counterparty": {
- color_type: orangeColumn,
- accessorKey: "data.contract.counterparty",
- },
- "data.contract.reference": {
- color_type: orangeColumn,
- accessorKey: "data.contract.reference",
- },
- "data.contract.date": {
- color_type: orangeColumn,
- accessorKey: "data.contract.date",
- },
- "data.contract.subject": {
- color_type: orangeColumn,
- accessorKey: "data.contract.subject",
- },
- "data.contract.currency": {
- color_type: orangeColumn,
- accessorKey: "data.contract.currency",
- },
- "data.contract.ceiling": {
- color_type: orangeColumn,
- accessorKey: "data.contract.ceiling",
- },
- "data.contract.vat_rate": {
- color_type: orangeColumn,
- accessorKey: "data.contract.vat_rate",
- },
- "data.contract.deadline": {
- color_type: orangeColumn,
- accessorKey: "data.contract.deadline",
- },
- "data.contract.scheme": {
- color_type: orangeColumn,
- accessorKey: "data.contract.scheme",
- },
- "data.contract.act": {
- color_type: orangeColumn,
- accessorKey: "data.contract.act",
- },
- "data.contract.comment": {
- color_type: orangeColumn,
- accessorKey: "data.contract.comment",
- },
- "data.booking.y2026.q1": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2026.q1",
- },
- "data.booking.y2026.q2": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2026.q2",
- },
- "data.booking.y2026.q3": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2026.q3",
- },
- "data.booking.y2026.q4": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2026.q4",
- },
- "data.booking.y2027.q1": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2027.q1",
- },
- "data.booking.y2027.q2": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2027.q2",
- },
- "data.booking.y2027.q3": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2027.q3",
- },
- "data.booking.y2027.q4": {
- color_type: orangeColumn,
- accessorKey: "data.booking.y2027.q4",
- },
- "data.q1.adj_current": {
- color_type: yellowColumn,
- accessorKey: "data.q1.adj_current",
- },
- "data.q1.adj_ssp": {
- color_type: yellowColumn,
- accessorKey: "data.q1.adj_ssp",
- },
- "data.q1.adj_reserve": {
- color_type: yellowColumn,
- accessorKey: "data.q1.adj_reserve",
- },
- "data.q1.adj_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q1.adj_comment",
- },
- "data.q1.corrected_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q1.corrected_plan",
- },
- "1_kvartal_2026_goda_field_field": {
- color_type: whiteColumn,
- accessorKey: "1_kvartal_2026_goda_field_field",
- },
- "data.q1.pay_date": {
- color_type: blueColumn,
- accessorKey: "data.q1.pay_date",
- },
- "data.q1.pay_amount": {
- color_type: blueColumn,
- accessorKey: "data.q1.pay_amount",
- },
- "data.q1.pay_comment": {
- color_type: blueColumn,
- accessorKey: "data.q1.pay_comment",
- },
- "data.q1.pay_act": {
- color_type: blueColumn,
- accessorKey: "data.q1.pay_act",
- },
- "data.q1.booking": {
- color_type: orangeColumn,
- accessorKey: "data.q1.booking",
- },
- "data.q1.actual_m1": {
- color_type: greenColumn,
- accessorKey: "data.q1.actual_m1",
- },
- "data.q1.actual_m2": {
- color_type: greenColumn,
- accessorKey: "data.q1.actual_m2",
- },
- "data.q1.actual_m3": {
- color_type: greenColumn,
- accessorKey: "data.q1.actual_m3",
- },
- "data.q1.actual_quarter": {
- color_type: greenColumn,
- accessorKey: "data.q1.actual_quarter",
- },
- "data.q1.residual_after_booking": {
- color_type: orangeColumn,
- accessorKey: "data.q1.residual_after_booking",
- },
- "data.q1.residual_after_actual": {
- color_type: greenColumn,
- accessorKey: "data.q1.residual_after_actual",
- },
- "data.q1.transfer_q2": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_q2",
- },
- "data.q1.transfer_q2_delay_acts": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_q2_delay_acts",
- },
- "data.q1.transfer_q2_delay_procurement": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_q2_delay_procurement",
- },
- "data.q1.transfer_q2_economy_rf": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_q2_economy_rf",
- },
- "data.q1.transfer_next_comment": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_next_comment",
- },
- "data.q1.transfer_q3": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_q3",
- },
- "data.q1.transfer_q4": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_q4",
- },
- "data.q1.transfer_far_comment": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_far_comment",
- },
- "data.q1.transfer_econ": {
- color_type: redColumn,
- accessorKey: "data.q1.transfer_econ",
- },
- "data.q1.total": {
- color_type: redColumn,
- accessorKey: "data.q1.total",
- },
- "data.q2.target_change": {
- color_type: redColumn,
- accessorKey: "data.q2.target_change",
- },
- "data.q2.base_correction": {
- color_type: redColumn,
- accessorKey: "data.q2.base_correction",
- },
- "data.q2.base_correction_comment": {
- color_type: redColumn,
- accessorKey: "data.q2.base_correction_comment",
- },
- "data.q2.revision_inc": {
- color_type: yellowColumn,
- accessorKey: "data.q2.revision_inc",
- },
- "data.q2.revision_seq": {
- color_type: yellowColumn,
- accessorKey: "data.q2.revision_seq",
- },
- "data.q2.revision_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q2.revision_comment",
- },
- "data.q2.new_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q2.new_plan",
- },
- "2_kvartal_2026_goda_field_field": {
- color_type: whiteColumn,
- accessorKey: "2_kvartal_2026_goda_field_field",
- },
- "data.q2.adj_current": {
- color_type: yellowColumn,
- accessorKey: "data.q2.adj_current",
- },
- "data.q2.adj_ssp": {
- color_type: yellowColumn,
- accessorKey: "data.q2.adj_ssp",
- },
- "data.q2.adj_reserve": {
- color_type: yellowColumn,
- accessorKey: "data.q2.adj_reserve",
- },
- "data.q2.adj_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q2.adj_comment",
- },
- "data.q2.corrected_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q2.corrected_plan",
- },
- "data.q2.pay_date": {
- color_type: blueColumn,
- accessorKey: "data.q2.pay_date",
- },
- "data.q2.pay_amount": {
- color_type: blueColumn,
- accessorKey: "data.q2.pay_amount",
- },
- "data.q2.pay_comment": {
- color_type: blueColumn,
- accessorKey: "data.q2.pay_comment",
- },
- "data.q2.pay_act": {
- color_type: blueColumn,
- accessorKey: "data.q2.pay_act",
- },
- "data.q2.booking": {
- color_type: orangeColumn,
- accessorKey: "data.q2.booking",
- },
- "data.q2.actual_m1": {
- color_type: greenColumn,
- accessorKey: "data.q2.actual_m1",
- },
- "data.q2.actual_m2": {
- color_type: greenColumn,
- accessorKey: "data.q2.actual_m2",
- },
- "data.q2.actual_m3": {
- color_type: greenColumn,
- accessorKey: "data.q2.actual_m3",
- },
- "data.q2.actual_quarter": {
- color_type: greenColumn,
- accessorKey: "data.q2.actual_quarter",
- },
- "data.q2.residual_after_booking": {
- color_type: orangeColumn,
- accessorKey: "data.q2.residual_after_booking",
- },
- "data.q2.residual_after_actual": {
- color_type: greenColumn,
- accessorKey: "data.q2.residual_after_actual",
- },
- "data.q2.transfer_q3": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_q3",
- },
- "data.q2.transfer_q3_delay_acts": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_q3_delay_acts",
- },
- "data.q2.transfer_q3_delay_procurement": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_q3_delay_procurement",
- },
- "data.q2.transfer_q3_economy_rf": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_q3_economy_rf",
- },
- "data.q2.transfer_next_comment": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_next_comment",
- },
- "data.q2.transfer_q4": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_q4",
- },
- "data.q2.transfer_far_comment": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_far_comment",
- },
- "data.q2.transfer_econ": {
- color_type: redColumn,
- accessorKey: "data.q2.transfer_econ",
- },
- "data.q2.total": {
- color_type: redColumn,
- accessorKey: "data.q2.total",
- },
- "data.q3.target_change": {
- color_type: redColumn,
- accessorKey: "data.q3.target_change",
- },
- "data.q3.base_correction": {
- color_type: redColumn,
- accessorKey: "data.q3.base_correction",
- },
- "data.q3.base_correction_comment": {
- color_type: redColumn,
- accessorKey: "data.q3.base_correction_comment",
- },
- "data.q3.revision_inc": {
- color_type: yellowColumn,
- accessorKey: "data.q3.revision_inc",
- },
- "data.q3.revision_seq": {
- color_type: yellowColumn,
- accessorKey: "data.q3.revision_seq",
- },
- "data.q3.revision_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q3.revision_comment",
- },
- "data.q3.new_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q3.new_plan",
- },
- "3_kvartal_2026_goda_field_field": {
- color_type: whiteColumn,
- accessorKey: "3_kvartal_2026_goda_field_field",
- },
- "data.q3.adj_current": {
- color_type: yellowColumn,
- accessorKey: "data.q3.adj_current",
- },
- "data.q3.adj_ssp": {
- color_type: yellowColumn,
- accessorKey: "data.q3.adj_ssp",
- },
- "data.q3.adj_reserve": {
- color_type: yellowColumn,
- accessorKey: "data.q3.adj_reserve",
- },
- "data.q3.adj_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q3.adj_comment",
- },
- "data.q3.corrected_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q3.corrected_plan",
- },
- "data.q3.pay_date": {
- color_type: blueColumn,
- accessorKey: "data.q3.pay_date",
- },
- "data.q3.pay_amount": {
- color_type: blueColumn,
- accessorKey: "data.q3.pay_amount",
- },
- "data.q3.pay_comment": {
- color_type: blueColumn,
- accessorKey: "data.q3.pay_comment",
- },
- "data.q3.pay_act": {
- color_type: blueColumn,
- accessorKey: "data.q3.pay_act",
- },
- "data.q3.booking": {
- color_type: orangeColumn,
- accessorKey: "data.q3.booking",
- },
- "data.q3.actual_m1": {
- color_type: greenColumn,
- accessorKey: "data.q3.actual_m1",
- },
- "data.q3.actual_m2": {
- color_type: greenColumn,
- accessorKey: "data.q3.actual_m2",
- },
- "data.q3.actual_m3": {
- color_type: greenColumn,
- accessorKey: "data.q3.actual_m3",
- },
- "data.q3.actual_quarter": {
- color_type: greenColumn,
- accessorKey: "data.q3.actual_quarter",
- },
- "data.q3.residual_after_booking": {
- color_type: orangeColumn,
- accessorKey: "data.q3.residual_after_booking",
- },
- "data.q3.residual_after_actual": {
- color_type: greenColumn,
- accessorKey: "data.q3.residual_after_actual",
- },
- "data.q3.transfer_q4": {
- color_type: redColumn,
- accessorKey: "data.q3.transfer_q4",
- },
- "data.q3.transfer_q4_delay_acts": {
- color_type: redColumn,
- accessorKey: "data.q3.transfer_q4_delay_acts",
- },
- "data.q3.transfer_q4_delay_procurement": {
- color_type: redColumn,
- accessorKey: "data.q3.transfer_q4_delay_procurement",
- },
- "data.q3.transfer_q4_economy_rf": {
- color_type: redColumn,
- accessorKey: "data.q3.transfer_q4_economy_rf",
- },
- "data.q3.transfer_next_comment": {
- color_type: redColumn,
- accessorKey: "data.q3.transfer_next_comment",
- },
- "data.q3.transfer_econ": {
- color_type: redColumn,
- accessorKey: "data.q3.transfer_econ",
- },
- "data.q3.total": {
- color_type: redColumn,
- accessorKey: "data.q3.total",
- },
- "data.q4.target_change": {
- color_type: redColumn,
- accessorKey: "data.q4.target_change",
- },
- "data.q4.base_correction": {
- color_type: redColumn,
- accessorKey: "data.q4.base_correction",
- },
- "data.q4.base_correction_comment": {
- color_type: redColumn,
- accessorKey: "data.q4.base_correction_comment",
- },
- "data.q4.revision_inc": {
- color_type: yellowColumn,
- accessorKey: "data.q4.revision_inc",
- },
- "data.q4.revision_seq": {
- color_type: yellowColumn,
- accessorKey: "data.q4.revision_seq",
- },
- "data.q4.revision_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q4.revision_comment",
- },
- "data.q4.new_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q4.new_plan",
- },
- "4_kvartal_2026_goda_field_field": {
- color_type: whiteColumn,
- accessorKey: "4_kvartal_2026_goda_field_field",
- },
- "data.q4.adj_current": {
- color_type: yellowColumn,
- accessorKey: "data.q4.adj_current",
- },
- "data.q4.adj_ssp": {
- color_type: yellowColumn,
- accessorKey: "data.q4.adj_ssp",
- },
- "data.q4.adj_reserve": {
- color_type: yellowColumn,
- accessorKey: "data.q4.adj_reserve",
- },
- "data.q4.adj_comment": {
- color_type: yellowColumn,
- accessorKey: "data.q4.adj_comment",
- },
- "data.q4.corrected_plan": {
- color_type: yellowColumn,
- accessorKey: "data.q4.corrected_plan",
- },
- "data.q4.pay_date": {
- color_type: blueColumn,
- accessorKey: "data.q4.pay_date",
- },
- "data.q4.pay_amount": {
- color_type: blueColumn,
- accessorKey: "data.q4.pay_amount",
- },
- "data.q4.pay_comment": {
- color_type: blueColumn,
- accessorKey: "data.q4.pay_comment",
- },
- "data.q4.pay_act": {
- color_type: blueColumn,
- accessorKey: "data.q4.pay_act",
- },
- "data.q4.booking": {
- color_type: orangeColumn,
- accessorKey: "data.q4.booking",
- },
- "data.q4.actual_m1": {
- color_type: greenColumn,
- accessorKey: "data.q4.actual_m1",
- },
- "data.q4.actual_m2": {
- color_type: greenColumn,
- accessorKey: "data.q4.actual_m2",
- },
- "data.q4.actual_m3": {
- color_type: greenColumn,
- accessorKey: "data.q4.actual_m3",
- },
- "data.q4.actual_spod": {
- color_type: greenColumn,
- accessorKey: "data.q4.actual_spod",
- },
- "data.q4.actual_quarter": {
- color_type: greenColumn,
- accessorKey: "data.q4.actual_quarter",
- },
- "data.q4.residual_after_booking": {
- color_type: orangeColumn,
- accessorKey: "data.q4.residual_after_booking",
- },
- "data.q4.residual_after_actual": {
- color_type: greenColumn,
- accessorKey: "data.q4.residual_after_actual",
- },
- "data.q4.transfer_econ": {
- color_type: redColumn,
- accessorKey: "data.q4.transfer_econ",
- },
- "data.totals.fact_year": {
- color_type: greenColumn,
- accessorKey: "data.totals.fact_year",
- },
- "2026_god_field_field_5": {
- color_type: whiteColumn,
- accessorKey: "2026_god_field_field_5",
- },
- "data.totals.pay_year": {
- color_type: blueColumn,
- accessorKey: "data.totals.pay_year",
- },
- },
- columns: [
- {
- header: " ",
- accessorKey: "field",
- columns: [
- {
- header: " ",
- accessorKey: "field_field",
- columns: [
- {
- header: "Код раздела",
- accessorKey: "data.header.section_code",
- columnLetter: "A",
- size: 150,
- filterFn: "contains",
- },
- {
- header: "ID статьи",
- accessorKey: "data.header.item_id",
- columnLetter: "B",
- size: 150,
- filterFn: "contains",
- },
- {
- header: "ID группы номенклатуры",
- accessorKey: "data.header.num_group",
- columnLetter: "C",
- size: 220,
- filterFn: "contains",
- },
- {
- header: "Наименование",
- accessorKey: "data.header.name",
- columnLetter: "D",
- size: 150,
- filterFn: "contains",
- },
- {
- header: "ВСП РФ",
- accessorKey: "data.header.vsp_id",
- columnLetter: "E",
- size: 150,
- filterFn: "contains",
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2026 год",
- accessorKey: "2026_god",
- columns: [
- {
- header: "Планирование годовых показателей",
- accessorKey: "2026_god_planirovanie_godovykh_pokazateley",
- columns: [
- {
- header: "1 квартал",
- accessorKey: "data.plan.q1",
- columnLetter: "F",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2 квартал",
- accessorKey: "data.plan.q2",
- columnLetter: "G",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "3 квартал",
- accessorKey: "data.plan.q3",
- columnLetter: "H",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "4 квартал",
- accessorKey: "data.plan.q4",
- columnLetter: "I",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Год",
- accessorKey: "data.plan.year",
- columnLetter: "J",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.plan.comment",
- columnLetter: "K",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
+ config: {
+ colors: {
+ 'data.header.section_code': {
+ color_type: greenColumn,
+ accessorKey: 'data.header.section_code',
+ },
+ 'data.header.item_id': {
+ color_type: greenColumn,
+ accessorKey: 'data.header.item_id',
+ },
+ 'data.header.num_group': {
+ color_type: greenColumn,
+ accessorKey: 'data.header.num_group',
+ },
+ 'data.header.name': {
+ color_type: greenColumn,
+ accessorKey: 'data.header.name',
+ },
+ 'data.header.vsp_id': {
+ color_type: greenColumn,
+ accessorKey: 'data.header.vsp_id',
+ },
+ 'data.header.vsp_address': {
+ color_type: greenColumn,
+ accessorKey: 'data.header.vsp_address',
+ },
+ 'data.plan.q1': {
+ color_type: greenColumn,
+ accessorKey: 'data.plan.q1',
+ },
+ 'data.plan.q2': {
+ color_type: greenColumn,
+ accessorKey: 'data.plan.q2',
+ },
+ 'data.plan.q3': {
+ color_type: greenColumn,
+ accessorKey: 'data.plan.q3',
+ },
+ 'data.plan.q4': {
+ color_type: greenColumn,
+ accessorKey: 'data.plan.q4',
+ },
+ 'data.plan.year': {
+ color_type: greenColumn,
+ accessorKey: 'data.plan.year',
+ },
+ 'data.plan.comment': {
+ color_type: greenColumn,
+ accessorKey: 'data.plan.comment',
+ },
+ '2026_god_field_field': {
+ color_type: whiteColumn,
+ accessorKey: '2026_god_field_field',
+ },
+ 'data.seq_dfip.q1': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_dfip.q1',
+ },
+ 'data.seq_dfip.q2': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_dfip.q2',
+ },
+ 'data.seq_dfip.q3': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_dfip.q3',
+ },
+ 'data.seq_dfip.q4': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_dfip.q4',
+ },
+ 'data.seq_dfip.year': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_dfip.year',
+ },
+ 'data.seq_dfip.justification': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_dfip.justification',
+ },
+ 'data.seq_ssp.q1': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_ssp.q1',
+ },
+ 'data.seq_ssp.q2': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_ssp.q2',
+ },
+ 'data.seq_ssp.q3': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_ssp.q3',
+ },
+ 'data.seq_ssp.q4': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_ssp.q4',
+ },
+ 'data.seq_ssp.year': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_ssp.year',
+ },
+ 'data.seq_ssp.justification': {
+ color_type: greenColumn,
+ accessorKey: 'data.seq_ssp.justification',
+ },
+ 'data.approved.q1': {
+ color_type: greenColumn,
+ accessorKey: 'data.approved.q1',
+ },
+ 'data.approved.q2': {
+ color_type: greenColumn,
+ accessorKey: 'data.approved.q2',
+ },
+ 'data.approved.q3': {
+ color_type: greenColumn,
+ accessorKey: 'data.approved.q3',
+ },
+ 'data.approved.q4': {
+ color_type: greenColumn,
+ accessorKey: 'data.approved.q4',
+ },
+ 'data.approved.year': {
+ color_type: greenColumn,
+ accessorKey: 'data.approved.year',
+ },
+ 'data.contract.counterparty': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.counterparty',
+ },
+ 'data.contract.reference': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.reference',
+ },
+ 'data.contract.date': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.date',
+ },
+ 'data.contract.subject': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.subject',
+ },
+ 'data.contract.currency': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.currency',
+ },
+ 'data.contract.ceiling': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.ceiling',
+ },
+ 'data.contract.vat_rate': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.vat_rate',
+ },
+ 'data.contract.deadline': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.deadline',
+ },
+ 'data.contract.scheme': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.scheme',
+ },
+ 'data.contract.act': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.act',
+ },
+ 'data.contract.comment': {
+ color_type: orangeColumn,
+ accessorKey: 'data.contract.comment',
+ },
+ 'data.booking.y2026.q1': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2026.q1',
+ },
+ 'data.booking.y2026.q2': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2026.q2',
+ },
+ 'data.booking.y2026.q3': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2026.q3',
+ },
+ 'data.booking.y2026.q4': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2026.q4',
+ },
+ 'data.booking.y2027.q1': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2027.q1',
+ },
+ 'data.booking.y2027.q2': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2027.q2',
+ },
+ 'data.booking.y2027.q3': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2027.q3',
+ },
+ 'data.booking.y2027.q4': {
+ color_type: orangeColumn,
+ accessorKey: 'data.booking.y2027.q4',
+ },
+ 'data.q1.adj_current': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q1.adj_current',
+ },
+ 'data.q1.adj_ssp': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q1.adj_ssp',
+ },
+ 'data.q1.adj_reserve': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q1.adj_reserve',
+ },
+ 'data.q1.adj_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q1.adj_comment',
+ },
+ 'data.q1.corrected_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q1.corrected_plan',
+ },
+ '1_kvartal_2026_goda_field_field': {
+ color_type: whiteColumn,
+ accessorKey: '1_kvartal_2026_goda_field_field',
+ },
+ 'data.q1.pay_date': {
+ color_type: blueColumn,
+ accessorKey: 'data.q1.pay_date',
+ },
+ 'data.q1.pay_amount': {
+ color_type: blueColumn,
+ accessorKey: 'data.q1.pay_amount',
+ },
+ 'data.q1.pay_comment': {
+ color_type: blueColumn,
+ accessorKey: 'data.q1.pay_comment',
+ },
+ 'data.q1.pay_act': {
+ color_type: blueColumn,
+ accessorKey: 'data.q1.pay_act',
+ },
+ 'data.q1.booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q1.booking',
+ },
+ 'data.q1.actual_m1': {
+ color_type: greenColumn,
+ accessorKey: 'data.q1.actual_m1',
+ },
+ 'data.q1.actual_m2': {
+ color_type: greenColumn,
+ accessorKey: 'data.q1.actual_m2',
+ },
+ 'data.q1.actual_m3': {
+ color_type: greenColumn,
+ accessorKey: 'data.q1.actual_m3',
+ },
+ 'data.q1.actual_quarter': {
+ color_type: greenColumn,
+ accessorKey: 'data.q1.actual_quarter',
+ },
+ 'data.q1.residual_after_booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q1.residual_after_booking',
+ },
+ 'data.q1.residual_after_actual': {
+ color_type: greenColumn,
+ accessorKey: 'data.q1.residual_after_actual',
+ },
+ 'data.q1.transfer_q2': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_q2',
+ },
+ 'data.q1.transfer_q2_delay_acts': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_q2_delay_acts',
+ },
+ 'data.q1.transfer_q2_delay_procurement': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_q2_delay_procurement',
+ },
+ 'data.q1.transfer_q2_economy_rf': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_q2_economy_rf',
+ },
+ 'data.q1.transfer_next_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_next_comment',
+ },
+ 'data.q1.transfer_q3': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_q3',
+ },
+ 'data.q1.transfer_q4': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_q4',
+ },
+ 'data.q1.transfer_far_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_far_comment',
+ },
+ 'data.q1.transfer_econ': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.transfer_econ',
+ },
+ 'data.q1.total': {
+ color_type: redColumn,
+ accessorKey: 'data.q1.total',
+ },
+ 'data.q2.target_change': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.target_change',
+ },
+ 'data.q2.base_correction': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.base_correction',
+ },
+ 'data.q2.base_correction_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.base_correction_comment',
+ },
+ 'data.q2.revision_inc': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.revision_inc',
+ },
+ 'data.q2.revision_seq': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.revision_seq',
+ },
+ 'data.q2.revision_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.revision_comment',
+ },
+ 'data.q2.new_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.new_plan',
+ },
+ '2_kvartal_2026_goda_field_field': {
+ color_type: whiteColumn,
+ accessorKey: '2_kvartal_2026_goda_field_field',
+ },
+ 'data.q2.adj_current': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.adj_current',
+ },
+ 'data.q2.adj_ssp': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.adj_ssp',
+ },
+ 'data.q2.adj_reserve': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.adj_reserve',
+ },
+ 'data.q2.adj_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.adj_comment',
+ },
+ 'data.q2.corrected_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q2.corrected_plan',
+ },
+ 'data.q2.pay_date': {
+ color_type: blueColumn,
+ accessorKey: 'data.q2.pay_date',
+ },
+ 'data.q2.pay_amount': {
+ color_type: blueColumn,
+ accessorKey: 'data.q2.pay_amount',
+ },
+ 'data.q2.pay_comment': {
+ color_type: blueColumn,
+ accessorKey: 'data.q2.pay_comment',
+ },
+ 'data.q2.pay_act': {
+ color_type: blueColumn,
+ accessorKey: 'data.q2.pay_act',
+ },
+ 'data.q2.booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q2.booking',
+ },
+ 'data.q2.actual_m1': {
+ color_type: greenColumn,
+ accessorKey: 'data.q2.actual_m1',
+ },
+ 'data.q2.actual_m2': {
+ color_type: greenColumn,
+ accessorKey: 'data.q2.actual_m2',
+ },
+ 'data.q2.actual_m3': {
+ color_type: greenColumn,
+ accessorKey: 'data.q2.actual_m3',
+ },
+ 'data.q2.actual_quarter': {
+ color_type: greenColumn,
+ accessorKey: 'data.q2.actual_quarter',
+ },
+ 'data.q2.residual_after_booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q2.residual_after_booking',
+ },
+ 'data.q2.residual_after_actual': {
+ color_type: greenColumn,
+ accessorKey: 'data.q2.residual_after_actual',
+ },
+ 'data.q2.transfer_q3': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_q3',
+ },
+ 'data.q2.transfer_q3_delay_acts': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_q3_delay_acts',
+ },
+ 'data.q2.transfer_q3_delay_procurement': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_q3_delay_procurement',
+ },
+ 'data.q2.transfer_q3_economy_rf': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_q3_economy_rf',
+ },
+ 'data.q2.transfer_next_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_next_comment',
+ },
+ 'data.q2.transfer_q4': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_q4',
+ },
+ 'data.q2.transfer_far_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_far_comment',
+ },
+ 'data.q2.transfer_econ': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.transfer_econ',
+ },
+ 'data.q2.total': {
+ color_type: redColumn,
+ accessorKey: 'data.q2.total',
+ },
+ 'data.q3.target_change': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.target_change',
+ },
+ 'data.q3.base_correction': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.base_correction',
+ },
+ 'data.q3.base_correction_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.base_correction_comment',
+ },
+ 'data.q3.revision_inc': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.revision_inc',
+ },
+ 'data.q3.revision_seq': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.revision_seq',
+ },
+ 'data.q3.revision_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.revision_comment',
+ },
+ 'data.q3.new_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.new_plan',
+ },
+ '3_kvartal_2026_goda_field_field': {
+ color_type: whiteColumn,
+ accessorKey: '3_kvartal_2026_goda_field_field',
+ },
+ 'data.q3.adj_current': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.adj_current',
+ },
+ 'data.q3.adj_ssp': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.adj_ssp',
+ },
+ 'data.q3.adj_reserve': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.adj_reserve',
+ },
+ 'data.q3.adj_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.adj_comment',
+ },
+ 'data.q3.corrected_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q3.corrected_plan',
+ },
+ 'data.q3.pay_date': {
+ color_type: blueColumn,
+ accessorKey: 'data.q3.pay_date',
+ },
+ 'data.q3.pay_amount': {
+ color_type: blueColumn,
+ accessorKey: 'data.q3.pay_amount',
+ },
+ 'data.q3.pay_comment': {
+ color_type: blueColumn,
+ accessorKey: 'data.q3.pay_comment',
+ },
+ 'data.q3.pay_act': {
+ color_type: blueColumn,
+ accessorKey: 'data.q3.pay_act',
+ },
+ 'data.q3.booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q3.booking',
+ },
+ 'data.q3.actual_m1': {
+ color_type: greenColumn,
+ accessorKey: 'data.q3.actual_m1',
+ },
+ 'data.q3.actual_m2': {
+ color_type: greenColumn,
+ accessorKey: 'data.q3.actual_m2',
+ },
+ 'data.q3.actual_m3': {
+ color_type: greenColumn,
+ accessorKey: 'data.q3.actual_m3',
+ },
+ 'data.q3.actual_quarter': {
+ color_type: greenColumn,
+ accessorKey: 'data.q3.actual_quarter',
+ },
+ 'data.q3.residual_after_booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q3.residual_after_booking',
+ },
+ 'data.q3.residual_after_actual': {
+ color_type: greenColumn,
+ accessorKey: 'data.q3.residual_after_actual',
+ },
+ 'data.q3.transfer_q4': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.transfer_q4',
+ },
+ 'data.q3.transfer_q4_delay_acts': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.transfer_q4_delay_acts',
+ },
+ 'data.q3.transfer_q4_delay_procurement': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.transfer_q4_delay_procurement',
+ },
+ 'data.q3.transfer_q4_economy_rf': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.transfer_q4_economy_rf',
+ },
+ 'data.q3.transfer_next_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.transfer_next_comment',
+ },
+ 'data.q3.transfer_econ': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.transfer_econ',
+ },
+ 'data.q3.total': {
+ color_type: redColumn,
+ accessorKey: 'data.q3.total',
+ },
+ 'data.q4.target_change': {
+ color_type: redColumn,
+ accessorKey: 'data.q4.target_change',
+ },
+ 'data.q4.base_correction': {
+ color_type: redColumn,
+ accessorKey: 'data.q4.base_correction',
+ },
+ 'data.q4.base_correction_comment': {
+ color_type: redColumn,
+ accessorKey: 'data.q4.base_correction_comment',
+ },
+ 'data.q4.revision_inc': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.revision_inc',
+ },
+ 'data.q4.revision_seq': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.revision_seq',
+ },
+ 'data.q4.revision_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.revision_comment',
+ },
+ 'data.q4.new_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.new_plan',
+ },
+ '4_kvartal_2026_goda_field_field': {
+ color_type: whiteColumn,
+ accessorKey: '4_kvartal_2026_goda_field_field',
+ },
+ 'data.q4.adj_current': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.adj_current',
+ },
+ 'data.q4.adj_ssp': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.adj_ssp',
+ },
+ 'data.q4.adj_reserve': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.adj_reserve',
+ },
+ 'data.q4.adj_comment': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.adj_comment',
+ },
+ 'data.q4.corrected_plan': {
+ color_type: yellowColumn,
+ accessorKey: 'data.q4.corrected_plan',
+ },
+ 'data.q4.pay_date': {
+ color_type: blueColumn,
+ accessorKey: 'data.q4.pay_date',
+ },
+ 'data.q4.pay_amount': {
+ color_type: blueColumn,
+ accessorKey: 'data.q4.pay_amount',
+ },
+ 'data.q4.pay_comment': {
+ color_type: blueColumn,
+ accessorKey: 'data.q4.pay_comment',
+ },
+ 'data.q4.pay_act': {
+ color_type: blueColumn,
+ accessorKey: 'data.q4.pay_act',
+ },
+ 'data.q4.booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q4.booking',
+ },
+ 'data.q4.actual_m1': {
+ color_type: greenColumn,
+ accessorKey: 'data.q4.actual_m1',
+ },
+ 'data.q4.actual_m2': {
+ color_type: greenColumn,
+ accessorKey: 'data.q4.actual_m2',
+ },
+ 'data.q4.actual_m3': {
+ color_type: greenColumn,
+ accessorKey: 'data.q4.actual_m3',
+ },
+ 'data.q4.actual_spod': {
+ color_type: greenColumn,
+ accessorKey: 'data.q4.actual_spod',
+ },
+ 'data.q4.actual_quarter': {
+ color_type: greenColumn,
+ accessorKey: 'data.q4.actual_quarter',
+ },
+ 'data.q4.residual_after_booking': {
+ color_type: orangeColumn,
+ accessorKey: 'data.q4.residual_after_booking',
+ },
+ 'data.q4.residual_after_actual': {
+ color_type: greenColumn,
+ accessorKey: 'data.q4.residual_after_actual',
+ },
+ 'data.q4.transfer_econ': {
+ color_type: redColumn,
+ accessorKey: 'data.q4.transfer_econ',
+ },
+ 'data.totals.fact_year': {
+ color_type: greenColumn,
+ accessorKey: 'data.totals.fact_year',
+ },
+ '2026_god_field_field_5': {
+ color_type: whiteColumn,
+ accessorKey: '2026_god_field_field_5',
+ },
+ 'data.totals.pay_year': {
+ color_type: blueColumn,
+ accessorKey: 'data.totals.pay_year',
+ },
+ },
+ columns: [
+ {
+ header: ' ',
+ accessorKey: 'field',
+ columns: [
+ {
+ header: ' ',
+ accessorKey: 'field_field',
+ columns: [
+ {
+ header: 'Код раздела',
+ accessorKey: 'data.header.section_code',
+ columnLetter: 'A',
+ size: 150,
+ filterFn: 'contains',
+ },
+ {
+ header: 'ID статьи',
+ accessorKey: 'data.header.item_id',
+ columnLetter: 'B',
+ size: 150,
+ filterFn: 'contains',
+ },
+ {
+ header: 'ID группы номенклатуры',
+ accessorKey: 'data.header.num_group',
+ columnLetter: 'C',
+ size: 220,
+ filterFn: 'contains',
+ },
+ {
+ header: 'Наименование',
+ accessorKey: 'data.header.name',
+ columnLetter: 'D',
+ size: 150,
+ filterFn: 'contains',
+ },
+ {
+ header: 'ВСП РФ',
+ accessorKey: 'data.header.vsp_id',
+ columnLetter: 'E',
+ size: 150,
+ filterFn: 'contains',
+ editType: 'vsp_dropdown',
+ },
+ {
+ header: 'Адрес ВСП',
+ accessorKey: 'data.header.vsp_address',
+ columnLetter: 'E1',
+ size: 220,
+ filterFn: 'contains',
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2026 год',
+ accessorKey: '2026_god',
+ columns: [
+ {
+ header: 'Планирование годовых показателей',
+ accessorKey: '2026_god_planirovanie_godovykh_pokazateley',
+ columns: [
+ {
+ header: '1 квартал',
+ accessorKey: 'data.plan.q1',
+ columnLetter: 'F',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2 квартал',
+ accessorKey: 'data.plan.q2',
+ columnLetter: 'G',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '3 квартал',
+ accessorKey: 'data.plan.q3',
+ columnLetter: 'H',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '4 квартал',
+ accessorKey: 'data.plan.q4',
+ columnLetter: 'I',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Год',
+ accessorKey: 'data.plan.year',
+ columnLetter: 'J',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.plan.comment',
+ columnLetter: 'K',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
- {
- header: "Секвестирование ДФиП",
- accessorKey: "2026_god_sekvestirovanie_dfip",
- columns: [
- {
- header: "1 квартал",
- accessorKey: "data.seq_dfip.q1",
- columnLetter: "M",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2 квартал",
- accessorKey: "data.seq_dfip.q2",
- columnLetter: "N",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "3 квартал",
- accessorKey: "data.seq_dfip.q3",
- columnLetter: "O",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "4 квартал",
- accessorKey: "data.seq_dfip.q4",
- columnLetter: "P",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Год",
- accessorKey: "data.seq_dfip.year",
- columnLetter: "Q",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Обоснование",
- accessorKey: "data.seq_dfip.justification",
- columnLetter: "R",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Секвестирование ССП ГО",
- accessorKey: "2026_god_sekvestirovanie_ssp_go",
- columns: [
- {
- header: "1 квартал",
- accessorKey: "data.seq_ssp.q1",
- columnLetter: "T",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2 квартал",
- accessorKey: "data.seq_ssp.q2",
- columnLetter: "U",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "3 квартал",
- accessorKey: "data.seq_ssp.q3",
- columnLetter: "V",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "4 квартал",
- accessorKey: "data.seq_ssp.q4",
- columnLetter: "W",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Год",
- accessorKey: "data.seq_ssp.year",
- columnLetter: "X",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Обоснование",
- accessorKey: "data.seq_ssp.justification",
- columnLetter: "Y",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Утвержденная смета расходов",
- accessorKey: "2026_god_utverzhdennaya_smeta_raskhodov",
- columns: [
- {
- header: "1 квартал",
- accessorKey: "data.approved.q1",
- columnLetter: "AA",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2 квартал",
- accessorKey: "data.approved.q2",
- columnLetter: "AB",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "3 квартал",
- accessorKey: "data.approved.q3",
- columnLetter: "AC",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "4 квартал",
- accessorKey: "data.approved.q4",
- columnLetter: "AD",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Год",
- accessorKey: "data.approved.year",
- columnLetter: "AE",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Параметры заключенного хозяйственного договора",
- accessorKey:
- "2026_god_parametry_zaklyuchennogo_khozyaystvennogo_dogovora",
- columns: [
- {
- header: "Контрагент",
- accessorKey: "data.contract.counterparty",
- columnLetter: "AG",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Номер",
- accessorKey: "data.contract.reference",
- columnLetter: "AH",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Дата",
- accessorKey: "data.contract.date",
- columnLetter: "AI",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Предмет",
- accessorKey: "data.contract.subject",
- columnLetter: "AJ",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Валюта",
- accessorKey: "data.contract.currency",
- columnLetter: "AK",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Предельная стоимость",
- accessorKey: "data.contract.ceiling",
- columnLetter: "AL",
- size: 200,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Ставка НДС (%)",
- accessorKey: "data.contract.vat_rate",
- columnLetter: "AM",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Срок",
- accessorKey: "data.contract.deadline",
- columnLetter: "AN",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Схема платежа",
- accessorKey: "data.contract.scheme",
- columnLetter: "AO",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "АКТ",
- accessorKey: "data.contract.act",
- columnLetter: "AP",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.contract.comment",
- columnLetter: "AQ",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств в 1 квартале",
- accessorKey: "data.booking.y2026.q1",
- columnLetter: "AR",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств во 2 квартале",
- accessorKey: "data.booking.y2026.q2",
- columnLetter: "AS",
- size: 270,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств в 3 квартале",
- accessorKey: "data.booking.y2026.q3",
- columnLetter: "AT",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств в 4 квартале",
- accessorKey: "data.booking.y2026.q4",
- columnLetter: "AU",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2027 год",
- accessorKey: "2027_god",
- columns: [
- {
- header: "",
- accessorKey: "2027_god_field",
- columns: [
- {
- header: "Бронь средств в 1 квартале",
- accessorKey: "data.booking.y2027.q1",
- columnLetter: "AV",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств во 2 квартале",
- accessorKey: "data.booking.y2027.q2",
- columnLetter: "AW",
- size: 270,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств в 3 квартале",
- accessorKey: "data.booking.y2027.q3",
- columnLetter: "AX",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Бронь средств в 4 квартале",
- accessorKey: "data.booking.y2027.q4",
- columnLetter: "AY",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "1 квартал 2026 года",
- accessorKey: "1_kvartal_2026_goda",
- columns: [
- {
- header: "Корректировки плановых значений",
- accessorKey:
- "1_kvartal_2026_goda_korrektirovki_planovykh_znacheniy",
- columns: [
- {
- header: "Текущие (= 0)",
- accessorKey: "data.q1.adj_current",
- columnLetter: "BA",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз сметы ГО",
- accessorKey: "data.q1.adj_ssp",
- columnLetter: "BB",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз резерва",
- accessorKey: "data.q1.adj_reserve",
- columnLetter: "BC",
- size: 180,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q1.adj_comment",
- columnLetter: "BD",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Базовый план с учетом корректировок",
- accessorKey: "data.q1.corrected_plan",
- columnLetter: "BE",
- size: 350,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
+ {
+ header: 'Секвестирование ДФиП',
+ accessorKey: '2026_god_sekvestirovanie_dfip',
+ columns: [
+ {
+ header: '1 квартал',
+ accessorKey: 'data.seq_dfip.q1',
+ columnLetter: 'M',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2 квартал',
+ accessorKey: 'data.seq_dfip.q2',
+ columnLetter: 'N',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '3 квартал',
+ accessorKey: 'data.seq_dfip.q3',
+ columnLetter: 'O',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '4 квартал',
+ accessorKey: 'data.seq_dfip.q4',
+ columnLetter: 'P',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Год',
+ accessorKey: 'data.seq_dfip.year',
+ columnLetter: 'Q',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Обоснование',
+ accessorKey: 'data.seq_dfip.justification',
+ columnLetter: 'R',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Секвестирование ССП ГО',
+ accessorKey: '2026_god_sekvestirovanie_ssp_go',
+ columns: [
+ {
+ header: '1 квартал',
+ accessorKey: 'data.seq_ssp.q1',
+ columnLetter: 'T',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2 квартал',
+ accessorKey: 'data.seq_ssp.q2',
+ columnLetter: 'U',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '3 квартал',
+ accessorKey: 'data.seq_ssp.q3',
+ columnLetter: 'V',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '4 квартал',
+ accessorKey: 'data.seq_ssp.q4',
+ columnLetter: 'W',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Год',
+ accessorKey: 'data.seq_ssp.year',
+ columnLetter: 'X',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Обоснование',
+ accessorKey: 'data.seq_ssp.justification',
+ columnLetter: 'Y',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Утвержденная смета расходов',
+ accessorKey: '2026_god_utverzhdennaya_smeta_raskhodov',
+ columns: [
+ {
+ header: '1 квартал',
+ accessorKey: 'data.approved.q1',
+ columnLetter: 'AA',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2 квартал',
+ accessorKey: 'data.approved.q2',
+ columnLetter: 'AB',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '3 квартал',
+ accessorKey: 'data.approved.q3',
+ columnLetter: 'AC',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '4 квартал',
+ accessorKey: 'data.approved.q4',
+ columnLetter: 'AD',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Год',
+ accessorKey: 'data.approved.year',
+ columnLetter: 'AE',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Параметры заключенного хозяйственного договора',
+ accessorKey: '2026_god_parametry_zaklyuchennogo_khozyaystvennogo_dogovora',
+ columns: [
+ {
+ header: 'Контрагент',
+ accessorKey: 'data.contract.counterparty',
+ columnLetter: 'AG',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Номер',
+ accessorKey: 'data.contract.reference',
+ columnLetter: 'AH',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Дата',
+ accessorKey: 'data.contract.date',
+ columnLetter: 'AI',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Предмет',
+ accessorKey: 'data.contract.subject',
+ columnLetter: 'AJ',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Валюта',
+ accessorKey: 'data.contract.currency',
+ columnLetter: 'AK',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Предельная стоимость',
+ accessorKey: 'data.contract.ceiling',
+ columnLetter: 'AL',
+ size: 200,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Ставка НДС (%)',
+ accessorKey: 'data.contract.vat_rate',
+ columnLetter: 'AM',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Срок',
+ accessorKey: 'data.contract.deadline',
+ columnLetter: 'AN',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Схема платежа',
+ accessorKey: 'data.contract.scheme',
+ columnLetter: 'AO',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'АКТ',
+ accessorKey: 'data.contract.act',
+ columnLetter: 'AP',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.contract.comment',
+ columnLetter: 'AQ',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств в 1 квартале',
+ accessorKey: 'data.booking.y2026.q1',
+ columnLetter: 'AR',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств во 2 квартале',
+ accessorKey: 'data.booking.y2026.q2',
+ columnLetter: 'AS',
+ size: 270,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств в 3 квартале',
+ accessorKey: 'data.booking.y2026.q3',
+ columnLetter: 'AT',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств в 4 квартале',
+ accessorKey: 'data.booking.y2026.q4',
+ columnLetter: 'AU',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2027 год',
+ accessorKey: '2027_god',
+ columns: [
+ {
+ header: '',
+ accessorKey: '2027_god_field',
+ columns: [
+ {
+ header: 'Бронь средств в 1 квартале',
+ accessorKey: 'data.booking.y2027.q1',
+ columnLetter: 'AV',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств во 2 квартале',
+ accessorKey: 'data.booking.y2027.q2',
+ columnLetter: 'AW',
+ size: 270,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств в 3 квартале',
+ accessorKey: 'data.booking.y2027.q3',
+ columnLetter: 'AX',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Бронь средств в 4 квартале',
+ accessorKey: 'data.booking.y2027.q4',
+ columnLetter: 'AY',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '1 квартал 2026 года',
+ accessorKey: '1_kvartal_2026_goda',
+ columns: [
+ {
+ header: 'Корректировки плановых значений',
+ accessorKey: '1_kvartal_2026_goda_korrektirovki_planovykh_znacheniy',
+ columns: [
+ {
+ header: 'Текущие (= 0)',
+ accessorKey: 'data.q1.adj_current',
+ columnLetter: 'BA',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз сметы ГО',
+ accessorKey: 'data.q1.adj_ssp',
+ columnLetter: 'BB',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз резерва',
+ accessorKey: 'data.q1.adj_reserve',
+ columnLetter: 'BC',
+ size: 180,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q1.adj_comment',
+ columnLetter: 'BD',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Базовый план с учетом корректировок',
+ accessorKey: 'data.q1.corrected_plan',
+ columnLetter: 'BE',
+ size: 350,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
- {
- header: "Согласование платежей",
- accessorKey: "1_kvartal_2026_goda_soglasovanie_platezhey",
- columns: [
- {
- header: "Дата платежа",
- accessorKey: "data.q1.pay_date",
- columnLetter: "BG",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Сумма платежа",
- accessorKey: "data.q1.pay_amount",
- columnLetter: "BH",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q1.pay_comment",
- columnLetter: "BI",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Предоставление акта",
- accessorKey: "data.q1.pay_act",
- columnLetter: "BJ",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Фактические расходы",
- accessorKey: "1_kvartal_2026_goda_fakticheskie_raskhody",
- columns: [
- {
- header: "Бронь1 квартал",
- accessorKey: "data.q1.booking",
- columnLetter: "BL",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактЯнварь",
- accessorKey: "data.q1.actual_m1",
- columnLetter: "BM",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактФевраль",
- accessorKey: "data.q1.actual_m2",
- columnLetter: "BN",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактМарт",
- accessorKey: "data.q1.actual_m3",
- columnLetter: "BO",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Факт1 квартал",
- accessorKey: "data.q1.actual_quarter",
- columnLetter: "BP",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после брони 1 квартала",
- accessorKey: "data.q1.residual_after_booking",
- columnLetter: "BQ",
- size: 300,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после факта 1 квартала",
- accessorKey: "data.q1.residual_after_actual",
- columnLetter: "BR",
- size: 300,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректировка остатка в последующие кварталы",
- accessorKey:
- "1_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly",
- columns: [
- {
- header: "Перенос во 2 квартал",
- accessorKey: "data.q1.transfer_q2",
- columnLetter: "BT",
- size: 200,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Задержка списания расходов / предоставления актов",
- accessorKey: "data.q1.transfer_q2_delay_acts",
- columnLetter: "BU",
- size: 490,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Задержка закупочных процедур",
- accessorKey: "data.q1.transfer_q2_delay_procurement",
- columnLetter: "BV",
- size: 280,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "экономия (будет использована РФ)",
- accessorKey: "data.q1.transfer_q2_economy_rf",
- columnLetter: "BW",
- size: 320,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий переноса во2 квартал",
- accessorKey: "data.q1.transfer_next_comment",
- columnLetter: "BX",
- size: 330,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Перенос в 3 квартал",
- accessorKey: "data.q1.transfer_q3",
- columnLetter: "BY",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Перенос в 4 квартал",
- accessorKey: "data.q1.transfer_q4",
- columnLetter: "BZ",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий переноса в3 и 4 квартал",
- accessorKey: "data.q1.transfer_far_comment",
- columnLetter: "CA",
- size: 360,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Перенос в фонд экономии",
- accessorKey: "data.q1.transfer_econ",
- columnLetter: "CB",
- size: 230,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "ВСЕГО",
- accessorKey: "data.q1.total",
- columnLetter: "CC",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2 квартал 2026 года",
- accessorKey: "2_kvartal_2026_goda",
- columns: [
- {
- header: "Корректировка базового плана",
- accessorKey: "2_kvartal_2026_goda_korrektirovka_bazovogo_plana",
- columns: [
- {
- header:
- "Изменение целевого назначения перенесенной экономии (= 0)",
- accessorKey: "data.q2.target_change",
- columnLetter: "CE",
- size: 250,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Корректировка статей базового плана (= 0)",
- accessorKey: "data.q2.base_correction",
- columnLetter: "CF",
- size: 410,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий изменения базового плана",
- accessorKey: "data.q2.base_correction_comment",
- columnLetter: "CG",
- size: 360,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "ДФиПУвеличение плана (> 0)",
- accessorKey: "data.q2.revision_inc",
- columnLetter: "CH",
- size: 270,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "ДФиПCеквестр плана (< 0)",
- accessorKey: "data.q2.revision_seq",
- columnLetter: "CI",
- size: 250,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q2.revision_comment",
- columnLetter: "CJ",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Скорректированный план на подпись",
- accessorKey: "data.q2.new_plan",
- columnLetter: "CK",
- size: 330,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
+ {
+ header: 'Согласование платежей',
+ accessorKey: '1_kvartal_2026_goda_soglasovanie_platezhey',
+ columns: [
+ {
+ header: 'Дата платежа',
+ accessorKey: 'data.q1.pay_date',
+ columnLetter: 'BG',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Сумма платежа',
+ accessorKey: 'data.q1.pay_amount',
+ columnLetter: 'BH',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q1.pay_comment',
+ columnLetter: 'BI',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Предоставление акта',
+ accessorKey: 'data.q1.pay_act',
+ columnLetter: 'BJ',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Фактические расходы',
+ accessorKey: '1_kvartal_2026_goda_fakticheskie_raskhody',
+ columns: [
+ {
+ header: 'Бронь1 квартал',
+ accessorKey: 'data.q1.booking',
+ columnLetter: 'BL',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактЯнварь',
+ accessorKey: 'data.q1.actual_m1',
+ columnLetter: 'BM',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактФевраль',
+ accessorKey: 'data.q1.actual_m2',
+ columnLetter: 'BN',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактМарт',
+ accessorKey: 'data.q1.actual_m3',
+ columnLetter: 'BO',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Факт1 квартал',
+ accessorKey: 'data.q1.actual_quarter',
+ columnLetter: 'BP',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после брони 1 квартала',
+ accessorKey: 'data.q1.residual_after_booking',
+ columnLetter: 'BQ',
+ size: 300,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после факта 1 квартала',
+ accessorKey: 'data.q1.residual_after_actual',
+ columnLetter: 'BR',
+ size: 300,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректировка остатка в последующие кварталы',
+ accessorKey: '1_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly',
+ columns: [
+ {
+ header: 'Перенос во 2 квартал',
+ accessorKey: 'data.q1.transfer_q2',
+ columnLetter: 'BT',
+ size: 200,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Задержка списания расходов / предоставления актов',
+ accessorKey: 'data.q1.transfer_q2_delay_acts',
+ columnLetter: 'BU',
+ size: 490,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Задержка закупочных процедур',
+ accessorKey: 'data.q1.transfer_q2_delay_procurement',
+ columnLetter: 'BV',
+ size: 280,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'экономия (будет использована РФ)',
+ accessorKey: 'data.q1.transfer_q2_economy_rf',
+ columnLetter: 'BW',
+ size: 320,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий переноса во2 квартал',
+ accessorKey: 'data.q1.transfer_next_comment',
+ columnLetter: 'BX',
+ size: 330,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Перенос в 3 квартал',
+ accessorKey: 'data.q1.transfer_q3',
+ columnLetter: 'BY',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Перенос в 4 квартал',
+ accessorKey: 'data.q1.transfer_q4',
+ columnLetter: 'BZ',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий переноса в3 и 4 квартал',
+ accessorKey: 'data.q1.transfer_far_comment',
+ columnLetter: 'CA',
+ size: 360,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Перенос в фонд экономии',
+ accessorKey: 'data.q1.transfer_econ',
+ columnLetter: 'CB',
+ size: 230,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'ВСЕГО',
+ accessorKey: 'data.q1.total',
+ columnLetter: 'CC',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2 квартал 2026 года',
+ accessorKey: '2_kvartal_2026_goda',
+ columns: [
+ {
+ header: 'Корректировка базового плана',
+ accessorKey: '2_kvartal_2026_goda_korrektirovka_bazovogo_plana',
+ columns: [
+ {
+ header: 'Изменение целевого назначения перенесенной экономии (= 0)',
+ accessorKey: 'data.q2.target_change',
+ columnLetter: 'CE',
+ size: 250,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Корректировка статей базового плана (= 0)',
+ accessorKey: 'data.q2.base_correction',
+ columnLetter: 'CF',
+ size: 410,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий изменения базового плана',
+ accessorKey: 'data.q2.base_correction_comment',
+ columnLetter: 'CG',
+ size: 360,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'ДФиПУвеличение плана (> 0)',
+ accessorKey: 'data.q2.revision_inc',
+ columnLetter: 'CH',
+ size: 270,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ДФиПCеквестр плана (< 0)',
+ accessorKey: 'data.q2.revision_seq',
+ columnLetter: 'CI',
+ size: 250,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q2.revision_comment',
+ columnLetter: 'CJ',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Скорректированный план на подпись',
+ accessorKey: 'data.q2.new_plan',
+ columnLetter: 'CK',
+ size: 330,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
- {
- header: "Корректировки плановых значений",
- accessorKey:
- "2_kvartal_2026_goda_korrektirovki_planovykh_znacheniy",
- columns: [
- {
- header: "Текущие (= 0)",
- accessorKey: "data.q2.adj_current",
- columnLetter: "CM",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз сметы ГО",
- accessorKey: "data.q2.adj_ssp",
- columnLetter: "CN",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз резерва",
- accessorKey: "data.q2.adj_reserve",
- columnLetter: "CO",
- size: 180,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q2.adj_comment",
- columnLetter: "CP",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Скорректированный план с учетом корректировок",
- accessorKey: "data.q2.corrected_plan",
- columnLetter: "CQ",
- size: 450,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Согласование платежей",
- accessorKey: "2_kvartal_2026_goda_soglasovanie_platezhey",
- columns: [
- {
- header: "Дата платежа",
- accessorKey: "data.q2.pay_date",
- columnLetter: "CS",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Сумма платежа",
- accessorKey: "data.q2.pay_amount",
- columnLetter: "CT",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q2.pay_comment",
- columnLetter: "CU",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Предоставление акта",
- accessorKey: "data.q2.pay_act",
- columnLetter: "CV",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Фактические расходы",
- accessorKey: "2_kvartal_2026_goda_fakticheskie_raskhody",
- columns: [
- {
- header: "Бронь2 квартал",
- accessorKey: "data.q2.booking",
- columnLetter: "CX",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактАпрель",
- accessorKey: "data.q2.actual_m1",
- columnLetter: "CY",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактМай",
- accessorKey: "data.q2.actual_m2",
- columnLetter: "CZ",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактИюнь",
- accessorKey: "data.q2.actual_m3",
- columnLetter: "DA",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Факт2 квартал",
- accessorKey: "data.q2.actual_quarter",
- columnLetter: "DB",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после брони 2 квартала",
- accessorKey: "data.q2.residual_after_booking",
- columnLetter: "DC",
- size: 300,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после факта 2 квартала",
- accessorKey: "data.q2.residual_after_actual",
- columnLetter: "DD",
- size: 300,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректировка остатка в последующие кварталы",
- accessorKey:
- "2_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly",
- columns: [
- {
- header: "Перенос в 3 квартал",
- accessorKey: "data.q2.transfer_q3",
- columnLetter: "DF",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Задержка списания расходов / предоставления актов",
- accessorKey: "data.q2.transfer_q3_delay_acts",
- columnLetter: "DG",
- size: 490,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Задержка закупочных процедур",
- accessorKey: "data.q2.transfer_q3_delay_procurement",
- columnLetter: "DH",
- size: 280,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "экономия (будет использована РФ)",
- accessorKey: "data.q2.transfer_q3_economy_rf",
- columnLetter: "DI",
- size: 320,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий переноса в3 квартал",
- accessorKey: "data.q2.transfer_next_comment",
- columnLetter: "DJ",
- size: 320,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Перенос в 4 квартал",
- accessorKey: "data.q2.transfer_q4",
- columnLetter: "DK",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий переноса в4 квартал",
- accessorKey: "data.q2.transfer_far_comment",
- columnLetter: "DL",
- size: 320,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Перенос в фонд экономии",
- accessorKey: "data.q2.transfer_econ",
- columnLetter: "DM",
- size: 230,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "ВСЕГО",
- accessorKey: "data.q2.total",
- columnLetter: "DN",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "3 квартал 2026 года",
- accessorKey: "3_kvartal_2026_goda",
- columns: [
- {
- header: "Корректировка базового плана",
- accessorKey: "3_kvartal_2026_goda_korrektirovka_bazovogo_plana",
- columns: [
- {
- header:
- "Изменение целевого назначения перенесенной экономии (= 0)",
- accessorKey: "data.q3.target_change",
- columnLetter: "DP",
- size: 250,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Корректировка статей базового плана (= 0)",
- accessorKey: "data.q3.base_correction",
- columnLetter: "DQ",
- size: 410,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий изменения базового плана",
- accessorKey: "data.q3.base_correction_comment",
- columnLetter: "DR",
- size: 360,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "ДФиПУвеличение плана (> 0)",
- accessorKey: "data.q3.revision_inc",
- columnLetter: "DS",
- size: 270,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "ДФиПCеквестр плана (< 0)",
- accessorKey: "data.q3.revision_seq",
- columnLetter: "DT",
- size: 250,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q3.revision_comment",
- columnLetter: "DU",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Скорректированный план на подпись",
- accessorKey: "data.q3.new_plan",
- columnLetter: "DV",
- size: 330,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
+ {
+ header: 'Корректировки плановых значений',
+ accessorKey: '2_kvartal_2026_goda_korrektirovki_planovykh_znacheniy',
+ columns: [
+ {
+ header: 'Текущие (= 0)',
+ accessorKey: 'data.q2.adj_current',
+ columnLetter: 'CM',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз сметы ГО',
+ accessorKey: 'data.q2.adj_ssp',
+ columnLetter: 'CN',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз резерва',
+ accessorKey: 'data.q2.adj_reserve',
+ columnLetter: 'CO',
+ size: 180,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q2.adj_comment',
+ columnLetter: 'CP',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Скорректированный план с учетом корректировок',
+ accessorKey: 'data.q2.corrected_plan',
+ columnLetter: 'CQ',
+ size: 450,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Согласование платежей',
+ accessorKey: '2_kvartal_2026_goda_soglasovanie_platezhey',
+ columns: [
+ {
+ header: 'Дата платежа',
+ accessorKey: 'data.q2.pay_date',
+ columnLetter: 'CS',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Сумма платежа',
+ accessorKey: 'data.q2.pay_amount',
+ columnLetter: 'CT',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q2.pay_comment',
+ columnLetter: 'CU',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Предоставление акта',
+ accessorKey: 'data.q2.pay_act',
+ columnLetter: 'CV',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Фактические расходы',
+ accessorKey: '2_kvartal_2026_goda_fakticheskie_raskhody',
+ columns: [
+ {
+ header: 'Бронь2 квартал',
+ accessorKey: 'data.q2.booking',
+ columnLetter: 'CX',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактАпрель',
+ accessorKey: 'data.q2.actual_m1',
+ columnLetter: 'CY',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактМай',
+ accessorKey: 'data.q2.actual_m2',
+ columnLetter: 'CZ',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактИюнь',
+ accessorKey: 'data.q2.actual_m3',
+ columnLetter: 'DA',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Факт2 квартал',
+ accessorKey: 'data.q2.actual_quarter',
+ columnLetter: 'DB',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после брони 2 квартала',
+ accessorKey: 'data.q2.residual_after_booking',
+ columnLetter: 'DC',
+ size: 300,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после факта 2 квартала',
+ accessorKey: 'data.q2.residual_after_actual',
+ columnLetter: 'DD',
+ size: 300,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректировка остатка в последующие кварталы',
+ accessorKey: '2_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschie_kvartaly',
+ columns: [
+ {
+ header: 'Перенос в 3 квартал',
+ accessorKey: 'data.q2.transfer_q3',
+ columnLetter: 'DF',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Задержка списания расходов / предоставления актов',
+ accessorKey: 'data.q2.transfer_q3_delay_acts',
+ columnLetter: 'DG',
+ size: 490,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Задержка закупочных процедур',
+ accessorKey: 'data.q2.transfer_q3_delay_procurement',
+ columnLetter: 'DH',
+ size: 280,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'экономия (будет использована РФ)',
+ accessorKey: 'data.q2.transfer_q3_economy_rf',
+ columnLetter: 'DI',
+ size: 320,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий переноса в3 квартал',
+ accessorKey: 'data.q2.transfer_next_comment',
+ columnLetter: 'DJ',
+ size: 320,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Перенос в 4 квартал',
+ accessorKey: 'data.q2.transfer_q4',
+ columnLetter: 'DK',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий переноса в4 квартал',
+ accessorKey: 'data.q2.transfer_far_comment',
+ columnLetter: 'DL',
+ size: 320,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Перенос в фонд экономии',
+ accessorKey: 'data.q2.transfer_econ',
+ columnLetter: 'DM',
+ size: 230,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'ВСЕГО',
+ accessorKey: 'data.q2.total',
+ columnLetter: 'DN',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '3 квартал 2026 года',
+ accessorKey: '3_kvartal_2026_goda',
+ columns: [
+ {
+ header: 'Корректировка базового плана',
+ accessorKey: '3_kvartal_2026_goda_korrektirovka_bazovogo_plana',
+ columns: [
+ {
+ header: 'Изменение целевого назначения перенесенной экономии (= 0)',
+ accessorKey: 'data.q3.target_change',
+ columnLetter: 'DP',
+ size: 250,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Корректировка статей базового плана (= 0)',
+ accessorKey: 'data.q3.base_correction',
+ columnLetter: 'DQ',
+ size: 410,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий изменения базового плана',
+ accessorKey: 'data.q3.base_correction_comment',
+ columnLetter: 'DR',
+ size: 360,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'ДФиПУвеличение плана (> 0)',
+ accessorKey: 'data.q3.revision_inc',
+ columnLetter: 'DS',
+ size: 270,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ДФиПCеквестр плана (< 0)',
+ accessorKey: 'data.q3.revision_seq',
+ columnLetter: 'DT',
+ size: 250,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q3.revision_comment',
+ columnLetter: 'DU',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Скорректированный план на подпись',
+ accessorKey: 'data.q3.new_plan',
+ columnLetter: 'DV',
+ size: 330,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
- {
- header: "Корректировки плановых значений",
- accessorKey:
- "3_kvartal_2026_goda_korrektirovki_planovykh_znacheniy",
- columns: [
- {
- header: "Текущие (= 0)",
- accessorKey: "data.q3.adj_current",
- columnLetter: "DX",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз сметы ГО",
- accessorKey: "data.q3.adj_ssp",
- columnLetter: "DY",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз резерва",
- accessorKey: "data.q3.adj_reserve",
- columnLetter: "DZ",
- size: 180,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q3.adj_comment",
- columnLetter: "EA",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Скорректированный план с учетом корректировок",
- accessorKey: "data.q3.corrected_plan",
- columnLetter: "EB",
- size: 450,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Согласование платежей",
- accessorKey: "3_kvartal_2026_goda_soglasovanie_platezhey",
- columns: [
- {
- header: "Дата платежа",
- accessorKey: "data.q3.pay_date",
- columnLetter: "ED",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Сумма платежа",
- accessorKey: "data.q3.pay_amount",
- columnLetter: "EE",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q3.pay_comment",
- columnLetter: "EF",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Предоставление акта",
- accessorKey: "data.q3.pay_act",
- columnLetter: "EG",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Фактические расходы",
- accessorKey: "3_kvartal_2026_goda_fakticheskie_raskhody",
- columns: [
- {
- header: "Бронь3 квартал",
- accessorKey: "data.q3.booking",
- columnLetter: "EI",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактИюль",
- accessorKey: "data.q3.actual_m1",
- columnLetter: "EJ",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактАвгуст",
- accessorKey: "data.q3.actual_m2",
- columnLetter: "EK",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактСентябрь",
- accessorKey: "data.q3.actual_m3",
- columnLetter: "EL",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Факт3 квартал",
- accessorKey: "data.q3.actual_quarter",
- columnLetter: "EM",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после брони 3 квартала",
- accessorKey: "data.q3.residual_after_booking",
- columnLetter: "EN",
- size: 300,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после факта 3 квартала",
- accessorKey: "data.q3.residual_after_actual",
- columnLetter: "EO",
- size: 300,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректировка остатка в последующий квартал",
- accessorKey:
- "3_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschiy_kvartal",
- columns: [
- {
- header: "Перенос в 4 квартал",
- accessorKey: "data.q3.transfer_q4",
- columnLetter: "EQ",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Задержка списания расходов / предоставления актов",
- accessorKey: "data.q3.transfer_q4_delay_acts",
- columnLetter: "ER",
- size: 490,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Задержка закупочных процедур",
- accessorKey: "data.q3.transfer_q4_delay_procurement",
- columnLetter: "ES",
- size: 280,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "экономия (будет использована РФ)",
- accessorKey: "data.q3.transfer_q4_economy_rf",
- columnLetter: "ET",
- size: 320,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий переноса в4 квартал",
- accessorKey: "data.q3.transfer_next_comment",
- columnLetter: "EU",
- size: 320,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Перенос в фонд экономии",
- accessorKey: "data.q3.transfer_econ",
- columnLetter: "EV",
- size: 230,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "ВСЕГО",
- accessorKey: "data.q3.total",
- columnLetter: "EW",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "4 квартал 2026 года",
- accessorKey: "4_kvartal_2026_goda",
- columns: [
- {
- header: "Корректировка базового плана",
- accessorKey: "4_kvartal_2026_goda_korrektirovka_bazovogo_plana",
- columns: [
- {
- header:
- "Изменение целевого назначения перенесенной экономии (= 0)",
- accessorKey: "data.q4.target_change",
- columnLetter: "EY",
- size: 250,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Корректировка статей базового плана (= 0)",
- accessorKey: "data.q4.base_correction",
- columnLetter: "EZ",
- size: 410,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "Комментарий изменения базового плана",
- accessorKey: "data.q4.base_correction_comment",
- columnLetter: "FA",
- size: 360,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- {
- header: "ДФиПУвеличение плана (> 0)",
- accessorKey: "data.q4.revision_inc",
- columnLetter: "FB",
- size: 270,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "ДФиПCеквестр плана (< 0)",
- accessorKey: "data.q4.revision_seq",
- columnLetter: "FC",
- size: 250,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q4.revision_comment",
- columnLetter: "FD",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Скорректированный план на подпись",
- accessorKey: "data.q4.new_plan",
- columnLetter: "FE",
- size: 330,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
+ {
+ header: 'Корректировки плановых значений',
+ accessorKey: '3_kvartal_2026_goda_korrektirovki_planovykh_znacheniy',
+ columns: [
+ {
+ header: 'Текущие (= 0)',
+ accessorKey: 'data.q3.adj_current',
+ columnLetter: 'DX',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз сметы ГО',
+ accessorKey: 'data.q3.adj_ssp',
+ columnLetter: 'DY',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз резерва',
+ accessorKey: 'data.q3.adj_reserve',
+ columnLetter: 'DZ',
+ size: 180,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q3.adj_comment',
+ columnLetter: 'EA',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Скорректированный план с учетом корректировок',
+ accessorKey: 'data.q3.corrected_plan',
+ columnLetter: 'EB',
+ size: 450,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Согласование платежей',
+ accessorKey: '3_kvartal_2026_goda_soglasovanie_platezhey',
+ columns: [
+ {
+ header: 'Дата платежа',
+ accessorKey: 'data.q3.pay_date',
+ columnLetter: 'ED',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Сумма платежа',
+ accessorKey: 'data.q3.pay_amount',
+ columnLetter: 'EE',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q3.pay_comment',
+ columnLetter: 'EF',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Предоставление акта',
+ accessorKey: 'data.q3.pay_act',
+ columnLetter: 'EG',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Фактические расходы',
+ accessorKey: '3_kvartal_2026_goda_fakticheskie_raskhody',
+ columns: [
+ {
+ header: 'Бронь3 квартал',
+ accessorKey: 'data.q3.booking',
+ columnLetter: 'EI',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактИюль',
+ accessorKey: 'data.q3.actual_m1',
+ columnLetter: 'EJ',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактАвгуст',
+ accessorKey: 'data.q3.actual_m2',
+ columnLetter: 'EK',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактСентябрь',
+ accessorKey: 'data.q3.actual_m3',
+ columnLetter: 'EL',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Факт3 квартал',
+ accessorKey: 'data.q3.actual_quarter',
+ columnLetter: 'EM',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после брони 3 квартала',
+ accessorKey: 'data.q3.residual_after_booking',
+ columnLetter: 'EN',
+ size: 300,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после факта 3 квартала',
+ accessorKey: 'data.q3.residual_after_actual',
+ columnLetter: 'EO',
+ size: 300,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректировка остатка в последующий квартал',
+ accessorKey: '3_kvartal_2026_goda_korrektirovka_ostatka_v_posleduyuschiy_kvartal',
+ columns: [
+ {
+ header: 'Перенос в 4 квартал',
+ accessorKey: 'data.q3.transfer_q4',
+ columnLetter: 'EQ',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Задержка списания расходов / предоставления актов',
+ accessorKey: 'data.q3.transfer_q4_delay_acts',
+ columnLetter: 'ER',
+ size: 490,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Задержка закупочных процедур',
+ accessorKey: 'data.q3.transfer_q4_delay_procurement',
+ columnLetter: 'ES',
+ size: 280,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'экономия (будет использована РФ)',
+ accessorKey: 'data.q3.transfer_q4_economy_rf',
+ columnLetter: 'ET',
+ size: 320,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий переноса в4 квартал',
+ accessorKey: 'data.q3.transfer_next_comment',
+ columnLetter: 'EU',
+ size: 320,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Перенос в фонд экономии',
+ accessorKey: 'data.q3.transfer_econ',
+ columnLetter: 'EV',
+ size: 230,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'ВСЕГО',
+ accessorKey: 'data.q3.total',
+ columnLetter: 'EW',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '4 квартал 2026 года',
+ accessorKey: '4_kvartal_2026_goda',
+ columns: [
+ {
+ header: 'Корректировка базового плана',
+ accessorKey: '4_kvartal_2026_goda_korrektirovka_bazovogo_plana',
+ columns: [
+ {
+ header: 'Изменение целевого назначения перенесенной экономии (= 0)',
+ accessorKey: 'data.q4.target_change',
+ columnLetter: 'EY',
+ size: 250,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Корректировка статей базового плана (= 0)',
+ accessorKey: 'data.q4.base_correction',
+ columnLetter: 'EZ',
+ size: 410,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'Комментарий изменения базового плана',
+ accessorKey: 'data.q4.base_correction_comment',
+ columnLetter: 'FA',
+ size: 360,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ {
+ header: 'ДФиПУвеличение плана (> 0)',
+ accessorKey: 'data.q4.revision_inc',
+ columnLetter: 'FB',
+ size: 270,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ДФиПCеквестр плана (< 0)',
+ accessorKey: 'data.q4.revision_seq',
+ columnLetter: 'FC',
+ size: 250,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q4.revision_comment',
+ columnLetter: 'FD',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Скорректированный план на подпись',
+ accessorKey: 'data.q4.new_plan',
+ columnLetter: 'FE',
+ size: 330,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
- {
- header: "Корректировки плановых значений",
- accessorKey:
- "4_kvartal_2026_goda_korrektirovki_planovykh_znacheniy",
- columns: [
- {
- header: "Текущие (= 0)",
- accessorKey: "data.q4.adj_current",
- columnLetter: "FG",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз сметы ГО",
- accessorKey: "data.q4.adj_ssp",
- columnLetter: "FH",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Корректиз резерва",
- accessorKey: "data.q4.adj_reserve",
- columnLetter: "FI",
- size: 180,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q4.adj_comment",
- columnLetter: "FJ",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- {
- header: "Скорректированный план с учетом корректировок",
- accessorKey: "data.q4.corrected_plan",
- columnLetter: "FK",
- size: 450,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFF66",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Согласование платежей",
- accessorKey: "4_kvartal_2026_goda_soglasovanie_platezhey",
- columns: [
- {
- header: "Дата платежа",
- accessorKey: "data.q4.pay_date",
- columnLetter: "FM",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Сумма платежа",
- accessorKey: "data.q4.pay_amount",
- columnLetter: "FN",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Комментарий",
- accessorKey: "data.q4.pay_comment",
- columnLetter: "FO",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- {
- header: "Предоставление акта",
- accessorKey: "data.q4.pay_act",
- columnLetter: "FP",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Фактические расходы",
- accessorKey: "4_kvartal_2026_goda_fakticheskie_raskhody",
- columns: [
- {
- header: "Бронь4 квартал",
- accessorKey: "data.q4.booking",
- columnLetter: "FR",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактОктябрь",
- accessorKey: "data.q4.actual_m1",
- columnLetter: "FS",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактНоябрь",
- accessorKey: "data.q4.actual_m2",
- columnLetter: "FT",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "ФактДекабрь",
- accessorKey: "data.q4.actual_m3",
- columnLetter: "FU",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "СПОД (Январь)",
- accessorKey: "data.q4.actual_spod",
- columnLetter: "FV",
- size: 150,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Факт4 квартал (с уч СПОД)",
- accessorKey: "data.q4.actual_quarter",
- columnLetter: "FW",
- size: 260,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после брони 4 квартала (с уч СПОД)",
- accessorKey: "data.q4.residual_after_booking",
- columnLetter: "FX",
- size: 420,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FABF8F",
- color: "#000000",
- },
- },
- },
- {
- header: "Остаток после факта 4 квартала (с уч СПОД)",
- accessorKey: "data.q4.residual_after_actual",
- columnLetter: "FY",
- size: 420,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- {
- header: "Экономия",
- accessorKey: "4_kvartal_2026_goda_ekonomiya",
- columns: [
- {
- header: "Перенос в фонд экономии",
- accessorKey: "data.q4.transfer_econ",
- columnLetter: "GA",
- size: 230,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#903C39",
- color: "#FFFFFF",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- {
- header: "2026 год.",
- accessorKey: "2026_god_43",
- columns: [
- {
- header: "",
- accessorKey: "2026_god_field_5",
- columns: [
- {
- header: "Сумма фактических расходов за год",
- accessorKey: "data.totals.fact_year",
- columnLetter: "GC",
- size: 330,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#C2D69B",
- color: "#000000",
- },
- },
- },
- {
- header: "Сумма оплаты за год",
- accessorKey: "data.totals.pay_year",
- columnLetter: "GE",
- size: 190,
- filterFn: "contains",
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#95B3D7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#B2A1C7",
- color: "#000000",
- },
- },
- },
- ],
- muiTableHeadCellProps: {
- sx: {
- backgroundColor: "#FFFFFF",
- color: "#000000",
- },
- },
- },
- ],
- },
+ {
+ header: 'Корректировки плановых значений',
+ accessorKey: '4_kvartal_2026_goda_korrektirovki_planovykh_znacheniy',
+ columns: [
+ {
+ header: 'Текущие (= 0)',
+ accessorKey: 'data.q4.adj_current',
+ columnLetter: 'FG',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз сметы ГО',
+ accessorKey: 'data.q4.adj_ssp',
+ columnLetter: 'FH',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Корректиз резерва',
+ accessorKey: 'data.q4.adj_reserve',
+ columnLetter: 'FI',
+ size: 180,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q4.adj_comment',
+ columnLetter: 'FJ',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Скорректированный план с учетом корректировок',
+ accessorKey: 'data.q4.corrected_plan',
+ columnLetter: 'FK',
+ size: 450,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFF66',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Согласование платежей',
+ accessorKey: '4_kvartal_2026_goda_soglasovanie_platezhey',
+ columns: [
+ {
+ header: 'Дата платежа',
+ accessorKey: 'data.q4.pay_date',
+ columnLetter: 'FM',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Сумма платежа',
+ accessorKey: 'data.q4.pay_amount',
+ columnLetter: 'FN',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Комментарий',
+ accessorKey: 'data.q4.pay_comment',
+ columnLetter: 'FO',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Предоставление акта',
+ accessorKey: 'data.q4.pay_act',
+ columnLetter: 'FP',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Фактические расходы',
+ accessorKey: '4_kvartal_2026_goda_fakticheskie_raskhody',
+ columns: [
+ {
+ header: 'Бронь4 квартал',
+ accessorKey: 'data.q4.booking',
+ columnLetter: 'FR',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактОктябрь',
+ accessorKey: 'data.q4.actual_m1',
+ columnLetter: 'FS',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактНоябрь',
+ accessorKey: 'data.q4.actual_m2',
+ columnLetter: 'FT',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'ФактДекабрь',
+ accessorKey: 'data.q4.actual_m3',
+ columnLetter: 'FU',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'СПОД (Январь)',
+ accessorKey: 'data.q4.actual_spod',
+ columnLetter: 'FV',
+ size: 150,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Факт4 квартал (с уч СПОД)',
+ accessorKey: 'data.q4.actual_quarter',
+ columnLetter: 'FW',
+ size: 260,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после брони 4 квартала (с уч СПОД)',
+ accessorKey: 'data.q4.residual_after_booking',
+ columnLetter: 'FX',
+ size: 420,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FABF8F',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Остаток после факта 4 квартала (с уч СПОД)',
+ accessorKey: 'data.q4.residual_after_actual',
+ columnLetter: 'FY',
+ size: 420,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Экономия',
+ accessorKey: '4_kvartal_2026_goda_ekonomiya',
+ columns: [
+ {
+ header: 'Перенос в фонд экономии',
+ accessorKey: 'data.q4.transfer_econ',
+ columnLetter: 'GA',
+ size: 230,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#903C39',
+ color: '#FFFFFF',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: '2026 год.',
+ accessorKey: '2026_god_43',
+ columns: [
+ {
+ header: '',
+ accessorKey: '2026_god_field_5',
+ columns: [
+ {
+ header: 'Сумма фактических расходов за год',
+ accessorKey: 'data.totals.fact_year',
+ columnLetter: 'GC',
+ size: 330,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#C2D69B',
+ color: '#000000',
+ },
+ },
+ },
+ {
+ header: 'Сумма оплаты за год',
+ accessorKey: 'data.totals.pay_year',
+ columnLetter: 'GE',
+ size: 190,
+ filterFn: 'contains',
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#95B3D7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#B2A1C7',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ muiTableHeadCellProps: {
+ sx: {
+ backgroundColor: '#FFFFFF',
+ color: '#000000',
+ },
+ },
+ },
+ ],
+ },
};
diff --git a/web/src/components/RealtimeTable/constants/FORM_2/CAP.js b/web/src/components/RealtimeTable/constants/FORM_2/CAP.js
index 0eaffdc..cadf2cd 100644
--- a/web/src/components/RealtimeTable/constants/FORM_2/CAP.js
+++ b/web/src/components/RealtimeTable/constants/FORM_2/CAP.js
@@ -25,6 +25,14 @@ export const config = {
color_type: orangeColumn,
accessorKey: "data.header.name",
},
+ "data.header.vsp_id": {
+ color_type: orangeColumn,
+ accessorKey: "data.header.vsp_id",
+ },
+ "data.header.vsp_address": {
+ color_type: orangeColumn,
+ accessorKey: "data.header.vsp_address",
+ },
"data.header.internal_order": {
color_type: orangeColumn,
accessorKey: "data.header.internal_order",
@@ -830,6 +838,33 @@ export const config = {
},
],
},
+ {
+ header: "ВСП РФ",
+ accessorKey: "field_vsp_rf",
+ columns: [
+ {
+ header: "",
+ accessorKey: "data.header.vsp_id",
+ columnLetter: "G",
+ size: 150,
+ filterFn: "contains",
+ editType: "vsp_dropdown",
+ },
+ ],
+ },
+ {
+ header: "Адрес ВСП",
+ accessorKey: "field_adres_vsp",
+ columns: [
+ {
+ header: "",
+ accessorKey: "data.header.vsp_address",
+ columnLetter: "G1",
+ size: 220,
+ filterFn: "contains",
+ },
+ ],
+ },
{
header: "Внутренний заказ",
accessorKey: "field_vnutrenniy_zakaz",
@@ -837,7 +872,7 @@ export const config = {
{
header: "",
accessorKey: "data.header.internal_order",
- columnLetter: "G",
+ columnLetter: "H",
size: 150,
filterFn: "contains",
},
diff --git a/web/src/components/RealtimeTable/constants/FORM_2/OPER.js b/web/src/components/RealtimeTable/constants/FORM_2/OPER.js
index 894bb85..bc7a9d4 100644
--- a/web/src/components/RealtimeTable/constants/FORM_2/OPER.js
+++ b/web/src/components/RealtimeTable/constants/FORM_2/OPER.js
@@ -25,6 +25,14 @@ export const config = {
color_type: blueColumn,
accessorKey: "data.header.name",
},
+ "data.header.vsp_id": {
+ color_type: blueColumn,
+ accessorKey: "data.header.vsp_id",
+ },
+ "data.header.vsp_address": {
+ color_type: blueColumn,
+ accessorKey: "data.header.vsp_address",
+ },
"data.header.internal_order": {
color_type: blueColumn,
accessorKey: "data.header.internal_order",
@@ -830,6 +838,33 @@ export const config = {
},
],
},
+ {
+ header: "ВСП РФ",
+ accessorKey: "field_vsp_rf",
+ columns: [
+ {
+ header: "",
+ accessorKey: "data.header.vsp_id",
+ columnLetter: "G",
+ size: 150,
+ filterFn: "contains",
+ editType: "vsp_dropdown",
+ },
+ ],
+ },
+ {
+ header: "Адрес ВСП",
+ accessorKey: "field_adres_vsp",
+ columns: [
+ {
+ header: "",
+ accessorKey: "data.header.vsp_address",
+ columnLetter: "G1",
+ size: 220,
+ filterFn: "contains",
+ },
+ ],
+ },
{
header: "Внутренний заказ",
accessorKey: "field_vnutrenniy_zakaz",
@@ -837,7 +872,7 @@ export const config = {
{
header: "",
accessorKey: "data.header.internal_order",
- columnLetter: "G",
+ columnLetter: "H",
size: 150,
filterFn: "contains",
},
diff --git a/web/src/components/RealtimeTable/contexts/RealtimeContext.js b/web/src/components/RealtimeTable/contexts/RealtimeContext.js
index 4028366..77d7305 100644
--- a/web/src/components/RealtimeTable/contexts/RealtimeContext.js
+++ b/web/src/components/RealtimeTable/contexts/RealtimeContext.js
@@ -1,454 +1,425 @@
-import React, {
- createContext,
- useContext,
- useCallback,
- useRef,
- useState,
- useEffect,
-} from "react";
-import { useWebSocket } from "../hooks/useWebSocket";
-import { toast } from "react-toastify";
-import { getRowId } from "../utils/rowUtils";
+import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
+import { toast } from 'react-toastify';
+import { useWebSocket } from '../hooks/useWebSocket';
+import { getRowId } from '../utils/rowUtils';
const RealtimeContext = createContext(null);
export const useRealtime = () => {
- const context = useContext(RealtimeContext);
- if (!context) {
- throw new Error("useRealtime must be used within RealtimeProvider");
- }
- return context;
+ const context = useContext(RealtimeContext);
+ if (!context) {
+ throw new Error('useRealtime must be used within RealtimeProvider');
+ }
+ return context;
};
-export const RealtimeProvider = ({
- children,
- formId,
- sheetName,
- direction,
- year,
- userId,
- isProject = false,
-}) => {
- // Формируем URL (кастомные секреты на фронте пока недоступны, делаем через REACT_APP_ROOT_PATH)
- const wsUrl =
- `${(
- process.env.REACT_APP_API_URL ||
- process.env.REACT_APP_API_URL ||
- process.env.REACT_APP_ROOT_PATH ||
- "ws://localhost:8000"
- ).replace(/^http/, "ws")}` +
- (!isProject
- ? `/api/v1/ws/form/${formId}/sheet/${sheetName}${direction ? `?direction=${direction}` : ""}`
- : `/api/v1/ws/projects/${formId}/report/${year}/${sheetName}`);
+export const RealtimeProvider = ({ children, formId, sheetName, direction, year, userId, isProject = false }) => {
+ // Формируем URL (кастомные секреты на фронте пока недоступны, делаем через REACT_APP_ROOT_PATH)
+ const wsUrl = `${(
+ process.env.REACT_APP_API_URL || process.env.REACT_APP_API_URL || process.env.REACT_APP_ROOT_PATH || 'ws://localhost:8000'
+ ).replace(/^http/, 'ws')}${
+ !isProject
+ ? `/api/v1/ws/form/${formId}/sheet/${sheetName}${direction ? `?direction=${direction}` : ''}`
+ : `/api/v1/ws/projects/${formId}/report/${year}/${sheetName}`
+ }`;
- //для ячеек которые редактируются другими пользователями
- const [lockedCells, setLockedCells] = useState([]);
- const handleMessage = useCallback((data) => {
- // Обработка ошибок
- if (data.error) {
- console.log(data.error.message);
- toast.error("Server error:" + data.error.message || "");
- onErrorRef.current?.(data.error);
- return;
- }
+ //для ячеек которые редактируются другими пользователями
+ const [lockedCells, setLockedCells] = useState([]);
+ const [vspOptions, setVspOptions] = useState([]);
+ const handleMessage = useCallback((data) => {
+ // Обработка ошибок
+ if (data.error) {
+ toast.error(`Server error:${data.error.message}` || '');
+ onErrorRef.current?.(data.error);
+ return;
+ }
- switch (data.event) {
- case "cell_edit_start":
- console.log("Cell edit started:", data);
- if (onCellEditStartRef.current) {
- onCellEditStartRef.current(data);
- }
- break;
+ switch (data.event) {
+ case 'cell_edit_start':
+ if (onCellEditStartRef.current) {
+ onCellEditStartRef.current(data);
+ }
+ break;
- case "cell_edit_end":
- console.log("Cell edit ended:", data);
- if (onCellEditEndRef.current) {
- onCellEditEndRef.current(data);
- }
- break;
+ case 'cell_edit_end':
+ if (onCellEditEndRef.current) {
+ onCellEditEndRef.current(data);
+ }
+ break;
- case "cell_updated":
- if (data.result && onCellUpdateRef.current) {
- const updatedCells = Array.isArray(data.result)
- ? data.result
- : [data.result];
- onCellUpdateRef.current(updatedCells);
- }
- break;
+ case 'cell_updated':
+ if (data.result && onCellUpdateRef.current) {
+ const updatedCells = Array.isArray(data.result) ? data.result : [data.result];
+ onCellUpdateRef.current(updatedCells);
+ }
+ break;
- case "row_added":
- if (data.result && onRowAddRef.current) {
- onRowAddRef.current(data);
- }
- break;
+ case 'row_added':
+ if (data.result && onRowAddRef.current) {
+ onRowAddRef.current(data);
+ }
+ break;
- case "row_deleted":
- if (data.result && onRowDeleteRef.current) {
- onRowDeleteRef.current(data);
- }
- break;
+ case 'row_deleted':
+ if (data.result && onRowDeleteRef.current) {
+ onRowDeleteRef.current(data);
+ }
+ break;
- case "program_added":
- console.log("Program added:", data);
- if (data.result && onProgramAddRef.current) {
- onProgramAddRef.current(data);
- }
- break;
+ case 'program_added':
+ if (data.result && onProgramAddRef.current) {
+ onProgramAddRef.current(data);
+ }
+ break;
- case "project_added":
- console.log("Project added:", data);
- if (data.result && onProjectAddRef.current) {
- onProjectAddRef.current(data);
- }
- break;
+ case 'project_added':
+ if (data.result && onProjectAddRef.current) {
+ onProjectAddRef.current(data);
+ }
+ break;
- default:
- console.log("Unknown event:", data.event);
- }
- }, []);
+ default:
+ }
+ }, []);
- const { isConnectedRef, isConnected, sendMessage, disconnect, lastError } =
- useWebSocket(wsUrl, handleMessage);
+ const { isConnectedRef, isConnected, sendMessage, disconnect, lastError } = useWebSocket(wsUrl, handleMessage);
- const onCellUpdateRef = useRef(null);
- const onRowAddRef = useRef(null);
- const onRowDeleteRef = useRef(null);
- const onProgramAddRef = useRef(null);
- const onProjectAddRef = useRef(null);
- const onErrorRef = useRef(null);
- const onAuthSuccessRef = useRef(null);
- const onCellEditStartRef = useRef(null);
- const onCellEditEndRef = useRef(null);
- const authAttemptedRef = useRef(false);
- const reconnectTimerRef = useRef(null);
+ const onCellUpdateRef = useRef(null);
+ const onRowAddRef = useRef(null);
+ const onRowDeleteRef = useRef(null);
+ const onProgramAddRef = useRef(null);
+ const onProjectAddRef = useRef(null);
+ const onErrorRef = useRef(null);
+ const onAuthSuccessRef = useRef(null);
+ const onCellEditStartRef = useRef(null);
+ const onCellEditEndRef = useRef(null);
+ const authAttemptedRef = useRef(false);
+ const _reconnectTimerRef = useRef(null);
- // Функция для получения токена из localStorage
- const getAccessToken = useCallback(() => {
- try {
- const token = localStorage.getItem("access_token");
+ // Функция для получения токена из localStorage
+ const getAccessToken = useCallback(() => {
+ try {
+ const token = localStorage.getItem('access_token');
- if (!token) {
- console.warn("No access token found in localStorage");
- return null;
- }
+ if (!token) {
+ return null;
+ }
- return token;
- } catch (error) {
- console.error("Error reading token from localStorage:", error);
- return null;
- }
- }, []);
+ return token;
+ } catch (_error) {
+ return null;
+ }
+ }, []);
- const sendLogin = useCallback(() => {
- const token = getAccessToken();
- if (!token) {
- console.error("Cannot login: no token available");
- onErrorRef.current?.("Токен авторизации не найден");
- return false;
- }
+ const sendLogin = useCallback(() => {
+ const token = getAccessToken();
+ if (!token) {
+ onErrorRef.current?.('Токен авторизации не найден');
+ return false;
+ }
- const loginMessage = {
- event: "user_login",
- data: { token },
- };
+ const loginMessage = {
+ event: 'user_login',
+ data: { token },
+ };
- return sendMessage(loginMessage);
- }, [getAccessToken, sendMessage]);
+ return sendMessage(loginMessage);
+ }, [getAccessToken, sendMessage]);
- useEffect(() => {
- if (isConnected && !authAttemptedRef.current) {
- authAttemptedRef.current = true;
- console.log("WebSocket connected, sending login...");
- setTimeout(() => {
- sendLogin();
- }, 100);
- }
- }, [isConnected, sendLogin]);
+ useEffect(() => {
+ if (isConnected && !authAttemptedRef.current) {
+ authAttemptedRef.current = true;
+ setTimeout(() => {
+ sendLogin();
+ }, 100);
+ }
+ }, [isConnected, sendLogin]);
- useEffect(() => {
- if (!isConnected) {
- authAttemptedRef.current = false;
- }
- }, [isConnected]);
+ useEffect(() => {
+ if (!isConnected) {
+ authAttemptedRef.current = false;
+ }
+ }, [isConnected]);
- const addCommonField = (message) => {
- if (isProject) {
- message.report_type = sheetName;
- message.project_id = formId;
- message.year = year;
- } else {
- message.sheet = sheetName;
- message.form_id = formId;
- message.direction = direction;
- }
- return message;
- };
+ const addCommonField = (message) => {
+ if (isProject) {
+ message.report_type = sheetName;
+ message.project_id = formId;
+ message.year = year;
+ } else {
+ message.sheet = sheetName;
+ message.form_id = formId;
+ message.direction = direction;
+ }
+ return message;
+ };
- // Функция для начала редактирования ячейки
- const startEditing = useCallback(
- async (row, column) => {
- const columnId = column.id;
- const rowId = row.id;
+ // Функция для начала редактирования ячейки
+ const startEditing = useCallback(
+ async (row, column) => {
+ const columnId = column.id;
+ const _rowId = row.id;
- if (!isConnectedRef) {
- onErrorRef.current?.("WebSocket не подключен");
- return false;
- }
+ if (!isConnectedRef) {
+ onErrorRef.current?.('WebSocket не подключен');
+ return false;
+ }
- const lineId = row.id || null;
- const colId = columnId.slice(5); // убираем префикс "data."
+ const lineId = row.id || null;
+ const colId = columnId.slice(5); // убираем префикс "data."
- const message = {
- event: "cell_edit_start",
- data: {
- line_id: lineId,
- column: colId,
- },
- };
+ const message = {
+ event: 'cell_edit_start',
+ data: {
+ line_id: lineId,
+ column: colId,
+ },
+ };
- const sent = sendMessage(message);
- if (!sent) {
- return false;
- }
+ const sent = sendMessage(message);
+ if (!sent) {
+ return false;
+ }
- return true;
- },
- [isConnected, sendMessage],
- );
+ return true;
+ },
+ [isConnected, sendMessage],
+ );
- // Функция для завершения редактирования ячейки
- const endEditing = useCallback(
- async (row, column) => {
- const columnId = column.id;
- const rowId = row.id;
+ // Функция для завершения редактирования ячейки
+ const endEditing = useCallback(
+ async (row, column) => {
+ const columnId = column.id;
+ const _rowId = row.id;
- if (!isConnectedRef) {
- onErrorRef.current?.("WebSocket не подключен");
- return false;
- }
+ if (!isConnectedRef) {
+ onErrorRef.current?.('WebSocket не подключен');
+ return false;
+ }
- const lineId = row.id || null;
- const colId = columnId.slice(5);
+ const lineId = row.id || null;
+ const colId = columnId.slice(5);
- const message = {
- event: "cell_edit_end",
- data: {
- line_id: lineId,
- column: colId,
- },
- };
+ const message = {
+ event: 'cell_edit_end',
+ data: {
+ line_id: lineId,
+ column: colId,
+ },
+ };
- const sent = sendMessage(message);
- if (!sent) {
- return false;
- }
+ const sent = sendMessage(message);
+ if (!sent) {
+ return false;
+ }
- return true;
- },
- [isConnected, sendMessage],
- );
+ return true;
+ },
+ [isConnected, sendMessage],
+ );
- const updateCell = useCallback(
- async (row, column, value) => {
- const columnId = column.id;
- const rowId = row.id;
- if (!isConnectedRef) {
- onErrorRef.current?.("WebSocket не подключен");
- return false;
- }
+ const updateCell = useCallback(
+ async (row, column, value) => {
+ const columnId = column.id;
+ const _rowId = row.id;
+ if (!isConnectedRef) {
+ onErrorRef.current?.('WebSocket не подключен');
+ return false;
+ }
- const lineId = getRowId(row);
- const colId = columnId.slice(5);
- const message = {
- event: "cell_updated",
- data: {
- line_id: lineId,
- line_id_code: row.id,
- column: colId,
- value: value,
- },
- };
- const sent = sendMessage(message);
+ const lineId = getRowId(row);
+ const colId = columnId.slice(5);
+ const message = {
+ event: 'cell_updated',
+ data: {
+ line_id: lineId,
+ line_id_code: row.id,
+ column: colId,
+ value: value,
+ },
+ };
+ const sent = sendMessage(message);
- if (!sent) {
- return false;
- }
+ if (!sent) {
+ return false;
+ }
- return true;
- },
- [isConnected, sendMessage],
- );
+ return true;
+ },
+ [isConnected, sendMessage],
+ );
- const addRow = useCallback(
- async (rowData) => {
- if (!isConnectedRef) {
- onErrorRef.current?.("Нет подключения или авторизации");
- return false;
- }
+ const addRow = useCallback(
+ async (rowData) => {
+ if (!isConnectedRef) {
+ onErrorRef.current?.('Нет подключения или авторизации');
+ return false;
+ }
- const message = {
- event: "row_added",
- data: rowData,
- };
- addCommonField(message);
+ const message = {
+ event: 'row_added',
+ data: rowData,
+ };
+ addCommonField(message);
- return sendMessage(message);
- },
- [isConnected, sendMessage, sheetName, formId, direction],
- );
+ return sendMessage(message);
+ },
+ [isConnected, sendMessage, sheetName, formId, direction],
+ );
- const addProject = useCallback(
- async (rowData) => {
- if (!isConnectedRef) {
- onErrorRef.current?.("Нет подключения или авторизации");
- return false;
- }
+ const addProject = useCallback(
+ async (rowData) => {
+ if (!isConnectedRef) {
+ onErrorRef.current?.('Нет подключения или авторизации');
+ return false;
+ }
- const message = {
- event: "project_added",
- data: rowData,
- };
- addCommonField(message);
+ const message = {
+ event: 'project_added',
+ data: rowData,
+ };
+ addCommonField(message);
- return sendMessage(message);
- },
- [isConnected, sendMessage, sheetName, formId, direction],
- );
+ return sendMessage(message);
+ },
+ [isConnected, sendMessage, sheetName, formId, direction],
+ );
- const addProgram = useCallback(
- async (rowData) => {
- if (!isConnectedRef) {
- onErrorRef.current?.("Нет подключения или авторизации");
- return false;
- }
+ const addProgram = useCallback(
+ async (rowData) => {
+ if (!isConnectedRef) {
+ onErrorRef.current?.('Нет подключения или авторизации');
+ return false;
+ }
- const message = {
- event: "program_added",
- data: rowData,
- };
- addCommonField(message);
+ const message = {
+ event: 'program_added',
+ data: rowData,
+ };
+ addCommonField(message);
- return sendMessage(message);
- },
- [isConnected, sendMessage, sheetName, formId, direction],
- );
+ return sendMessage(message);
+ },
+ [isConnected, sendMessage, sheetName, formId, direction],
+ );
- const deleteRow = useCallback(
- async (rowId) => {
- if (!isConnectedRef) {
- onErrorRef.current?.("Нет подключения или авторизации");
- return false;
- }
+ const deleteRow = useCallback(
+ async (rowId) => {
+ if (!isConnectedRef) {
+ onErrorRef.current?.('Нет подключения или авторизации');
+ return false;
+ }
- const message = {
- event: "row_deleted",
- data: { row_id: rowId },
- };
- addCommonField(message);
+ const message = {
+ event: 'row_deleted',
+ data: { row_id: rowId },
+ };
+ addCommonField(message);
- return sendMessage(message);
- },
- [isConnected, sendMessage, sheetName, formId, direction],
- );
+ return sendMessage(message);
+ },
+ [isConnected, sendMessage, sheetName, formId, direction],
+ );
- const subscribeToCellUpdates = useCallback((callback) => {
- onCellUpdateRef.current = callback;
- return () => {
- onCellUpdateRef.current = null;
- };
- }, []);
+ const subscribeToCellUpdates = useCallback((callback) => {
+ onCellUpdateRef.current = callback;
+ return () => {
+ onCellUpdateRef.current = null;
+ };
+ }, []);
- const subscribeToRowAdds = useCallback((callback) => {
- onRowAddRef.current = callback;
- return () => {
- onRowAddRef.current = null;
- };
- }, []);
+ const subscribeToRowAdds = useCallback((callback) => {
+ onRowAddRef.current = callback;
+ return () => {
+ onRowAddRef.current = null;
+ };
+ }, []);
- const subscribeToRowDeletes = useCallback((callback) => {
- onRowDeleteRef.current = callback;
- return () => {
- onRowDeleteRef.current = null;
- };
- }, []);
+ const subscribeToRowDeletes = useCallback((callback) => {
+ onRowDeleteRef.current = callback;
+ return () => {
+ onRowDeleteRef.current = null;
+ };
+ }, []);
- const subscribeToProgramAdds = useCallback((callback) => {
- onProgramAddRef.current = callback;
- return () => {
- onProgramAddRef.current = null;
- };
- }, []);
+ const subscribeToProgramAdds = useCallback((callback) => {
+ onProgramAddRef.current = callback;
+ return () => {
+ onProgramAddRef.current = null;
+ };
+ }, []);
- const subscribeToProjectAdds = useCallback((callback) => {
- onProjectAddRef.current = callback;
- return () => {
- onProjectAddRef.current = null;
- };
- }, []);
+ const subscribeToProjectAdds = useCallback((callback) => {
+ onProjectAddRef.current = callback;
+ return () => {
+ onProjectAddRef.current = null;
+ };
+ }, []);
- const subscribeToErrors = useCallback((callback) => {
- onErrorRef.current = callback;
- return () => {
- onErrorRef.current = null;
- };
- }, []);
+ const subscribeToErrors = useCallback((callback) => {
+ onErrorRef.current = callback;
+ return () => {
+ onErrorRef.current = null;
+ };
+ }, []);
- const subscribeToAuthSuccess = useCallback((callback) => {
- onAuthSuccessRef.current = callback;
- return () => {
- onAuthSuccessRef.current = null;
- };
- }, []);
+ const subscribeToAuthSuccess = useCallback((callback) => {
+ onAuthSuccessRef.current = callback;
+ return () => {
+ onAuthSuccessRef.current = null;
+ };
+ }, []);
- const subscribeToCellEditStart = useCallback((callback) => {
- onCellEditStartRef.current = callback;
- return () => {
- onCellEditStartRef.current = null;
- };
- }, []);
+ const subscribeToCellEditStart = useCallback((callback) => {
+ onCellEditStartRef.current = callback;
+ return () => {
+ onCellEditStartRef.current = null;
+ };
+ }, []);
- const subscribeToCellEditEnd = useCallback((callback) => {
- onCellEditEndRef.current = callback;
- return () => {
- onCellEditEndRef.current = null;
- };
- }, []);
+ const subscribeToCellEditEnd = useCallback((callback) => {
+ onCellEditEndRef.current = callback;
+ return () => {
+ onCellEditEndRef.current = null;
+ };
+ }, []);
- const retryLogin = useCallback(() => {
- if (isConnected) {
- authAttemptedRef.current = false;
- sendLogin();
- }
- }, [isConnected, sendLogin]);
+ const retryLogin = useCallback(() => {
+ if (isConnected) {
+ authAttemptedRef.current = false;
+ sendLogin();
+ }
+ }, [isConnected, sendLogin]);
- return (
- releaseAllLocks(userId),
- }}
- >
- {children}
-
- );
+ return (
+ releaseAllLocks(userId),
+ }}>
+ {children}
+
+ );
};
diff --git a/web/src/components/RealtimeTable/tableColumns.jsx b/web/src/components/RealtimeTable/tableColumns.jsx
index 43fb911..9e7717c 100644
--- a/web/src/components/RealtimeTable/tableColumns.jsx
+++ b/web/src/components/RealtimeTable/tableColumns.jsx
@@ -1,210 +1,205 @@
import React, { useEffect, useRef, useState, useMemo, useCallback } from 'react';
import { createPortal } from 'react-dom';
import { useParams } from 'react-router';
+import VspDropdownEditCell from './Cell/EditCell/VspDropdownEditCell';
import { useRealtime } from './contexts/RealtimeContext';
-const EditCellPortal = React.memo(({
- cell,
- table,
- EditCell,
- onSaveStart,
- onSaveEnd,
- onError,
- isEditable
-}) => {
- const { formId, formType, sheetName, direction } = useParams();
- const tableKey = `${formId}_${formType}_${sheetName}_${direction}`;
- const ref = useRef(null);
- const [refTbody, setRefTbody] = useState(null);
- const [isSaving, setIsSaving] = useState(false);
+const EditCellPortal = React.memo(({ cell, table, EditCell, onSaveStart, onSaveEnd, onError, isEditable }) => {
+ const { formId, formType, sheetName, direction } = useParams();
+ const tableKey = `${formId}_${formType}_${sheetName}_${direction}`;
+ const ref = useRef(null);
+ const [refTbody, setRefTbody] = useState(null);
+ const [isSaving, _setIsSaving] = useState(false);
- const { endEditing: contextEndEditing } = useRealtime();
+ const { endEditing: contextEndEditing } = useRealtime();
- useEffect(() => {
- if (ref.current) {
- const tbodyRef = ref.current.offsetParent?.offsetParent?.offsetParent;
- if (tbodyRef && tbodyRef !== refTbody) {
- setRefTbody(tbodyRef);
- }
- }
- }, []);
+ useEffect(() => {
+ if (ref.current) {
+ const tbodyRef = ref.current.offsetParent?.offsetParent?.offsetParent;
+ if (tbodyRef && tbodyRef !== refTbody) {
+ setRefTbody(tbodyRef);
+ }
+ }
+ }, []);
- const handleChange = useCallback( (val) => {
- table.setEditingCell(null);
- try {
- if (table.options.meta?.updateCell) {
- const success = table.options.meta.updateCell(
- cell.row,
- cell.column,
- val
- );
- if (!success) {
- console.error('Failed to update cell via WebSocket');
- onError?.('Не удалось сохранить изменение');
- }
- }
- } catch (error) {
- console.error('Error updating cell:', error);
- onError?.(error.message);
- }
- }, [table, cell, onError]);
+ const handleChange = useCallback(
+ (val) => {
+ table.setEditingCell(null);
+ try {
+ if (table.options.meta?.updateCell) {
+ const success = table.options.meta.updateCell(cell.row, cell.column, val);
+ if (!success) {
+ onError?.('Не удалось сохранить изменение');
+ }
+ }
+ } catch (error) {
+ onError?.(error.message);
+ }
+ },
+ [table, cell, onError],
+ );
- const editCellProps = useMemo(() => ({
- refCell: ref,
- cell,
- value: cell.getValue(),
- disabled: !isEditable,
- onChange: handleChange,
- tableId: tableKey,
- table,
- cellId: `${cell.row.id}_${cell.column.id}`,
- }), [cell, isEditable, handleChange, tableKey, table]);
+ const editCellProps = useMemo(
+ () => ({
+ refCell: ref,
+ cell,
+ value: cell.getValue(),
+ disabled: !isEditable,
+ onChange: handleChange,
+ tableId: tableKey,
+ table,
+ cellId: `${cell.row.id}_${cell.column.id}`,
+ }),
+ [cell, isEditable, handleChange, tableKey, table],
+ );
- const portalContent = useMemo(() => {
- if (!refTbody || isSaving) return null;
- return createPortal(
- ,
- refTbody
- );
- }, [refTbody, isSaving, editCellProps, EditCell]);
+ const editType = cell.column.columnDef?.editType;
- return (
- <>
-
- {portalContent}
- >
- );
+ const portalContent = useMemo(() => {
+ if (!refTbody || isSaving) return null;
+
+ if (editType === 'vsp_dropdown') {
+ return createPortal(, refTbody);
+ }
+
+ return createPortal(, refTbody);
+ }, [refTbody, isSaving, editCellProps, EditCell, editType]);
+
+ return (
+ <>
+
+ {portalContent}
+ >
+ );
});
+export const getTableColumns = ({ Cell, EditCell, columnsConfig, onCellUpdateError, onCellNumberClick, isCellInvalid }) => {
+ const columnColors = { ...columnsConfig.colors };
+ const columns = structuredClone(columnsConfig.columns);
-export const getTableColumns = ({
- Cell,
- EditCell,
- columnsConfig,
- onCellUpdateError,
- onCellNumberClick,
- isCellInvalid,
-}) => {
- const columnColors = { ...columnsConfig.colors };
- const columns = structuredClone(columnsConfig.columns);
+ const cellPropsCache = new WeakMap();
+ const editPropsCache = new WeakMap();
- const cellPropsCache = new WeakMap();
- const editPropsCache = new WeakMap();
+ const getCachedCellProps = (row, column, table) => {
+ const key = `${row.id}_${column.id}`;
+ const value = row.getValue(column.id);
+ const isInvalid = isCellInvalid?.(column.id, value, row.original) || false;
- const getCachedCellProps = (row, column, table) => {
- const key = `${row.id}_${column.id}`;
- const value = row.getValue(column.id);
- const isInvalid = isCellInvalid?.(column.id, value, row.original) || false;
+ if (!cellPropsCache.has(row)) {
+ cellPropsCache.set(row, {});
+ }
- if (!cellPropsCache.has(row)) {
- cellPropsCache.set(row, {});
- }
+ const rowCache = cellPropsCache.get(row);
+ if (rowCache[key]) {
+ const cached = rowCache[key];
+ const currentGlobalFilter = table.getState().globalFilter;
+ const currentColumnFilter = table.getState().columnFilters?.find((f) => f.id === column.id)?.value;
- const rowCache = cellPropsCache.get(row);
- if (rowCache[key]) {
- const cached = rowCache[key];
- const currentGlobalFilter = table.getState().globalFilter;
- const currentColumnFilter = table.getState().columnFilters?.find(f => f.id === column.id)?.value;
+ if (
+ cached.globalFilter === currentGlobalFilter &&
+ cached.columnFilter === currentColumnFilter &&
+ cached.value === value &&
+ cached.isInvalid === isInvalid
+ ) {
+ return cached;
+ }
+ }
- if (cached.globalFilter === currentGlobalFilter &&
- cached.columnFilter === currentColumnFilter &&
- cached.value === value &&
- cached.isInvalid === isInvalid) {
- return cached;
- }
- }
+ const globalFilter = table.getState().globalFilter;
+ const columnFilter = table.getState().columnFilters?.find((f) => f.id === column.id)?.value;
- const globalFilter = table.getState().globalFilter;
- const columnFilter = table.getState().columnFilters?.find(f => f.id === column.id)?.value;
+ const props = {
+ globalFilter,
+ columnFilter,
+ isEditable: row.original?.row_type === 'INPUT' || false,
+ backgroundColor: columnColors[column.id]?.color_type?.[row.original?.row_type || row.row_type],
+ isUpdating: table.options.meta?.updatingCells?.[`${row.id}_${column.id}`],
+ isInvalid,
+ value,
+ _hash: `${globalFilter}_${columnFilter}_${row.id}_${column.id}_${value}_${isInvalid}`,
+ };
- const props = {
- globalFilter,
- columnFilter,
- isEditable: row.original?.row_type === 'INPUT' || false,
- backgroundColor: columnColors[column.id]?.color_type?.[row.original?.row_type || row.row_type],
- isUpdating: table.options.meta?.updatingCells?.[`${row.id}_${column.id}`],
- isInvalid,
- value,
- _hash: `${globalFilter}_${columnFilter}_${row.id}_${column.id}_${value}_${isInvalid}`,
- };
+ rowCache[key] = props;
+ return props;
+ };
- rowCache[key] = props;
- return props;
- };
+ const getCachedEditProps = (row, column, _table) => {
+ const key = `${row.id}_${column.id}`;
- const getCachedEditProps = (row, column, table) => {
- const key = `${row.id}_${column.id}`;
+ if (!editPropsCache.has(row)) {
+ editPropsCache.set(row, {});
+ }
- if (!editPropsCache.has(row)) {
- editPropsCache.set(row, {});
- }
+ const rowCache = editPropsCache.get(row);
+ if (rowCache[key]) {
+ return rowCache[key];
+ }
- const rowCache = editPropsCache.get(row);
- if (rowCache[key]) {
- return rowCache[key];
- }
+ const props = {
+ isEditable: row.original?.row_type === 'INPUT' || false,
+ };
- const props = {
- isEditable: row.original?.row_type === 'INPUT' || false,
- };
+ rowCache[key] = props;
+ return props;
+ };
- rowCache[key] = props;
- return props;
- };
+ // Оптимизированная функция processColumns
+ const processColumns = (columns) => {
+ columns.forEach((col) => {
+ col.Cell = ({ cell, table, column, row }) => {
+ const { vspOptions } = useRealtime();
+ const props = getCachedCellProps(row, column, table);
- // Оптимизированная функция processColumns
- const processColumns = (columns) => {
- columns.forEach((col) => {
- col.Cell = ({ cell, table, column, row }) => {
- const props = getCachedCellProps(row, column, table);
+ const cellProps = useMemo(
+ () => ({
+ row,
+ column,
+ cell,
+ vspOptions,
+ ...props,
+ }),
+ [row.id, column.id, cell.getValue(), props._hash, vspOptions],
+ );
- const cellProps = useMemo(() => ({
- row,
- column,
- cell,
- ...props,
- }), [row.id, column.id, cell.getValue(), props._hash]);
+ return | ;
+ };
- return | ;
- };
+ col.Edit = ({ cell, table, row, column }) => {
+ const props = getCachedEditProps(row, column, table);
- col.Edit = ({ cell, table, row, column }) => {
- const props = getCachedEditProps(row, column, table);
+ const editComponent = useMemo(
+ () => ,
+ [cell, table, EditCell, onCellUpdateError, props.isEditable],
+ );
- const editComponent = useMemo(() => (
-
- ), [cell, table, EditCell, onCellUpdateError, props.isEditable]);
+ return editComponent;
+ };
- return editComponent;
- };
+ if (col.editType === 'vsp_dropdown') {
+ col.enableEditing = (row) => row?.original?.row_type === 'INPUT';
+ }
- if (col.columns?.length) {
- processColumns(col.columns);
- }
- });
- };
+ if (col.columns?.length) {
+ processColumns(col.columns);
+ }
+ });
+ };
- processColumns(columns);
+ processColumns(columns);
- const rowNumber = {
- accessorKey: 'sort_order',
- header: '#',
- size: 50,
- enableEditing: false,
- Cell: ({ cell, row }) => {
- const handleClick = useCallback(() => {
- onCellNumberClick(row.id);
- }, [row.id, onCellNumberClick]);
+ const rowNumber = {
+ accessorKey: 'sort_order',
+ header: '#',
+ size: 50,
+ enableEditing: false,
+ Cell: ({ cell, row }) => {
+ const handleClick = useCallback(() => {
+ onCellNumberClick(row.id);
+ }, [row.id, onCellNumberClick]);
- return ;
- },
- };
+ return ;
+ },
+ };
- return [rowNumber, ...columns];
-};
\ No newline at end of file
+ return [rowNumber, ...columns];
+};