183 lines
5.6 KiB
JavaScript
183 lines
5.6 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 {
|
|
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 { ModalCreateProject } from './ModalCreateProject';
|
|
import { downloadFile } from '../../utils/downloadFile';
|
|
import { ExportWithTextButton } from '../../components/common/Buttons/ButtonsActions';
|
|
import TablesList from '../../components/common/TableList/TableList';
|
|
import { SHEET_NAME } from '../../constants';
|
|
|
|
const TaskInfo = ({ task }) => {
|
|
const formattedDateRange = `${formatDate(task.start_date)} — ${formatDate(task.end_date)}`;
|
|
|
|
const portalContent = (
|
|
<TaskInfoContainer>
|
|
<BackButton to="/tasks" />
|
|
<NameTask>{task.title}</NameTask>
|
|
<Chip>
|
|
<DateIcon />
|
|
<span style={{ fontSize: '0.75rem' }}>{formattedDateRange}</span>
|
|
</Chip>
|
|
</TaskInfoContainer>
|
|
);
|
|
|
|
const targetElement = document.getElementById('TableInfo');
|
|
|
|
if (targetElement) {
|
|
return createPortal(portalContent, targetElement);
|
|
}
|
|
};
|
|
|
|
export default function TaskPage() {
|
|
const { taskId } = useParams();
|
|
const navigate = useNavigate();
|
|
const id = 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([]);
|
|
|
|
useEffect(() => {
|
|
const getSheets = async () => {
|
|
setIsLoading(true);
|
|
try {
|
|
const data = await TasksApi.getSheets(id);
|
|
setTables(data.result.sheets.map(table => ({ name: SHEET_NAME[table], sheet: table })));
|
|
} catch (error) {
|
|
toast.error(
|
|
error?.response?.data?.detail || 'Ошибка получения данных задачи',
|
|
);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
if (Number.isFinite(id)) {
|
|
getSheets();
|
|
}
|
|
}, [id]);
|
|
|
|
useEffect(() => {
|
|
const getFormInfo = async () => {
|
|
setIsLoading(true);
|
|
try {
|
|
const data = await TasksApi.getById(id);
|
|
setTask(data.result)
|
|
} catch (error) {
|
|
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
if (Number.isFinite(id)) {
|
|
getFormInfo();
|
|
}
|
|
}, [id]);
|
|
|
|
const handleCreateProject = (projectData) => {
|
|
|
|
};
|
|
|
|
// Фильтруем таблицы по query
|
|
const filteredTables = tables.filter((item) =>
|
|
item.name.toLowerCase().includes(query.toLowerCase()),
|
|
);
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="flex justify-center pt-12">
|
|
<CircularProgress />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const handleExport = async () => {
|
|
try {
|
|
const response = await TasksApi.exportTask(taskId);
|
|
await downloadFile(response, task.title, 'xlsx');
|
|
} catch (error) {
|
|
toast.error('Ошибка при скачивании файла');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{/* <TaskInfo task={task} /> */}
|
|
<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' }}>
|
|
|
|
<ExportWithTextButton onClick={handleExport} />
|
|
|
|
<PrimaryOutlinedButton
|
|
variant="outlined"
|
|
onClick={() => setModalStageOpen(true)}
|
|
>
|
|
<span>Этапы</span>
|
|
</PrimaryOutlinedButton>
|
|
<SettingStageModal
|
|
isOpen={modalStageOpen}
|
|
onClose={() => setModalStageOpen(false)}
|
|
taskId={taskId}
|
|
mode="task"
|
|
/>
|
|
</Stack>
|
|
</Box>
|
|
|
|
<TablesList
|
|
query={query}
|
|
projects={projects}
|
|
filteredTables={filteredTables}
|
|
basePath="/table"
|
|
formInfo={task}
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
</>
|
|
);
|
|
}
|