diff --git a/web/src/components/RealtimeTable/RealtimeTable.jsx b/web/src/components/RealtimeTable/RealtimeTable.jsx index 2cebd56..73b574e 100644 --- a/web/src/components/RealtimeTable/RealtimeTable.jsx +++ b/web/src/components/RealtimeTable/RealtimeTable.jsx @@ -35,8 +35,10 @@ import { CreateProgramModal } from './Modals/CreateProgramProjectModal'; import { FormsNoCanAddRow } from './constants/formConfig'; import { DictVspApi } from '../../api/dict-vsp'; +import { useAuth } from '../../app/context/AuthProvider'; const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => { + const { user } = useAuth(); const { data, setData, columnsCurStage, isLoading: isTableLoading, editingCells: dataEditingCells } = useRealtimeData(formId, sheetName, direction, formType, year); const [globalFilter, setGlobalFilter] = useState(''); const [showColumnFilters, setShowColumnFilters] = useState(false); @@ -215,6 +217,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => { EditCell, columnsConfig, columnsCurStage, + user, onCellUpdate: handleUpdateCell, onCellNumberClick: handleClickRowCell, onCellUpdateError: handleCellUpdateError, @@ -227,6 +230,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => { }, [ columnsConfig, columnsCurStage, + user, handleCellUpdateError, handleClickRowCell, handleUpdateCell, diff --git a/web/src/components/RealtimeTable/constants/PROJECT/CURRENT_EXPENSES.js b/web/src/components/RealtimeTable/constants/PROJECT/CURRENT_EXPENSES.js index 4efa3aa..247361b 100644 --- a/web/src/components/RealtimeTable/constants/PROJECT/CURRENT_EXPENSES.js +++ b/web/src/components/RealtimeTable/constants/PROJECT/CURRENT_EXPENSES.js @@ -279,7 +279,7 @@ export const config = { accessorKey: 'otchet_ob_ispolnenii_tekuschikh_raskhodov_v_i_kvartale_korrektirovka_limita', columns: [ { - header: 'По статьям сметы *', + header: 'По статьям сметы*', accessorKey: 'data.q1.adj_by_items', columnLetter: 'E', size: 180, @@ -292,7 +292,7 @@ export const config = { }, }, { - header: 'Увеличение сметы **', + header: 'Увеличение сметы**', accessorKey: 'data.q1.adj_increase', columnLetter: 'F', size: 200, @@ -368,7 +368,7 @@ export const config = { }, }, { - header: 'За', + header: 'За март', accessorKey: 'data.q1.m3', columnLetter: 'J', size: 150, @@ -462,7 +462,7 @@ export const config = { accessorKey: 'otchet_ob_ispolnenii_tekuschikh_raskhodov_v_ii_kvartale_korrektirovka_limita', columns: [ { - header: 'По статьям сметы *', + header: 'По статьям сметы*', accessorKey: 'data.q2.adj_by_items', columnLetter: 'O', size: 180, @@ -475,7 +475,7 @@ export const config = { }, }, { - header: 'Увеличение сметы **', + header: 'Увеличение сметы**', accessorKey: 'data.q2.adj_increase', columnLetter: 'P', size: 200, @@ -551,7 +551,7 @@ export const config = { }, }, { - header: 'За', + header: 'За июнь', accessorKey: 'data.q2.m3', columnLetter: 'T', size: 150, @@ -645,7 +645,7 @@ export const config = { accessorKey: 'otchet_ob_ispolnenii_tekuschikh_raskhodov_v_iii_kvartale_korrektirovka_limita', columns: [ { - header: 'По статьям сметы *', + header: 'По статьям сметы*', accessorKey: 'data.q3.adj_by_items', columnLetter: 'Y', size: 180, @@ -658,7 +658,7 @@ export const config = { }, }, { - header: 'Увеличение сметы **', + header: 'Увеличение сметы**', accessorKey: 'data.q3.adj_increase', columnLetter: 'Z', size: 200, @@ -734,7 +734,7 @@ export const config = { }, }, { - header: 'За', + header: 'За сентябрь', accessorKey: 'data.q3.m3', columnLetter: 'AD', size: 150, @@ -828,7 +828,7 @@ export const config = { accessorKey: 'otchet_ob_ispolnenii_tekuschikh_raskhodov_v_iv_kvartale_korrektirovka_limita', columns: [ { - header: 'По статьям сметы *', + header: 'По статьям сметы*', accessorKey: 'data.q4.adj_by_items', columnLetter: 'AI', size: 180, @@ -841,7 +841,7 @@ export const config = { }, }, { - header: 'Увеличение сметы **', + header: 'Увеличение сметы**', accessorKey: 'data.q4.adj_increase', columnLetter: 'AJ', size: 200, @@ -917,7 +917,7 @@ export const config = { }, }, { - header: 'За', + header: 'За декабрь', accessorKey: 'data.q4.m3', columnLetter: 'AN', size: 150, diff --git a/web/src/components/RealtimeTable/constants/tableConfig.js b/web/src/components/RealtimeTable/constants/tableConfig.js index 41fd6a6..49cfedc 100644 --- a/web/src/components/RealtimeTable/constants/tableConfig.js +++ b/web/src/components/RealtimeTable/constants/tableConfig.js @@ -28,6 +28,10 @@ export const BASE_TABLE_CONFIG = { defaultColumn: { filterFn: 'contains' }, columnResizeMode: 'onChange', localization: { + expand: 'Раскрыть', + expandAll: 'Раскрыть все', + collapse: 'Свернуть', + collapseAll: 'Свернуть все', noRecordsToDisplay: Нет данных для отображения, }, }; diff --git a/web/src/components/RealtimeTable/tableColumns.jsx b/web/src/components/RealtimeTable/tableColumns.jsx index 5c3c912..fb39e49 100644 --- a/web/src/components/RealtimeTable/tableColumns.jsx +++ b/web/src/components/RealtimeTable/tableColumns.jsx @@ -5,7 +5,6 @@ import { useRealtime } from './contexts/RealtimeContext'; import { sectionCodeColor } from './constants/columnConfig'; import { blueColumn, greenColumn } from './constants/columnColors'; -import { useAuth } from '../../app/context/AuthProvider'; import { ROLES_NAME_ID } from '../../constants/constants'; import VspDropdownEditCell from './Cell/EditCell/VspDropdownEditCell'; @@ -94,18 +93,38 @@ const EditCellPortal = React.memo(({ }); function getColorCell(colors, column, row) { - if (row.original.data.section_code) { - const section_code = row.original.data.section_code[0]; - return (sectionCodeColor[section_code] || blueColumn)[row.original?.row_type || row.row_type]; + const rowType = row?.original?.row_type || row?.row_type; + const sectionCodeValue = + row?.original?.data?.section_code ?? row?.original?.data?.header?.section_code; + + if (sectionCodeValue !== null && sectionCodeValue !== undefined && sectionCodeValue !== '') { + const sectionCode = String(sectionCodeValue)[0]; + return (sectionCodeColor[sectionCode] || blueColumn)[rowType]; } - return colors[column.id]?.color_type?.[row.original?.row_type || row.row_type]; + + return colors[column.id]?.color_type?.[rowType]; } +const UPPERCASE_MONTH_PATTERN = + /ЯНВАРЬ|ФЕВРАЛЬ|МАРТ|АПРЕЛЬ|МАЙ|ИЮНЬ|ИЮЛЬ|АВГУСТ|СЕНТЯБРЬ|ОКТЯБРЬ|НОЯБРЬ|ДЕКАБРЬ/g; + +const normalizeMonthHeader = (header) => { + if (typeof header !== 'string') return header; + + return header.replace(UPPERCASE_MONTH_PATTERN, (month, offset) => { + const normalizedMonth = month.toLowerCase(); + if (offset !== 0) return normalizedMonth; + + return normalizedMonth[0].toUpperCase() + normalizedMonth.slice(1); + }); +}; + export const getTableColumns = ({ Cell, EditCell, columnsConfig, columnsCurStage, + user, onCellUpdateError, onCellNumberClick, isCellInvalid, @@ -113,8 +132,6 @@ export const getTableColumns = ({ const columnColors = { ...columnsConfig.colors }; const columns = structuredClone(columnsConfig.columns); - const { user } = useAuth(); - const cellPropsCache = new WeakMap(); const editPropsCache = new WeakMap(); @@ -130,6 +147,9 @@ export const getTableColumns = ({ const key = `${row.id}_${column.id}`; const value = row.getValue(column.id); const isInvalid = isCellInvalid?.(column.id, value, row.original) || false; + const isEditableCell = isEditable(row, column); + const backgroundColor = getColorCell(columnColors, column, row); + const isUpdating = table.options.meta?.updatingCells?.[key]; if (!cellPropsCache.has(row)) { cellPropsCache.set(row, {}); @@ -141,12 +161,13 @@ export const getTableColumns = ({ 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 && + cached.backgroundColor === backgroundColor) { + return cached; + } } const globalFilter = table.getState().globalFilter; @@ -155,12 +176,11 @@ export const getTableColumns = ({ const props = { globalFilter, columnFilter, - isEditable: isEditable(row, column), - backgroundColor: getColorCell(columnColors, column, row), - isUpdating: table.options.meta?.updatingCells?.[`${row.id}_${column.id}`], + isEditable: isEditableCell, + backgroundColor, isInvalid, value, - _hash: `${globalFilter}_${columnFilter}_${row.id}_${column.id}_${value}_${isInvalid}`, + _hash: `${globalFilter}_${columnFilter}_${key}_${value}_${isInvalid}_${backgroundColor}`, }; rowCache[key] = props; @@ -190,6 +210,8 @@ export const getTableColumns = ({ // Оптимизированная функция processColumns const processColumns = (columns) => { for (const col of columns) { + col.header = normalizeMonthHeader(col.header); + col.Cell = ({ cell, table, column, row }) => { const { vspOptions } = useRealtime(); const props = getCachedCellProps(row, column, table); @@ -236,7 +258,7 @@ export const getTableColumns = ({ const rowNumber = { accessorKey: 'sort_order', - header: '#', + header: '№', size: 50, enableEditing: false, Cell: ({ cell, row }) => { @@ -248,4 +270,4 @@ export const getTableColumns = ({ }; return [rowNumber, ...columns]; -}; \ No newline at end of file +}; diff --git a/web/src/pages/AdminPanel/UsersPage/UserTableForAdd.jsx b/web/src/pages/AdminPanel/UsersPage/UserTableForAdd.jsx index 838858f..a0b5716 100644 --- a/web/src/pages/AdminPanel/UsersPage/UserTableForAdd.jsx +++ b/web/src/pages/AdminPanel/UsersPage/UserTableForAdd.jsx @@ -281,6 +281,9 @@ const UserTableForAdd = ({ usersEmail = [], sspOptions = [], onDeleteUser, onCha maxHeight: '18.38rem', }, }, + localization: { + noRecordsToDisplay: 'Нет данных для отображения', + }, enableRowNumbers: false, muiToolbarAlertBannerProps: false, }); diff --git a/web/src/pages/ProjectPages/SummaryPage.jsx b/web/src/pages/ProjectPages/SummaryPage.jsx index 7802348..4e63921 100644 --- a/web/src/pages/ProjectPages/SummaryPage.jsx +++ b/web/src/pages/ProjectPages/SummaryPage.jsx @@ -472,6 +472,13 @@ const SummaryPage = () => { columns: firstColumns, data: filteredData, ...projectsTableOptions, + localization: { + expand: 'Раскрыть', + expandAll: 'Раскрыть все', + collapse: 'Свернуть', + collapseAll: 'Свернуть все', + noRecordsToDisplay: 'Нет данных для отображения', + }, initialState: { columnPinning: { right: ['actions'], left: ['mrt-row-expand', 'project'] }, }, @@ -482,6 +489,9 @@ const SummaryPage = () => { columns: secondColumns, data: summaryData, ...summaryProjectTableOptions, + localization: { + noRecordsToDisplay: 'Нет данных для отображения', + }, initialState: { columnPinning: { left: ['data.header.name'] }, },