194 lines
7.0 KiB
JavaScript
194 lines
7.0 KiB
JavaScript
import { useEffect, useState } from 'react';
|
||
import { createPortal } from 'react-dom';
|
||
import { useParams, useNavigate } from 'react-router-dom';
|
||
import { TasksApi } from '../../api/tasks';
|
||
import { TablesApi } from '../../api/tables';
|
||
import { ProjectsApi } from '../../api/projects'; // Добавьте импорт API для проектов
|
||
import {
|
||
TaskInfoContainer,
|
||
NameTask,
|
||
} from '../../components/common/SwitchFormTask/SwitchFormTask.style';
|
||
import { Box, CircularProgress, Stack, Typography } from '@mui/material';
|
||
import { formatDate } from '../../utils/formatDate';
|
||
import { DateIcon, TableIcon } from '../../components/common/icons/icons';
|
||
import { Chip } from '../../components/styles/StyledChip';
|
||
import { IconWithContent } from '../../components/common/IconWithContent';
|
||
import SearchComponent from '../../components/common/SearchComponent';
|
||
import { BackButton } from '../../components/common/Buttons/BackButton';
|
||
import { toast } from 'react-toastify';
|
||
import { SettingModal as SettingStageModal } from '../../components/Stages/SettingModal';
|
||
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 TablesList from '../../components/common/TableList/TableList';
|
||
import { DIRECTION_TRANSLATE, FORM_TYPE_TRANSLATE, SHEET_NAME } from '../../constants/constants';
|
||
|
||
const TaskInfo = ({ task, isProject }) => {
|
||
const portalContent = (
|
||
<TaskInfoContainer>
|
||
<BackButton to={isProject ? "/projects" : "/tasks"} />
|
||
<NameTask>{isProject ? 'Проект' : FORM_TYPE_TRANSLATE[task.form_type_code] || ''}</NameTask>
|
||
</TaskInfoContainer>
|
||
);
|
||
|
||
const targetElement = document.getElementById('TableInfo');
|
||
|
||
if (targetElement) {
|
||
return createPortal(portalContent, targetElement);
|
||
}
|
||
};
|
||
|
||
export default function TaskPage() {
|
||
const { taskId, projectId } = useParams();
|
||
const navigate = useNavigate();
|
||
|
||
// Определяем, что у нас за ID и какой тип
|
||
const isProject = !!projectId;
|
||
const id = isProject ? Number(projectId) : Number(taskId);
|
||
|
||
const [task, setTask] = useState(null);
|
||
const [tables, setTables] = useState([]);
|
||
const [isLoading, setIsLoading] = useState(false);
|
||
const [query, setQuery] = useState('');
|
||
const [modalStageOpen, setModalStageOpen] = useState(false);
|
||
const [modalProjectOpen, setModalProjectOpen] = useState(false);
|
||
const [tempProjects, setTempProjects] = useState([]);
|
||
const [projects, setProjects] = useState([]);
|
||
const [isProjectData, setIsProjectData] = useState(false);
|
||
|
||
useEffect(() => {
|
||
const getData = async () => {
|
||
setIsLoading(true);
|
||
try {
|
||
if (isProject) {
|
||
// Получаем информацию о проекте
|
||
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,
|
||
}));
|
||
setTables(mappedTables);
|
||
} else {
|
||
// Получаем информацию о задаче
|
||
const taskData = await TasksApi.getById(id);
|
||
setTask(taskData.result);
|
||
setIsProjectData(false);
|
||
|
||
// Получаем таблицы задачи
|
||
const tablesData = await TasksApi.getSheets(id);
|
||
const mappedTables = tablesData.result.all_sheets.map(sheet => ({
|
||
name: SHEET_NAME[sheet.sheet_name] || sheet.sheet_name,
|
||
sheet: sheet.sheet_name,
|
||
direction: sheet.direction,
|
||
}));
|
||
setTables(mappedTables.filter(t => t.sheet !== "OTCH9F"));
|
||
}
|
||
} catch (error) {
|
||
toast.error(
|
||
error?.response?.data?.detail || `Ошибка получения данных ${isProject ? 'проекта' : 'задачи'}`,
|
||
);
|
||
} finally {
|
||
setIsLoading(false);
|
||
}
|
||
};
|
||
|
||
if (Number.isFinite(id)) {
|
||
getData();
|
||
}
|
||
}, [id, isProject]);
|
||
|
||
// Объединили два useEffect в один
|
||
|
||
const handleCreateProject = (projectData) => {
|
||
// логика создания проекта
|
||
};
|
||
|
||
// Фильтруем таблицы по query (учитывая name и direction)
|
||
const filteredTables = tables.filter((item) => {
|
||
const searchString = `${item.name} ${item.direction || ''}`.toLowerCase();
|
||
return searchString.includes(query.toLowerCase());
|
||
});
|
||
|
||
// Функция для экспорта
|
||
const handleExport = () => {
|
||
const fileName = isProject
|
||
? `project_${task?.title || id}`
|
||
: `form_${task?.title || taskId}`;
|
||
exportSingleForm(id, fileName);
|
||
};
|
||
|
||
if (isLoading) {
|
||
return (
|
||
<div className="flex justify-center pt-12">
|
||
<CircularProgress />
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<>
|
||
{task && <TaskInfo task={task} isProject={isProject} />}
|
||
<Box
|
||
sx={{
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
paddingTop: '2.5rem'
|
||
}}
|
||
>
|
||
<Box sx={{ display: 'flex', gap: 2, flexDirection: 'column', width: '50rem' }}>
|
||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||
<span>Выберите таблицу</span>
|
||
<Chip>
|
||
<IconWithContent icon={<TableIcon />}>
|
||
<span>Таблиц: {tables.length}</span>
|
||
</IconWithContent>
|
||
</Chip>
|
||
</Box>
|
||
|
||
<Box sx={{ display: 'flex', gap: 2, justifyContent: 'space-between' }}>
|
||
<SearchComponent
|
||
placeholder="Поиск по названию или направлению"
|
||
value={query}
|
||
onChange={setQuery}
|
||
/>
|
||
<Stack sx={{ flexDirection: 'row', spacing: '.5rem', justifyContent: 'end', gap: '.5rem' }}>
|
||
<ExportWithTextButton onClick={handleExport} />
|
||
<PrimaryOutlinedButton
|
||
variant="outlined"
|
||
onClick={() => setModalStageOpen(true)}
|
||
>
|
||
<span>Этапы</span>
|
||
</PrimaryOutlinedButton>
|
||
|
||
<SettingStageModal
|
||
isOpen={modalStageOpen}
|
||
onClose={() => setModalStageOpen(false)}
|
||
taskId={isProject ? undefined : taskId}
|
||
projectId={isProject ? projectId : undefined}
|
||
mode={isProject ? "project" : "task"}
|
||
formTypeCode={ task?.form_type_code || ''}
|
||
sheets={tables}
|
||
/>
|
||
|
||
</Stack>
|
||
</Box>
|
||
|
||
<TablesList
|
||
query={query}
|
||
projects={projects}
|
||
filteredTables={filteredTables}
|
||
basePath={"/table"}
|
||
formInfo={task}
|
||
isProject={isProject}
|
||
/>
|
||
</Box>
|
||
</Box>
|
||
</>
|
||
);
|
||
} |