Compare commits

...

3 Commits

Author SHA1 Message Date
PotapovaA
a23a2dffc6 865 2026-07-02 17:31:23 +03:00
PotapovaA
cc62551c92 1134 2026-07-02 16:07:44 +03:00
PotapovaA
40c373b5ed projects 2026-07-02 15:35:44 +03:00
30 changed files with 5847 additions and 5629 deletions

View File

@ -21,7 +21,7 @@ export const DictVspApi = {
responseType: "blob", responseType: "blob",
}); });
}, },
getDropdownVsp(params){ getDropdownVsp(params) {
return api.get(`/dict/info/dropdown`, params).then((r) => r.data); return api.get(`/dict/info/dropdown`, { params }).then((r) => r.data);
} },
}; };

View File

@ -21,19 +21,14 @@ export const ProjectsApi = {
return api.delete(`/projects/${id}`).then((r) => r.data); return api.delete(`/projects/${id}`).then((r) => r.data);
}, },
getTasks: (projectId) => { getTableData: (id, sheetName, year) => {
return api.get(`/projects/${projectId}/tasks`).then((r) => r.data);
},
addTask: (projectId, taskId) => {
return api return api
.post(`/projects/${projectId}/tasks/${taskId}`) .get(`/projects/${id}/report/${year}/${sheetName}`)
.then((r) => r.data); .then((r) => r.data);
}, },
export: (id, year, sheetName) => {
removeTask: (projectId, taskId) => { return api.get(`/export/project/${id}/report/${year}/${sheetName}`, {
return api responseType: "blob",
.delete(`/projects/${projectId}/tasks/${taskId}`) });
.then((r) => r.data);
}, },
}; };

View File

@ -52,7 +52,7 @@ export const AppRoutes = () => {
<Route path="/new-table" element={<NewTablePage />} /> <Route path="/new-table" element={<NewTablePage />} />
<Route path="/tables-new" element={<TablesTest />} /> <Route path="/tables-new" element={<TablesTest />} />
<Route path="/tables/:form/:sheetName" element={<NewFormTablePage />} /> <Route path="/tables/:form/:sheetName" element={<NewFormTablePage />} />
<Route path="/table/form/:formId/form-type/:formType/:sheetName/:direction" element={<NewFormTablePage />} /> <Route path="/table/form/:formId/form-type/:formType/:sheetName/:direction/:year" element={<NewFormTablePage />} />
</Route> </Route>
</Route> </Route>
</Routes> </Routes>

View File

@ -31,12 +31,13 @@ const LockBadge = styled.div`
`; `;
// Функция для подсветки текста // Функция для подсветки текста
const highlightText = (text, searchQuery) => { const highlightText = (text, searchQueries) => {
if (!searchQuery || !text) return text; if (!text) return text;
const cleanSearchQueries = searchQueries.filter(q => (q !== undefined && q !== ''));
const escapedQuery = searchQuery.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); if (cleanSearchQueries.length == 0) return text;
const regex = new RegExp(`(${escapedQuery})`, 'gi');
const escapedQueries = cleanSearchQueries.map(query => query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
const regex = new RegExp(`(${ escapedQueries.join('|')})`, 'gi');
const parts = text.split(regex); const parts = text.split(regex);
return parts.map((part, index) => return parts.map((part, index) =>
@ -89,7 +90,7 @@ const formatNumber = (value, asInteger = false) => {
}); });
}; };
const Cell = React.memo(({ cell, row, column, onClick, globalFilter, backgroundColor, color, isEditable }) => { const Cell = React.memo(({ cell, row, column, onClick, globalFilter, columnFilter, backgroundColor, color, isEditable }) => {
const { lockedCells } = useRealtime(); const { lockedCells } = useRealtime();
const cellKey = `${row.id}_${column.id}`; const cellKey = `${row.id}_${column.id}`;
@ -105,9 +106,10 @@ const Cell = React.memo(({ cell, row, column, onClick, globalFilter, backgroundC
} }
const highlightedContent = useMemo(() => { const highlightedContent = useMemo(() => {
return highlightText(textValue, globalFilter); return highlightText(textValue, [globalFilter, columnFilter]);
}, [textValue, globalFilter]); }, [textValue, globalFilter]);
// Базовые стили для заблокированной ячейки // Базовые стили для заблокированной ячейки
const lockedStyles = isLocked ? { const lockedStyles = isLocked ? {
border: '2px solid #e0e0e0', border: '2px solid #e0e0e0',

View File

@ -29,8 +29,8 @@ import { additionVspRowTable } from './constants/addingRowConfig';
import { SelectVspModal } from './Modals/SelectVspModal'; import { SelectVspModal } from './Modals/SelectVspModal';
import { getRowId } from './utils/rowUtils'; import { getRowId } from './utils/rowUtils';
const RealtimeTable = ({ formType, formId, sheetName, direction }) => { const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
const { data, setData, isLoading: isTableLoading, editingCells: dataEditingCells } = useRealtimeData(formId, sheetName, direction); const { data, setData, isLoading: isTableLoading, editingCells: dataEditingCells } = useRealtimeData(formId, sheetName, direction, formType, year);
const [globalFilter, setGlobalFilter] = useState(''); const [globalFilter, setGlobalFilter] = useState('');
const [showColumnFilters, setShowColumnFilters] = useState(false); const [showColumnFilters, setShowColumnFilters] = useState(false);
const [selectedColumnId, setSelectedColumnId] = useState(); const [selectedColumnId, setSelectedColumnId] = useState();
@ -229,6 +229,12 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
minHeight: '1px', minHeight: '1px',
maxHeight: '1px', maxHeight: '1px',
visibility: 'hidden', visibility: 'hidden',
'& svg': {
height: '1px',
minHeight: '1px',
maxHeight: '1px',
visibility: 'hidden',
}
}, },
}, },
muiTablePaperProps: getTablePaperStyles(), muiTablePaperProps: getTablePaperStyles(),
@ -360,6 +366,8 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
formId={formId} formId={formId}
sheetName={sheetName} sheetName={sheetName}
direction={direction} direction={direction}
year={year}
isProject={formType == 'PROJECT'}
/> />
<div style={tableWrapperStyle}> <div style={tableWrapperStyle}>
@ -420,8 +428,6 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
onClose={() => setIsOpenModalSelectVsp(false)} onClose={() => setIsOpenModalSelectVsp(false)}
formId={formId} formId={formId}
onSelect={handleAddVspRow} onSelect={handleAddVspRow}
// vspOptions={}
// selectedVSP={}
title="Выбор ВСП" title="Выбор ВСП"
/> />
</> </>

View File

@ -18,7 +18,7 @@ import CollapsibleTree from '../../common/CollapsibleTree';
import ZoomSlider from './ZoomSlider'; import ZoomSlider from './ZoomSlider';
import SearchComponent from '../../common/SearchComponent'; import SearchComponent from '../../common/SearchComponent';
import { ExportDefaultButton } from '../../common/Buttons/ButtonsActions'; import { ExportDefaultButton } from '../../common/Buttons/ButtonsActions';
import { exportSheet } from '../../../utils/exportForm'; import { exportSheet, exportSheetProject } from '../../../utils/exportFile';
const SettingPanel = ({ const SettingPanel = ({
selectedColumnId, selectedColumnId,
@ -39,6 +39,8 @@ const SettingPanel = ({
formId, formId,
sheetName, sheetName,
direction, direction,
year,
isProject,
}) => { }) => {
const [isPinned, setIsPinned] = useState(false); const [isPinned, setIsPinned] = useState(false);
const [isExporting, setIsExporting] = useState(false); const [isExporting, setIsExporting] = useState(false);
@ -76,7 +78,16 @@ const SettingPanel = ({
const handleClickDeleteFormula = () => { }; const handleClickDeleteFormula = () => { };
const handleExport = async () => { const handleExport = async () => {
if (!formId || !sheetName || isExporting) return; if (isExporting) return;
if (isProject) {
if (!formId || !sheetName || !year) return;
setIsExporting(true);
await exportSheetProject(formId, sheetName, year);
setIsExporting(false);
return;
}
if (!formId || !sheetName) return;
setIsExporting(true); setIsExporting(true);
await exportSheet(formId, sheetName, direction); await exportSheet(formId, sheetName, direction);
setIsExporting(false); setIsExporting(false);
@ -115,40 +126,27 @@ const SettingPanel = ({
</Tooltip> </Tooltip>
</GroupByObject> </GroupByObject>
<Divider orientation="vertical" flexItem />
<GroupByObject title="Строки"> {!isProject ??
<Tooltip title="Добавить строку"> <>
<IconButton onClick={onAddRow} variant="outlined"> <Divider orientation="vertical" flexItem />
<Plus /> <GroupByObject title="Строки">
<AddLine /> <Tooltip title="Добавить строку">
</IconButton> <IconButton onClick={onAddRow} variant="outlined">
</Tooltip> <Plus />
<AddLine />
</IconButton>
</Tooltip>
<Tooltip title="Удалить строку"> <Tooltip title="Удалить строку">
<IconButton onClick={onDeleteRow} variant="outlined"> <IconButton onClick={onDeleteRow} variant="outlined">
<Minus /> <Minus />
<RemoveLine /> <RemoveLine />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
</GroupByObject> </GroupByObject>
</>
{/* <Divider orientation="vertical" flexItem /> }
<GroupByObject title="Формулы">
<Tooltip title="Добавить формулу">
<IconButton onClick={handleClickAddFormula} variant="outlined">
<FormulaSettingPanel />
</IconButton>
</Tooltip>
<Tooltip title="Удалить формулу">
<IconButton onClick={handleClickDeleteFormula} variant="outlined">
<Minus />
<FormulaSettingPanel />
</IconButton>
</Tooltip>
</GroupByObject> */}
<Divider orientation="vertical" flexItem /> <Divider orientation="vertical" flexItem />
<GroupByObject title="Столбцы"> <GroupByObject title="Столбцы">
{columns ? ( {columns ? (

View File

@ -313,10 +313,10 @@ const FilterCell = ({ column, table }) => {
onChange={(e) => handleFilterChange(e.target.value)} onChange={(e) => handleFilterChange(e.target.value)}
style={{ style={{
width: '100%', width: '100%',
padding: '4px 6px', padding: '0.25rem 0.375rem',
fontSize: '11px', fontSize: '0.6875rem',
border: '1px solid #ddd', border: '1px solid #ddd',
borderRadius: '4px', borderRadius: '0.25rem',
backgroundColor: 'white', backgroundColor: 'white',
}} }}
> >
@ -330,23 +330,30 @@ const FilterCell = ({ column, table }) => {
); );
case 'range': { case 'range': {
// Для диапазона можно реализовать два поля
const [min, max] = column.getFilterValue() || ['', '']; const [min, max] = column.getFilterValue() || ['', ''];
return ( return (
<div style={{ display: 'flex', gap: '4px' }}> <div style={{ display: 'flex', gap: '0.25rem' }}> {/* 4px */}
<input <input
type="number" type="number"
placeholder="От" placeholder="От"
value={min} value={min}
onChange={(e) => column.setFilterValue([e.target.value, max])} onChange={(e) => column.setFilterValue([e.target.value, max])}
style={{ width: '50%', padding: '4px', fontSize: '11px' }} style={{
width: '50%',
padding: '0.25rem',
fontSize: '0.6875rem'
}}
/> />
<input <input
type="number" type="number"
placeholder="До" placeholder="До"
value={max} value={max}
onChange={(e) => column.setFilterValue([min, e.target.value])} onChange={(e) => column.setFilterValue([min, e.target.value])}
style={{ width: '50%', padding: '4px', fontSize: '11px' }} style={{
width: '50%',
padding: '0.25rem',
fontSize: '0.6875rem'
}}
/> />
</div> </div>
); );
@ -361,10 +368,10 @@ const FilterCell = ({ column, table }) => {
placeholder="Поиск..." placeholder="Поиск..."
style={{ style={{
width: '100%', width: '100%',
padding: '4px 6px', padding: '0.25rem 0.375rem',
fontSize: '11px', fontSize: '0.6875rem',
border: '1px solid #ddd', border: '1px solid #ddd',
borderRadius: '4px', borderRadius: '0.25rem',
boxSizing: 'border-box', boxSizing: 'border-box',
}} }}
/> />

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,555 +0,0 @@
import {
greenColumn,
whiteColumn,
orangeColumn,
yellowColumn,
redColumn,
blueColumn,
} from '../columnColors';
export const config = {
"config":{
"colors":{
"kod_razdela_kod_razdela":{
"color_type":whiteColumn,
"accessorKey":"kod_razdela_kod_razdela"
},
"id_stati_id_stati":{
"color_type":whiteColumn,
"accessorKey":"id_stati_id_stati"
},
"id_gruppy_nomenklatury_id_gruppy_nomenklatury":{
"color_type":whiteColumn,
"accessorKey":"id_gruppy_nomenklatury_id_gruppy_nomenklatury"
},
"naimenovanie_naimenovanie":{
"color_type":whiteColumn,
"accessorKey":"naimenovanie_naimenovanie"
},
"korrektirovka_limita_po_statyam_smety":{
"color_type":whiteColumn,
"accessorKey":"korrektirovka_limita_po_statyam_smety"
},
"field_uvelichenie_smety":{
"color_type":whiteColumn,
"accessorKey":"field_uvelichenie_smety"
},
"field_za_yanvar":{
"color_type":whiteColumn,
"accessorKey":"field_za_yanvar"
},
"field_za_fevral":{
"color_type":whiteColumn,
"accessorKey":"field_za_fevral"
},
"field_itogo_i_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_i_kvartal"
},
"field_za_aprel":{
"color_type":whiteColumn,
"accessorKey":"field_za_aprel"
},
"field_za_may":{
"color_type":whiteColumn,
"accessorKey":"field_za_may"
},
"field_itogo_ii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_ii_kvartal"
},
"field_za_iyul":{
"color_type":whiteColumn,
"accessorKey":"field_za_iyul"
},
"field_za_avgust":{
"color_type":whiteColumn,
"accessorKey":"field_za_avgust"
},
"field_itogo_iii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_iii_kvartal"
},
"field_za_oktyabr":{
"color_type":whiteColumn,
"accessorKey":"field_za_oktyabr"
},
"field_za_noyabr":{
"color_type":whiteColumn,
"accessorKey":"field_za_noyabr"
},
"field_spod":{
"color_type":whiteColumn,
"accessorKey":"field_spod"
},
"field_itogo_iv_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_iv_kvartal"
},
"itogo_itogo":{
"color_type":whiteColumn,
"accessorKey":"itogo_itogo"
},
"fakt_zamart":{
"color_type":whiteColumn,
"accessorKey":"fakt_zamart"
},
"fakt_zaiyun":{
"color_type":whiteColumn,
"accessorKey":"fakt_zaiyun"
},
"fakt_zasentyabr":{
"color_type":whiteColumn,
"accessorKey":"fakt_zasentyabr"
},
"fakt_zadekabr":{
"color_type":whiteColumn,
"accessorKey":"fakt_zadekabr"
},
"ekonomiya_pereraskhod_ekonomiya_pereraskhod":{
"color_type":whiteColumn,
"accessorKey":"ekonomiya_pereraskhod_ekonomiya_pereraskhod"
},
"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal"
},
"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal"
},
"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal":{
"color_type":whiteColumn,
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal"
}
},
"columns":[
{
"header":"Код раздела",
"accessorKey":"kod_razdela",
"columns":[
{
"header":"Код раздела",
"accessorKey":"kod_razdela_kod_razdela",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"ID статьи",
"accessorKey":"id_stati",
"columns":[
{
"header":"ID статьи",
"accessorKey":"id_stati_id_stati",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"ID группы номенклатуры",
"accessorKey":"id_gruppy_nomenklatury",
"columns":[
{
"header":"ID группы номенклатуры",
"accessorKey":"id_gruppy_nomenklatury_id_gruppy_nomenklatury",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Наименование",
"accessorKey":"naimenovanie",
"columns":[
{
"header":"Наименование",
"accessorKey":"naimenovanie_naimenovanie",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Корректировка лимита",
"accessorKey":"korrektirovka_limita",
"columns":[
{
"header":"по статьям сметы *",
"accessorKey":"korrektirovka_limita_po_statyam_smety",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"",
"accessorKey":"field",
"columns":[
{
"header":"увеличение сметы **",
"accessorKey":"field_uvelichenie_smety",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ЯНВАРЬ",
"accessorKey":"field_za_yanvar",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ФЕВРАЛЬ",
"accessorKey":"field_za_fevral",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого I квартал",
"accessorKey":"field_itogo_i_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за АПРЕЛЬ",
"accessorKey":"field_za_aprel",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за МАЙ",
"accessorKey":"field_za_may",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого II квартал",
"accessorKey":"field_itogo_ii_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ИЮЛЬ",
"accessorKey":"field_za_iyul",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за АВГУСТ",
"accessorKey":"field_za_avgust",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого III квартал",
"accessorKey":"field_itogo_iii_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ОКТЯБРЬ",
"accessorKey":"field_za_oktyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за НОЯБРЬ",
"accessorKey":"field_za_noyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"СПОД",
"accessorKey":"field_spod",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого IV квартал",
"accessorKey":"field_itogo_iv_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого",
"accessorKey":"itogo",
"columns":[
{
"header":"Итого",
"accessorKey":"itogo_itogo",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Факт",
"accessorKey":"fakt",
"columns":[
{
"header":"заМАРТ",
"accessorKey":"fakt_zamart",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заИЮНЬ",
"accessorKey":"fakt_zaiyun",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заСЕНТЯБРЬ",
"accessorKey":"fakt_zasentyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заДЕКАБРЬ",
"accessorKey":"fakt_zadekabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"экономия (+) перерасход (-)",
"accessorKey":"ekonomiya_pereraskhod",
"columns":[
{
"header":"экономия (+) перерасход (-)",
"accessorKey":"ekonomiya_pereraskhod_ekonomiya_pereraskhod",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Лимит затрат / остаток лимита затрат на II квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal",
"columns":[
{
"header":"Лимит затрат / остаток лимита затрат на II квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Лимит затрат / остаток лимита затрат на III квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal",
"columns":[
{
"header":"Лимит затрат / остаток лимита затрат на III квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Лимит затрат / остаток лимита затрат на IV квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal",
"columns":[
{
"header":"Лимит затрат / остаток лимита затрат на IV квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
]
}
}

View File

@ -1,577 +0,0 @@
import {
greenColumn,
whiteColumn,
orangeColumn,
yellowColumn,
redColumn,
blueColumn,
} from '../columnColors';
export const config = {
"config":{
"colors":{
"kod_razdela_kod_razdela":{
"color_type":whiteColumn,
"accessorKey":"kod_razdela_kod_razdela"
},
"id_stati_id_stati":{
"color_type":whiteColumn,
"accessorKey":"id_stati_id_stati"
},
"id_gruppy_nomenklatury_id_gruppy_nomenklatury":{
"color_type":whiteColumn,
"accessorKey":"id_gruppy_nomenklatury_id_gruppy_nomenklatury"
},
"naimenovanie_naimenovanie":{
"color_type":whiteColumn,
"accessorKey":"naimenovanie_naimenovanie"
},
"korrektirovka_plana_po_statyam_smety":{
"color_type":whiteColumn,
"accessorKey":"korrektirovka_plana_po_statyam_smety"
},
"field_uvelichenie_smety":{
"color_type":whiteColumn,
"accessorKey":"field_uvelichenie_smety"
},
"field_za_yanvar":{
"color_type":whiteColumn,
"accessorKey":"field_za_yanvar"
},
"field_za_fevral":{
"color_type":whiteColumn,
"accessorKey":"field_za_fevral"
},
"field_itogo_i_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_i_kvartal"
},
"field_za_aprel":{
"color_type":whiteColumn,
"accessorKey":"field_za_aprel"
},
"field_za_may":{
"color_type":whiteColumn,
"accessorKey":"field_za_may"
},
"field_itogo_ii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_ii_kvartal"
},
"field_za_iyul":{
"color_type":whiteColumn,
"accessorKey":"field_za_iyul"
},
"field_za_avgust":{
"color_type":whiteColumn,
"accessorKey":"field_za_avgust"
},
"field_itogo_iii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_iii_kvartal"
},
"field_za_oktyabr":{
"color_type":whiteColumn,
"accessorKey":"field_za_oktyabr"
},
"field_za_noyabr":{
"color_type":whiteColumn,
"accessorKey":"field_za_noyabr"
},
"field_spod":{
"color_type":whiteColumn,
"accessorKey":"field_spod"
},
"field_itogo_iv_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_iv_kvartal"
},
"itogo_korrektirovka_itogo_korrektirovka":{
"color_type":whiteColumn,
"accessorKey":"itogo_korrektirovka_itogo_korrektirovka"
},
"fakt_zamart":{
"color_type":whiteColumn,
"accessorKey":"fakt_zamart"
},
"fakt_zaiyun":{
"color_type":whiteColumn,
"accessorKey":"fakt_zaiyun"
},
"fakt_zasentyabr":{
"color_type":whiteColumn,
"accessorKey":"fakt_zasentyabr"
},
"fakt_zadekabr":{
"color_type":whiteColumn,
"accessorKey":"fakt_zadekabr"
},
"ekonomiya_pereraskhod_ekonomiya_pereraskhod":{
"color_type":whiteColumn,
"accessorKey":"ekonomiya_pereraskhod_ekonomiya_pereraskhod"
},
"smeta_raskhodov_po_razvitiyu_na_ii_kvartal_smeta_raskhodov_po_razvitiyu_na_ii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_ii_kvartal_smeta_raskhodov_po_razvitiyu_na_ii_kvartal"
},
"itogo_skorrek_smeta_itogo_skorrek_smeta":{
"color_type":whiteColumn,
"accessorKey":"itogo_skorrek_smeta_itogo_skorrek_smeta"
},
"smeta_raskhodov_po_razvitiyu_na_iii_kvartal_smeta_raskhodov_po_razvitiyu_na_iii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_iii_kvartal_smeta_raskhodov_po_razvitiyu_na_iii_kvartal"
},
"smeta_raskhodov_po_razvitiyu_na_iv_kvartal_smeta_raskhodov_po_razvitiyu_na_iv_kvartal":{
"color_type":whiteColumn,
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_iv_kvartal_smeta_raskhodov_po_razvitiyu_na_iv_kvartal"
}
},
"columns":[
{
"header":"Код раздела",
"accessorKey":"kod_razdela",
"columns":[
{
"header":"Код раздела",
"accessorKey":"kod_razdela_kod_razdela",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"ID статьи",
"accessorKey":"id_stati",
"columns":[
{
"header":"ID статьи",
"accessorKey":"id_stati_id_stati",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"ID группы номенклатуры",
"accessorKey":"id_gruppy_nomenklatury",
"columns":[
{
"header":"ID группы номенклатуры",
"accessorKey":"id_gruppy_nomenklatury_id_gruppy_nomenklatury",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Наименование",
"accessorKey":"naimenovanie",
"columns":[
{
"header":"Наименование",
"accessorKey":"naimenovanie_naimenovanie",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Корректировка плана",
"accessorKey":"korrektirovka_plana",
"columns":[
{
"header":"по статьям сметы *",
"accessorKey":"korrektirovka_plana_po_statyam_smety",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"",
"accessorKey":"field",
"columns":[
{
"header":"увеличение сметы **",
"accessorKey":"field_uvelichenie_smety",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ЯНВАРЬ",
"accessorKey":"field_za_yanvar",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ФЕВРАЛЬ",
"accessorKey":"field_za_fevral",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого I квартал",
"accessorKey":"field_itogo_i_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за АПРЕЛЬ",
"accessorKey":"field_za_aprel",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за МАЙ",
"accessorKey":"field_za_may",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого II квартал",
"accessorKey":"field_itogo_ii_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ИЮЛЬ",
"accessorKey":"field_za_iyul",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за АВГУСТ",
"accessorKey":"field_za_avgust",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого III квартал",
"accessorKey":"field_itogo_iii_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ОКТЯБРЬ",
"accessorKey":"field_za_oktyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за НОЯБРЬ",
"accessorKey":"field_za_noyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"СПОД",
"accessorKey":"field_spod",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого IV квартал",
"accessorKey":"field_itogo_iv_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого корректировка",
"accessorKey":"itogo_korrektirovka",
"columns":[
{
"header":"Итого корректировка",
"accessorKey":"itogo_korrektirovka_itogo_korrektirovka",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Факт",
"accessorKey":"fakt",
"columns":[
{
"header":"заМАРТ",
"accessorKey":"fakt_zamart",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заИЮНЬ",
"accessorKey":"fakt_zaiyun",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заСЕНТЯБРЬ",
"accessorKey":"fakt_zasentyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заДЕКАБРЬ",
"accessorKey":"fakt_zadekabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"экономия (+) перерасход (-)",
"accessorKey":"ekonomiya_pereraskhod",
"columns":[
{
"header":"экономия (+) перерасход (-)",
"accessorKey":"ekonomiya_pereraskhod_ekonomiya_pereraskhod",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Смета расходов по развитию на II квартал",
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_ii_kvartal",
"columns":[
{
"header":"Смета расходов по развитию на II квартал",
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_ii_kvartal_smeta_raskhodov_po_razvitiyu_na_ii_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого скоррек. смета",
"accessorKey":"itogo_skorrek_smeta",
"columns":[
{
"header":"Итого скоррек. смета",
"accessorKey":"itogo_skorrek_smeta_itogo_skorrek_smeta",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Смета расходов по развитию на III квартал",
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_iii_kvartal",
"columns":[
{
"header":"Смета расходов по развитию на III квартал",
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_iii_kvartal_smeta_raskhodov_po_razvitiyu_na_iii_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Смета расходов по развитию на IV квартал",
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_iv_kvartal",
"columns":[
{
"header":"Смета расходов по развитию на IV квартал",
"accessorKey":"smeta_raskhodov_po_razvitiyu_na_iv_kvartal_smeta_raskhodov_po_razvitiyu_na_iv_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
]
}
}

View File

@ -1,555 +0,0 @@
import {
greenColumn,
whiteColumn,
orangeColumn,
yellowColumn,
redColumn,
blueColumn,
} from '../columnColors';
export const config = {
"config":{
"colors":{
"kod_razdela_kod_razdela":{
"color_type":whiteColumn,
"accessorKey":"kod_razdela_kod_razdela"
},
"id_stati_id_stati":{
"color_type":whiteColumn,
"accessorKey":"id_stati_id_stati"
},
"id_gruppy_nomenklatury_id_gruppy_nomenklatury":{
"color_type":whiteColumn,
"accessorKey":"id_gruppy_nomenklatury_id_gruppy_nomenklatury"
},
"naimenovanie_naimenovanie":{
"color_type":whiteColumn,
"accessorKey":"naimenovanie_naimenovanie"
},
"korrektirovka_limita_po_statyam_smety":{
"color_type":whiteColumn,
"accessorKey":"korrektirovka_limita_po_statyam_smety"
},
"field_uvelichenie_smety":{
"color_type":whiteColumn,
"accessorKey":"field_uvelichenie_smety"
},
"field_za_yanvar":{
"color_type":whiteColumn,
"accessorKey":"field_za_yanvar"
},
"field_za_fevral":{
"color_type":whiteColumn,
"accessorKey":"field_za_fevral"
},
"field_itogo_i_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_i_kvartal"
},
"field_za_aprel":{
"color_type":whiteColumn,
"accessorKey":"field_za_aprel"
},
"field_za_may":{
"color_type":whiteColumn,
"accessorKey":"field_za_may"
},
"field_itogo_ii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_ii_kvartal"
},
"field_za_iyul":{
"color_type":whiteColumn,
"accessorKey":"field_za_iyul"
},
"field_za_avgust":{
"color_type":whiteColumn,
"accessorKey":"field_za_avgust"
},
"field_itogo_iii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_iii_kvartal"
},
"field_za_oktyabr":{
"color_type":whiteColumn,
"accessorKey":"field_za_oktyabr"
},
"field_za_noyabr":{
"color_type":whiteColumn,
"accessorKey":"field_za_noyabr"
},
"field_spod":{
"color_type":whiteColumn,
"accessorKey":"field_spod"
},
"field_itogo_iv_kvartal":{
"color_type":whiteColumn,
"accessorKey":"field_itogo_iv_kvartal"
},
"itogo_itogo":{
"color_type":whiteColumn,
"accessorKey":"itogo_itogo"
},
"fakt_zamart":{
"color_type":whiteColumn,
"accessorKey":"fakt_zamart"
},
"fakt_zaiyun":{
"color_type":whiteColumn,
"accessorKey":"fakt_zaiyun"
},
"fakt_zasentyabr":{
"color_type":whiteColumn,
"accessorKey":"fakt_zasentyabr"
},
"fakt_zadekabr":{
"color_type":whiteColumn,
"accessorKey":"fakt_zadekabr"
},
"ekonomiya_pereraskhod_ekonomiya_pereraskhod":{
"color_type":whiteColumn,
"accessorKey":"ekonomiya_pereraskhod_ekonomiya_pereraskhod"
},
"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal"
},
"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal":{
"color_type":whiteColumn,
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal"
},
"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal":{
"color_type":whiteColumn,
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal"
}
},
"columns":[
{
"header":"Код раздела",
"accessorKey":"kod_razdela",
"columns":[
{
"header":"Код раздела",
"accessorKey":"kod_razdela_kod_razdela",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"ID статьи",
"accessorKey":"id_stati",
"columns":[
{
"header":"ID статьи",
"accessorKey":"id_stati_id_stati",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"ID группы номенклатуры",
"accessorKey":"id_gruppy_nomenklatury",
"columns":[
{
"header":"ID группы номенклатуры",
"accessorKey":"id_gruppy_nomenklatury_id_gruppy_nomenklatury",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Наименование",
"accessorKey":"naimenovanie",
"columns":[
{
"header":"Наименование",
"accessorKey":"naimenovanie_naimenovanie",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Корректировка лимита",
"accessorKey":"korrektirovka_limita",
"columns":[
{
"header":"по статьям сметы *",
"accessorKey":"korrektirovka_limita_po_statyam_smety",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"",
"accessorKey":"field",
"columns":[
{
"header":"увеличение сметы **",
"accessorKey":"field_uvelichenie_smety",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ЯНВАРЬ",
"accessorKey":"field_za_yanvar",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ФЕВРАЛЬ",
"accessorKey":"field_za_fevral",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого I квартал",
"accessorKey":"field_itogo_i_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за АПРЕЛЬ",
"accessorKey":"field_za_aprel",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за МАЙ",
"accessorKey":"field_za_may",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого II квартал",
"accessorKey":"field_itogo_ii_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ИЮЛЬ",
"accessorKey":"field_za_iyul",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за АВГУСТ",
"accessorKey":"field_za_avgust",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого III квартал",
"accessorKey":"field_itogo_iii_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за ОКТЯБРЬ",
"accessorKey":"field_za_oktyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"за НОЯБРЬ",
"accessorKey":"field_za_noyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"СПОД",
"accessorKey":"field_spod",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого IV квартал",
"accessorKey":"field_itogo_iv_kvartal",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Итого",
"accessorKey":"itogo",
"columns":[
{
"header":"Итого",
"accessorKey":"itogo_itogo",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Факт",
"accessorKey":"fakt",
"columns":[
{
"header":"заМАРТ",
"accessorKey":"fakt_zamart",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заИЮНЬ",
"accessorKey":"fakt_zaiyun",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заСЕНТЯБРЬ",
"accessorKey":"fakt_zasentyabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"заДЕКАБРЬ",
"accessorKey":"fakt_zadekabr",
"size":150,
"filterFn":"contains",
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"экономия (+) перерасход (-)",
"accessorKey":"ekonomiya_pereraskhod",
"columns":[
{
"header":"экономия (+) перерасход (-)",
"accessorKey":"ekonomiya_pereraskhod_ekonomiya_pereraskhod",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Лимит затрат / остаток лимита затрат на II квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal",
"columns":[
{
"header":"Лимит затрат / остаток лимита затрат на II квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_ii_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Лимит затрат / остаток лимита затрат на III квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal",
"columns":[
{
"header":"Лимит затрат / остаток лимита затрат на III квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iii_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
},
{
"header":"Лимит затрат / остаток лимита затрат на IV квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal",
"columns":[
{
"header":"Лимит затрат / остаток лимита затрат на IV квартал",
"accessorKey":"limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal_limit_zatrat_ostatok_limita_zatrat_na_iv_kvartal",
"size":150,
"filterFn":"contains"
}
],
"muiTableHeadCellProps":{
"sx":{
"backgroundColor":"#C2D69B",
"color":"#000000"
}
}
}
]
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,17 +25,29 @@ export const RealtimeProvider = ({
formId, formId,
sheetName, sheetName,
direction, direction,
year,
userId, userId,
isProject = false,
}) => { }) => {
// Формируем URL (кастомные секреты на фронте пока недоступны, делаем через REACT_APP_ROOT_PATH) // Формируем 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")}/api/v1/ws/form/${formId}/sheet/${sheetName}${direction ? `?direction=${direction}` : ""}`; 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 [lockedCells, setLockedCells] = useState([]);
const handleMessage = useCallback((data) => { const handleMessage = useCallback((data) => {
// Обработка ошибок // Обработка ошибок
if (data.error) { if (data.error) {
console.log(data.error.message) console.log(data.error.message);
toast.error("Server error:" + data.error.message || ''); toast.error("Server error:" + data.error.message || "");
onErrorRef.current?.(data.error); onErrorRef.current?.(data.error);
return; return;
} }
@ -145,6 +157,19 @@ export const RealtimeProvider = ({
} }
}, [isConnected]); }, [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 startEditing = useCallback( const startEditing = useCallback(
async (row, column) => { async (row, column) => {
@ -249,10 +274,9 @@ export const RealtimeProvider = ({
const message = { const message = {
event: "row_added", event: "row_added",
data: rowData, data: rowData,
sheet: sheetName,
form_id: formId,
direction: direction,
}; };
addCommonField(message);
return sendMessage(message); return sendMessage(message);
}, },
[isConnected, sendMessage, sheetName, formId, direction], [isConnected, sendMessage, sheetName, formId, direction],
@ -268,10 +292,8 @@ export const RealtimeProvider = ({
const message = { const message = {
event: "row_deleted", event: "row_deleted",
data: { row_id: rowId }, data: { row_id: rowId },
sheet: sheetName,
form_id: formId,
direction: direction,
}; };
addCommonField(message);
return sendMessage(message); return sendMessage(message);
}, },

View File

@ -4,8 +4,9 @@ import { useRealtime } from "../contexts/RealtimeContext";
import { deleteRow, insertCell, updateCells } from "../utils/cellUtils"; import { deleteRow, insertCell, updateCells } from "../utils/cellUtils";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { isVspNewRow, isVspRow } from "../utils/rowUtils"; import { isVspNewRow, isVspRow } from "../utils/rowUtils";
import { ProjectsApi } from "../../../api/projects";
const useRealtimeData = (formId, sheetName, direction) => { const useRealtimeData = (formId, sheetName, direction, formType, year) => {
const [data, setData] = useState([]); const [data, setData] = useState([]);
const [isConnected, setIsConnected] = useState(false); const [isConnected, setIsConnected] = useState(false);
const [error, setError] = useState(null); const [error, setError] = useState(null);
@ -77,7 +78,10 @@ const useRealtimeData = (formId, sheetName, direction) => {
try { try {
setIsLoading(true); setIsLoading(true);
let res; let res;
if (direction !== null) {
if(formType == 'PROJECT'){
res = await ProjectsApi.getTableData(formId, sheetName, year)
} else if (direction !== null) {
res = await FormsSheetApi.get(formId, sheetName, { res = await FormsSheetApi.get(formId, sheetName, {
params: { direction: direction }, params: { direction: direction },
}); });

View File

@ -107,20 +107,6 @@ export const useWebSocket = (url, onMessage) => {
return false; return false;
}, []); }, []);
const login = useCallback(
(token) => {
if (!token) {
console.warn("No token provided for login");
return false;
}
return sendMessage({
event: "user_login",
data: { token },
});
},
[sendMessage],
);
useEffect(() => { useEffect(() => {
connect(); connect();
return () => disconnect(); return () => disconnect();
@ -130,7 +116,6 @@ export const useWebSocket = (url, onMessage) => {
isConnected: isConnectedRef, isConnected: isConnectedRef,
error, error,
sendMessage, sendMessage,
login,
disconnect, disconnect,
}; };
}; };

View File

@ -112,6 +112,7 @@ export const getTableColumns = ({
globalFilter={ globalFilter={
table.getState().globalFilter table.getState().globalFilter
} }
columnFilter={table.getState().columnFilters?.find(f => f.id === column.id)?.value}
isEditable={row.original?.row_type === 'INPUT' || false} isEditable={row.original?.row_type === 'INPUT' || false}
backgroundColor={columnColors[column.id]?.color_type?.[row.original?.row_type || row.row_type]} backgroundColor={columnColors[column.id]?.color_type?.[row.original?.row_type || row.row_type]}
color={columnColors[column.id]?.color_type?.['COLOR']} color={columnColors[column.id]?.color_type?.['COLOR']}

View File

@ -0,0 +1,33 @@
// components/NavigationToggle.jsx
import React from 'react';
import { Box, Typography } from '@mui/material';
import { PrimaryOutlinedButton } from './Buttons/Buttons'; // Ваш компонент кнопки
const NavigationToggle = ({ currentView, onViewChange }) => {
const handleNavigateToTasks = () => {
onViewChange('/tasks');
};
const handleNavigateToProjects = () => {
onViewChange('/projects');
};
return (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
{currentView === 'tasks' ? (
<PrimaryOutlinedButton onClick={handleNavigateToProjects}>
К проектам
</PrimaryOutlinedButton>
) : (
<PrimaryOutlinedButton onClick={handleNavigateToTasks}>
К задачам
</PrimaryOutlinedButton>
)}
<Typography variant="h6" color="primary" sx={{ fontWeight: 200, fontSize: '1rem' }}>
{currentView === 'tasks' ? 'Управление задачами' : 'Управление проектами'}
</Typography>
</Box>
);
};
export default NavigationToggle;

View File

@ -14,7 +14,7 @@ import {
ExportExitButton, ExportExitButton,
ExportWithTextButton, ExportWithTextButton,
} from './Buttons/ButtonsActions'; } from './Buttons/ButtonsActions';
import { exportBulkForms, exportSingleForm } from '../../utils/exportForm'; import { exportBulkForms, exportSingleForm } from '../../utils/exportFile';
/** /**
* Универсальный компонент для отображения списка с пагинацией и экспортом * Универсальный компонент для отображения списка с пагинацией и экспортом
@ -32,12 +32,13 @@ import { exportBulkForms, exportSingleForm } from '../../utils/exportForm';
* @param {Function} props.getItemTitle - Функция получения заголовка элемента * @param {Function} props.getItemTitle - Функция получения заголовка элемента
* @param {string} props.entityName - Название сущности (для текстов) * @param {string} props.entityName - Название сущности (для текстов)
* @param {string} props.emptyMessage - Сообщение при пустом списке * @param {string} props.emptyMessage - Сообщение при пустом списке
* @param {number} props.skeletonCount - Количество скелетонов * @param {number} props.skeletonCount - Количество силуэтов таблиц при загрузки
* @param {Object} props.extraActions - Дополнительные действия справа * @param {Object} props.extraActions - Дополнительные действия справа
* @param {boolean} props.enableExport - Включить экспорт * @param {boolean} props.enableExport - Включить экспорт
* @param {Array} props.limitOptions - Опции для выбора лимита * @param {Array} props.limitOptions - Опции для выбора лимита
* @param {number} props.maxHeight - Максимальная высота контейнера со скроллом * @param {number} props.maxHeight - Максимальная высота контейнера со скроллом
* @param {boolean} props.enableScroll - Включить скролл для списка * @param {boolean} props.enableScroll - Включить скролл для списка
* @param {boolean} props.filterActions - Элементы фильтрации
*/ */
export function PaginatedList({ export function PaginatedList({
items = [], items = [],
@ -58,6 +59,7 @@ export function PaginatedList({
limitOptions = [10, 20, 50, 100, 200], limitOptions = [10, 20, 50, 100, 200],
maxHeight = 'calc(100vh - 300px)', maxHeight = 'calc(100vh - 300px)',
enableScroll = true, enableScroll = true,
filterActions = null,
}) { }) {
const [exportMode, setExportMode] = useState(false); const [exportMode, setExportMode] = useState(false);
const [exportList, setExportList] = useState([]); const [exportList, setExportList] = useState([]);
@ -104,37 +106,45 @@ export function PaginatedList({
}; };
return ( return (
<Box sx={{ display: 'flex', flexDirection: 'column', height: '100%' }}> <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', width: '100%' }}>
{/* Верхняя панель с экспортом и дополнительными действиями */} {/* Верхняя панель с экспортом и дополнительными действиями */}
{enableExport && ( {enableExport && (
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2, flexShrink: 0 }}> <Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
{exportMode && ( <div>
<Typography variant="body2" color="textSecondary"> {filterActions}
Выделено {entityName}: {exportList.length} </div>
</Typography> <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: '1.5rem' }}>
)} {exportMode && (
<Box sx={{ flex: 1 }} /> <Typography variant="body2" color="textSecondary">
<Stack direction="row" spacing="0.5rem"> Выделено {entityName}: {exportList.length}
{!exportMode ? ( </Typography>
<>
<ExportWithTextButton
text="Пакетный экспорт"
onClick={() => setExportMode(true)}
/>
{extraActions}
</>
) : (
<>
<ExportWithTextButton
text="Экспортировать"
onClick={handleBulkExport}
disabled={exportList.length === 0}
/>
<ExportExitButton onClick={() => setExportMode(false)} />
</>
)} )}
</Stack> <Box sx={{ flex: 1 }} />
<Stack direction="row" spacing="0.5rem">
{!exportMode ? (
<>
<ExportWithTextButton
text="Пакетный экспорт"
onClick={() => setExportMode(true)}
height='2.5rem'
/>
{extraActions}
</>
) : (
<>
<ExportWithTextButton
text="Экспортировать"
onClick={handleBulkExport}
disabled={exportList.length === 0}
height='2.5rem'
/>
<ExportExitButton onClick={() => setExportMode(false)} />
</>
)}
</Stack>
</Box>
</Box> </Box>
)} )}
{/* Контейнер со скроллом для списка */} {/* Контейнер со скроллом для списка */}

View File

@ -6,15 +6,12 @@ import { toast } from 'react-toastify';
const TablesList = ({ const TablesList = ({
filteredTables, filteredTables,
projects,
query, query,
basePath = '/table', basePath = '/table',
formInfo formInfo,
isProject = false,
}) => { }) => {
const navigate = useNavigate(); const navigate = useNavigate();
const isProject = useMemo(() => {
return !!projects;
}, [projects])
const handleNavigate = (path) => { const handleNavigate = (path) => {
navigate(path); navigate(path);
@ -25,7 +22,7 @@ const TablesList = ({
if (!formInfo){ if (!formInfo){
return; return;
} }
const path = `${basePath}/form/${formInfo.id}/form-type/${isProject ? 'project' : formInfo.form_type_code}/${table.sheet}/${table?.direction}`; const path = `${basePath}/form/${formInfo.id}/form-type/${isProject ? 'PROJECT' : formInfo.form_type_code}/${table.sheet}/${table?.direction}/${table?.year}`;
return ( return (
<TableCard <TableCard

View File

@ -82,15 +82,15 @@ export const EVENT_CONFIGS = {
}, },
ACCESS_EXTEND: { ACCESS_EXTEND: {
form_id: 'Информация о задаче', form_id: 'Информация о задаче',
closes_at_after: 'Дата закрытия', closes_at_after: 'Дата закрытия (новая)',
closes_at_before: 'Дата открытия', closes_at_before: 'Дата закрытия (старая)',
phase_name: 'Названия этапа', phase_name: 'Названия этапа',
sheet: "Лист", sheet: "Лист",
}, },
ACCESS_WINDOW_CHANGE: { ACCESS_WINDOW_CHANGE: {
form_id: 'Информация о задаче', form_id: 'Информация о задаче',
closes_at: 'Дата закрытия', closes_at: 'Дата закрытия',
open_at: 'Дата открытия', opens_at: 'Дата открытия',
phase_name: 'Названия этапа', phase_name: 'Названия этапа',
role: 'Для роли', role: 'Для роли',
column_keys: 'Колонки в этапе', column_keys: 'Колонки в этапе',

View File

@ -10,10 +10,11 @@ import { useAuth } from '../app/context/AuthProvider';
import { BackButton } from '../components/common/Buttons/BackButton'; import { BackButton } from '../components/common/Buttons/BackButton';
import { SHEET_NAME } from '../constants/constants'; import { SHEET_NAME } from '../constants/constants';
const TableInfo = ({ formId, sheetName }) => { const TableInfo = ({ formId, sheetName, isProject = false }) => {
const path = (isProject ? `/project/` : '/task/') + formId;
const portalContent = ( const portalContent = (
<TaskInfoContainer> <TaskInfoContainer>
<BackButton to={`/task/${formId}`} /> <BackButton to={path} />
{sheetName && ( {sheetName && (
<NameTask>{SHEET_NAME[sheetName] || sheetName}</NameTask> <NameTask>{SHEET_NAME[sheetName] || sheetName}</NameTask>
)} )}
@ -28,20 +29,29 @@ const TableInfo = ({ formId, sheetName }) => {
}; };
export default function NewTablePage() { export default function NewTablePage() {
const { formId, formType, sheetName, direction } = useParams(); const { formId, formType, sheetName, direction, year } = useParams();
const { user } = useAuth(); const { user } = useAuth();
const isProject = formType == 'PROJECT';
return ( return (
<> <>
{formId && <TableInfo formId={formId} sheetName={sheetName} />} {formId && <TableInfo formId={formId} sheetName={sheetName} isProject={isProject} />}
{user && ( {user && (
<RealtimeProvider <RealtimeProvider
formId={formId} formId={formId}
sheetName={sheetName} sheetName={sheetName}
userId={user.id} userId={user.id}
direction={direction === 'null' ? null : direction} direction={direction === 'null' ? null : direction}
isProject={isProject}
year={year}
> >
<RealtimeTable formType={formType} formId={formId} sheetName={sheetName} direction={direction === 'null' ? null : direction} /> <RealtimeTable
formType={formType}
formId={formId}
sheetName={sheetName}
direction={direction === 'null' ? null : direction}
year={year}
/>
</RealtimeProvider> </RealtimeProvider>
)} )}

View File

@ -26,17 +26,18 @@ import {
ROLES_NAME_ID, ROLES_NAME_ID,
} from '../../constants/constants'; } from '../../constants/constants';
import { useAuth } from '../../app/context/AuthProvider'; import { useAuth } from '../../app/context/AuthProvider';
import { PrimaryButton } from '../../components/common/Buttons/Buttons'; import { PrimaryButton, PrimaryOutlinedButton } from '../../components/common/Buttons/Buttons';
import { import {
ExportExitButton, ExportExitButton,
ExportWithTextButton, ExportWithTextButton,
} from '../../components/common/Buttons/ButtonsActions'; } from '../../components/common/Buttons/ButtonsActions';
import { exportBulkForms, exportSingleForm } from '../../utils/exportForm'; import { exportBulkForms, exportSingleForm } from '../../utils/exportFile';
import { WhitePlus } from '../../components/common/icons/icons'; import { WhitePlus } from '../../components/common/icons/icons';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { PaginatedList } from '../../components/common/PaginatedList'; import { PaginatedList } from '../../components/common/PaginatedList';
import { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig'; import { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig';
import { SspApi } from '../../api/ssp'; import { SspApi } from '../../api/ssp';
import NavigationToggle from '../../components/common/NavigationToggle';
export { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig'; export { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig';
@ -213,10 +214,6 @@ export default function ProjectsPage() {
exportSingleForm(projectId, projectTitle); exportSingleForm(projectId, projectTitle);
}; };
const handleNavigateToTasks = () => {
navigate('/tasks');
};
const handleRefresh = () => { const handleRefresh = () => {
loadProjects(page, limit); loadProjects(page, limit);
toast.info('Список проектов обновлен'); toast.info('Список проектов обновлен');
@ -228,78 +225,7 @@ export default function ProjectsPage() {
<> <>
<PageContainer> <PageContainer>
<HeaderSwitch /> <HeaderSwitch />
<NavigationToggle currentView={'projects'} onViewChange={(path) => navigate(path)} />
{/* Навигация */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 2 }}>
<Button variant="outlined" size="small" onClick={handleNavigateToTasks}>
К задачам
</Button>
<Typography variant="h6" color="primary" sx={{ fontWeight: 500 }}>
Управление проектами
</Typography>
</Box>
{/* Фильтры */}
<Box sx={{ mb: 3, display: 'flex', gap: 2, flexWrap: 'wrap', alignItems: 'center' }}>
{/* Фильтр по году */}
<FormControl size="small" sx={{ minWidth: 150, height:'2.5rem' }}>
<Select
displayEmpty
value={yearFilter}
onChange={(e) => setYearFilter(e.target.value)}
>
<MenuItem value="">Все годы</MenuItem>
{yearOptions.map((year) => (
<MenuItem key={year} value={year}>
{year}
</MenuItem>
))}
</Select>
</FormControl>
{/* Фильтр по ССП/РФ */}
<FormControl size="small" sx={{ minWidth: '10rem' }}>
<Autocomplete
size="small"
options={projectData['ССП/РФ']?.options ?? []}
noOptionsText="Не найдено"
getOptionLabel={(option) => option.title || option.name || '-'}
value={
branchFilter
}
onChange={(event, newValue) => {
setBranchFilter(newValue);
}}
sx={{ height: '2.5rem', minWidth: '21.25rem' }}
renderInput={(params) => (
<TextField
{...params}
placeholder="Все"
sx={{
height: '2.5rem',
width: '21.25rem',
'& .MuiOutlinedInput-root': {
height: '2.5rem',
'& fieldset': {
borderRadius: '0.5rem',
borderColor: 'rgba(0,0,0,0.1)',
},
},
}}
/>
)}
/>
</FormControl>
<Button
variant="outlined"
size="small"
onClick={handleClearFilters}
sx={{ ml: 'auto' }}
>
Сбросить фильтры
</Button>
</Box>
<PaginatedList <PaginatedList
items={items} items={items}
@ -323,11 +249,41 @@ export default function ProjectsPage() {
getItemTitle={(project) => project.name || 'Проект'} getItemTitle={(project) => project.name || 'Проект'}
extraActions={ extraActions={
user.role_id === ROLES_NAME_ID.admin && ( user.role_id === ROLES_NAME_ID.admin && (
<PrimaryButton onClick={openModal} startIcon={<WhitePlus />}> <PrimaryButton onClick={openModal} startIcon={<WhitePlus />} height='2.5rem' >
Создать проект Создать проект
</PrimaryButton> </PrimaryButton>
) )
} }
filterActions={
<Box sx={{ display: 'flex', gap: 1.5, flexWrap: 'wrap', alignItems: 'center', height: '2.5rem' }}>
<Select
size="small"
displayEmpty
value={yearFilter}
onChange={(e) => setYearFilter(e.target.value)}
sx={{ width: 130 }}
>
<MenuItem value="">Все годы</MenuItem>
{yearOptions.map((year) => (
<MenuItem key={year} value={year}>{year}</MenuItem>
))}
</Select>
<Autocomplete
size="small"
options={projectData['ССП/РФ']?.options ?? []}
noOptionsText="Не найдено"
getOptionLabel={(option) => option.title || option.name || '-'}
value={branchFilter}
onChange={(event, newValue) => setBranchFilter(newValue)}
sx={{ width: 200 }}
renderInput={(params) => (
<TextField {...params} placeholder="Все" size="small" />
)}
/>
<PrimaryOutlinedButton onClick={handleClearFilters} height="100%"> Сбросить</PrimaryOutlinedButton>
</Box>
}
/> />
</PageContainer> </PageContainer>

View File

@ -1,7 +1,8 @@
import styled from '@emotion/styled'; import styled from '@emotion/styled';
const PageContainer = styled.div` const PageContainer = styled.div`
padding: 2.5rem; padding: 2rem;
padding-top: 1rem;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -20,7 +20,7 @@ import { SettingModal as SettingStageModal } from '../../components/Stages/Setti
import { PrimaryOutlinedButton } from '../../components/common/Buttons/Buttons'; import { PrimaryOutlinedButton } from '../../components/common/Buttons/Buttons';
import { FormsApi } from '../../api/forms'; import { FormsApi } from '../../api/forms';
import { ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions'; import { ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions';
import { exportSingleForm } from '../../utils/exportForm'; import { exportSingleForm } from '../../utils/exportFile';
import TablesList from '../../components/common/TableList/TableList'; import TablesList from '../../components/common/TableList/TableList';
import { DIRECTION_TRANSLATE, FORM_TYPE_TRANSLATE, SHEET_NAME } from '../../constants/constants'; import { DIRECTION_TRANSLATE, FORM_TYPE_TRANSLATE, SHEET_NAME } from '../../constants/constants';
@ -66,11 +66,11 @@ export default function TaskPage() {
const projectData = await ProjectsApi.get(id); const projectData = await ProjectsApi.get(id);
setTask(projectData.result); setTask(projectData.result);
setIsProjectData(true); setIsProjectData(true);
console.log(projectData.result.reports);
const mappedTables = projectData.result.reports.map(sheet => ({ const mappedTables = projectData.result.reports.map(sheet => ({
name: SHEET_NAME[sheet.report_type] || sheet.report_type, name: SHEET_NAME[sheet.report_type] || sheet.report_type,
sheet: sheet.report_type, sheet: sheet.report_type,
year: sheet.year,
})); }));
setTables(mappedTables); setTables(mappedTables);
} else { } else {

View File

@ -35,11 +35,13 @@ import {
ExportExitButton, ExportExitButton,
ExportWithTextButton, ExportWithTextButton,
} from '../../components/common/Buttons/ButtonsActions'; } from '../../components/common/Buttons/ButtonsActions';
import { exportBulkForms, exportSingleForm } from '../../utils/exportForm'; import { exportBulkForms, exportSingleForm } from '../../utils/exportFile';
import { WhitePlus } from '../../components/common/icons/icons'; import { WhitePlus } from '../../components/common/icons/icons';
import { OrgUnitsAutocompletePaper } from '../../components/common/OrgUnitsAutocompletePaper/OrgUnitsAutocompletePaper'; import { OrgUnitsAutocompletePaper } from '../../components/common/OrgUnitsAutocompletePaper/OrgUnitsAutocompletePaper';
import { renderOrgUnitValue } from '../../components/common/OrgUnitsAutocompletePaper/renderOrgUnitValue'; import { renderOrgUnitValue } from '../../components/common/OrgUnitsAutocompletePaper/renderOrgUnitValue';
import { PaginatedList } from '../../components/common/PaginatedList'; import { PaginatedList } from '../../components/common/PaginatedList';
import NavigationToggle from '../../components/common/NavigationToggle';
import { useNavigate } from 'react-router';
const modalSelectMenuProps = { const modalSelectMenuProps = {
sx: { zIndex: 1301 }, sx: { zIndex: 1301 },
@ -53,6 +55,8 @@ const modalSelectSx = {
}; };
export default function TasksPage() { export default function TasksPage() {
const navigate = useNavigate();
const [items, setItems] = useState([]); const [items, setItems] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [loadingUpdate, setLoadingUpdate] = useState(false); const [loadingUpdate, setLoadingUpdate] = useState(false);
@ -256,7 +260,7 @@ export default function TasksPage() {
<> <>
<PageContainer> <PageContainer>
<HeaderSwitch /> <HeaderSwitch />
<NavigationToggle currentView={'tasks'} onViewChange={(path) => navigate(path)} />
<PaginatedList <PaginatedList
items={items} items={items}
loading={loading} loading={loading}
@ -278,7 +282,7 @@ export default function TasksPage() {
getItemTitle={(task) => task.title || 'Задача'} getItemTitle={(task) => task.title || 'Задача'}
extraActions={ extraActions={
user.role_id === ROLES_NAME_ID.admin && ( user.role_id === ROLES_NAME_ID.admin && (
<PrimaryButton onClick={openModal} startIcon={<WhitePlus />}> <PrimaryButton onClick={openModal} startIcon={<WhitePlus />} height={'2.5rem'}>
Создать задачу Создать задачу
</PrimaryButton> </PrimaryButton>
) )

View File

@ -0,0 +1,64 @@
import { FormsSheetApi } from "../api/form_sheet";
import { ProjectsApi } from "../api/projects";
import { TasksApi } from "../api/tasks";
import { downloadFile } from "./downloadFile";
import { getApiErrorMessage } from "./getApiErrorMessage";
import { toast } from "react-toastify";
export const exportSingleForm = async (taskId, taskTitle) => {
try {
const response = await TasksApi.exportTask(taskId);
await downloadFile(response, taskTitle, "xlsx");
} catch (error) {
const message = await getApiErrorMessage(
error,
"Ошибка при скачивании файла",
);
toast.error(message);
}
};
export const exportSheet = async (formId, sheetName, direction) => {
try {
const normalizedDirection =
direction && direction !== "null" ? direction : undefined;
const params = normalizedDirection
? { direction: normalizedDirection }
: {};
const response = await FormsSheetApi.export(formId, sheetName, params);
await downloadFile(response, sheetName, "xlsx");
} catch (error) {
const message = await getApiErrorMessage(
error,
"Ошибка при скачивании файла",
);
toast.error(message);
}
};
export const exportSheetProject = async (formId, sheetName, year) => {
try {
const response = await ProjectsApi.export(formId, year, sheetName);
await downloadFile(response, sheetName, "xlsx");
} catch (error) {
const message = await getApiErrorMessage(
error,
"Ошибка при скачивании файла",
);
toast.error(message);
}
};
export const exportBulkForms = async (formIds, fileName = "Задачи") => {
try {
const response = await TasksApi.exportTasks({ form_ids: formIds });
await downloadFile(response, fileName, "xlsx");
} catch (error) {
const message = await getApiErrorMessage(
error,
"Ошибка при скачивании файла",
);
toast.error(message);
throw error;
}
};

View File

@ -1,48 +0,0 @@
import { FormsSheetApi } from '../api/form_sheet';
import { TasksApi } from '../api/tasks';
import { downloadFile } from './downloadFile';
import { getApiErrorMessage } from './getApiErrorMessage';
import { toast } from 'react-toastify';
export const exportSingleForm = async (taskId, taskTitle) => {
try {
const response = await TasksApi.exportTask(taskId);
await downloadFile(response, taskTitle, 'xlsx');
} catch (error) {
const message = await getApiErrorMessage(
error,
'Ошибка при скачивании файла',
);
toast.error(message);
}
};
export const exportSheet = async (formId, sheetName, direction) => {
try {
const normalizedDirection =
direction && direction !== 'null' ? direction : undefined;
const params = normalizedDirection ? { direction: normalizedDirection } : {};
const response = await FormsSheetApi.export(formId, sheetName, params);
await downloadFile(response, sheetName, 'xlsx');
} catch (error) {
const message = await getApiErrorMessage(
error,
'Ошибка при скачивании файла',
);
toast.error(message);
}
};
export const exportBulkForms = async (formIds, fileName = 'Задачи') => {
try {
const response = await TasksApi.exportTasks({ form_ids: formIds });
await downloadFile(response, fileName, 'xlsx');
} catch (error) {
const message = await getApiErrorMessage(
error,
'Ошибка при скачивании файла',
);
toast.error(message);
throw error;
}
};