This commit is contained in:
PotapovaA 2026-07-02 14:43:35 +03:00
parent 4e7cc9b3bd
commit 40c373b5ed
26 changed files with 5811 additions and 5609 deletions

View File

@ -21,7 +21,7 @@ export const DictVspApi = {
responseType: "blob",
});
},
getDropdownVsp(params){
return api.get(`/dict/info/dropdown`, params).then((r) => r.data);
}
getDropdownVsp(params) {
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);
},
getTasks: (projectId) => {
return api.get(`/projects/${projectId}/tasks`).then((r) => r.data);
},
addTask: (projectId, taskId) => {
getTableData: (id, sheetName, year) => {
return api
.post(`/projects/${projectId}/tasks/${taskId}`)
.get(`/projects/${id}/report/${year}/${sheetName}`)
.then((r) => r.data);
},
removeTask: (projectId, taskId) => {
return api
.delete(`/projects/${projectId}/tasks/${taskId}`)
.then((r) => r.data);
export: (id, year, sheetName) => {
return api.get(`/export/project/${id}/report/${year}/${sheetName}`, {
responseType: "blob",
});
},
};

View File

@ -52,7 +52,7 @@ export const AppRoutes = () => {
<Route path="/new-table" element={<NewTablePage />} />
<Route path="/tables-new" element={<TablesTest />} />
<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>
</Routes>

View File

@ -29,8 +29,8 @@ import { additionVspRowTable } from './constants/addingRowConfig';
import { SelectVspModal } from './Modals/SelectVspModal';
import { getRowId } from './utils/rowUtils';
const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
const { data, setData, isLoading: isTableLoading, editingCells: dataEditingCells } = useRealtimeData(formId, sheetName, direction);
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();
@ -360,6 +360,8 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
formId={formId}
sheetName={sheetName}
direction={direction}
year={year}
isProject={formType == 'PROJECT'}
/>
<div style={tableWrapperStyle}>
@ -420,8 +422,6 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
onClose={() => setIsOpenModalSelectVsp(false)}
formId={formId}
onSelect={handleAddVspRow}
// vspOptions={}
// selectedVSP={}
title="Выбор ВСП"
/>
</>

View File

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

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,
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")}/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 handleMessage = useCallback((data) => {
// Обработка ошибок
if (data.error) {
console.log(data.error.message)
toast.error("Server error:" + data.error.message || '');
console.log(data.error.message);
toast.error("Server error:" + data.error.message || "");
onErrorRef.current?.(data.error);
return;
}
@ -145,6 +157,19 @@ export const RealtimeProvider = ({
}
}, [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(
async (row, column) => {
@ -249,10 +274,9 @@ export const RealtimeProvider = ({
const message = {
event: "row_added",
data: rowData,
sheet: sheetName,
form_id: formId,
direction: direction,
};
addCommonField(message);
return sendMessage(message);
},
[isConnected, sendMessage, sheetName, formId, direction],
@ -268,10 +292,8 @@ export const RealtimeProvider = ({
const message = {
event: "row_deleted",
data: { row_id: rowId },
sheet: sheetName,
form_id: formId,
direction: direction,
};
addCommonField(message);
return sendMessage(message);
},

View File

@ -4,8 +4,9 @@ import { useRealtime } from "../contexts/RealtimeContext";
import { deleteRow, insertCell, updateCells } from "../utils/cellUtils";
import { toast } from "react-toastify";
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 [isConnected, setIsConnected] = useState(false);
const [error, setError] = useState(null);
@ -77,7 +78,10 @@ const useRealtimeData = (formId, sheetName, direction) => {
try {
setIsLoading(true);
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, {
params: { direction: direction },
});

View File

@ -107,20 +107,6 @@ export const useWebSocket = (url, onMessage) => {
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(() => {
connect();
return () => disconnect();
@ -130,7 +116,6 @@ export const useWebSocket = (url, onMessage) => {
isConnected: isConnectedRef,
error,
sendMessage,
login,
disconnect,
};
};

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

View File

@ -6,15 +6,12 @@ import { toast } from 'react-toastify';
const TablesList = ({
filteredTables,
projects,
query,
basePath = '/table',
formInfo
formInfo,
isProject = false,
}) => {
const navigate = useNavigate();
const isProject = useMemo(() => {
return !!projects;
}, [projects])
const handleNavigate = (path) => {
navigate(path);
@ -25,7 +22,7 @@ const TablesList = ({
if (!formInfo){
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 (
<TableCard

View File

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

View File

@ -26,17 +26,18 @@ import {
ROLES_NAME_ID,
} from '../../constants/constants';
import { useAuth } from '../../app/context/AuthProvider';
import { PrimaryButton } from '../../components/common/Buttons/Buttons';
import { PrimaryButton, PrimaryOutlinedButton } from '../../components/common/Buttons/Buttons';
import {
ExportExitButton,
ExportWithTextButton,
} 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 { useNavigate } from 'react-router-dom';
import { PaginatedList } from '../../components/common/PaginatedList';
import { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig';
import { SspApi } from '../../api/ssp';
import NavigationToggle from '../../components/common/NavigationToggle';
export { DEFAULT_PROJECT_CONFIG } from '../../constants/projectConfig';
@ -213,10 +214,6 @@ export default function ProjectsPage() {
exportSingleForm(projectId, projectTitle);
};
const handleNavigateToTasks = () => {
navigate('/tasks');
};
const handleRefresh = () => {
loadProjects(page, limit);
toast.info('Список проектов обновлен');
@ -228,78 +225,7 @@ export default function ProjectsPage() {
<>
<PageContainer>
<HeaderSwitch />
{/* Навигация */}
<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>
<NavigationToggle currentView={'projects'} onViewChange={(path) => navigate(path)} />
<PaginatedList
items={items}
@ -323,11 +249,41 @@ export default function ProjectsPage() {
getItemTitle={(project) => project.name || 'Проект'}
extraActions={
user.role_id === ROLES_NAME_ID.admin && (
<PrimaryButton onClick={openModal} startIcon={<WhitePlus />}>
<PrimaryButton onClick={openModal} startIcon={<WhitePlus />} height='2.5rem' >
Создать проект
</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>

View File

@ -1,7 +1,8 @@
import styled from '@emotion/styled';
const PageContainer = styled.div`
padding: 2.5rem;
padding: 2rem;
padding-top: 1rem;
box-sizing: border-box;
display: flex;
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 { FormsApi } from '../../api/forms';
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 { DIRECTION_TRANSLATE, FORM_TYPE_TRANSLATE, SHEET_NAME } from '../../constants/constants';
@ -66,11 +66,11 @@ export default function TaskPage() {
const projectData = await ProjectsApi.get(id);
setTask(projectData.result);
setIsProjectData(true);
console.log(projectData.result.reports);
const mappedTables = projectData.result.reports.map(sheet => ({
name: SHEET_NAME[sheet.report_type] || sheet.report_type,
sheet: sheet.report_type,
year: sheet.year,
}));
setTables(mappedTables);
} else {

View File

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