fix lint
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2026-01-15 02:36:24 +03:00
parent dea0676169
commit 2e46cc41a1
42 changed files with 940 additions and 301 deletions

View File

@ -17,7 +17,6 @@ import {
List,
ListItem,
ListItemText,
ListItemSecondaryAction,
Divider,
Chip,
} from '@mui/material';
@ -84,7 +83,8 @@ export function SpecificationModal({
const [isEditing, setIsEditing] = useState(false);
const [editedText, setEditedText] = useState('');
const [tabIndex, setTabIndex] = useState(0);
const [viewingHistoryItem, setViewingHistoryItem] = useState<SpecificationHistoryItem | null>(null);
const [viewingHistoryItem, setViewingHistoryItem] =
useState<SpecificationHistoryItem | null>(null);
// Сбрасываем состояние при открытии/закрытии
useEffect(() => {
@ -97,12 +97,12 @@ export function SpecificationModal({
}, [open, specification]);
const handleEdit = () => {
setEditedText(specification || '');
setEditedText(specification ?? '');
setIsEditing(true);
};
const handleCancel = () => {
setEditedText(specification || '');
setEditedText(specification ?? '');
setIsEditing(false);
};
@ -152,7 +152,13 @@ export function SpecificationModal({
fullWidth
data-testid="specification-modal"
>
<DialogTitle sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
<DialogTitle
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'flex-start',
}}
>
<Box>
<Typography variant="h6" component="span">
Техническое задание
@ -194,7 +200,7 @@ export function SpecificationModal({
{hasHistory && !isEditing && !viewingHistoryItem && (
<Tabs
value={tabIndex}
onChange={(_, newValue) => setTabIndex(newValue)}
onChange={(_, newValue: number) => setTabIndex(newValue)}
sx={{ px: 3, borderBottom: 1, borderColor: 'divider' }}
>
<Tab label="Текущее ТЗ" data-testid="specification-tab-current" />
@ -225,7 +231,9 @@ export function SpecificationModal({
<IconButton
size="small"
color="primary"
onClick={() => handleRestoreFromHistory(viewingHistoryItem.id)}
onClick={() =>
handleRestoreFromHistory(viewingHistoryItem.id)
}
disabled={isRestoring}
data-testid="specification-restore-button"
>
@ -236,7 +244,8 @@ export function SpecificationModal({
{viewingHistoryItem.ideaDescriptionSnapshot && (
<Alert severity="info" sx={{ mb: 2 }}>
<Typography variant="caption">
Описание идеи на момент генерации: {viewingHistoryItem.ideaDescriptionSnapshot}
Описание идеи на момент генерации:{' '}
{viewingHistoryItem.ideaDescriptionSnapshot}
</Typography>
</Alert>
)}
@ -248,7 +257,11 @@ export function SpecificationModal({
borderRadius: 1,
maxHeight: '50vh',
overflow: 'auto',
'& h1, & h2, & h3, & h4, & h5, & h6': { mt: 2, mb: 1, '&:first-of-type': { mt: 0 } },
'& h1, & h2, & h3, & h4, & h5, & h6': {
mt: 2,
mb: 1,
'&:first-of-type': { mt: 0 },
},
'& h1': { fontSize: '1.5rem', fontWeight: 600 },
'& h2': { fontSize: '1.25rem', fontWeight: 600 },
'& h3': { fontSize: '1.1rem', fontWeight: 600 },
@ -256,9 +269,29 @@ export function SpecificationModal({
'& ul, & ol': { pl: 3, mb: 1.5 },
'& li': { mb: 0.5 },
'& strong': { fontWeight: 600 },
'& code': { bgcolor: 'grey.200', px: 0.5, py: 0.25, borderRadius: 0.5, fontFamily: 'monospace', fontSize: '0.875em' },
'& pre': { bgcolor: 'grey.200', p: 1.5, borderRadius: 1, overflow: 'auto', '& code': { bgcolor: 'transparent', p: 0 } },
'& blockquote': { borderLeft: 3, borderColor: 'primary.main', pl: 2, ml: 0, fontStyle: 'italic', color: 'text.secondary' },
'& code': {
bgcolor: 'grey.200',
px: 0.5,
py: 0.25,
borderRadius: 0.5,
fontFamily: 'monospace',
fontSize: '0.875em',
},
'& pre': {
bgcolor: 'grey.200',
p: 1.5,
borderRadius: 1,
overflow: 'auto',
'& code': { bgcolor: 'transparent', p: 0 },
},
'& blockquote': {
borderLeft: 3,
borderColor: 'primary.main',
pl: 2,
ml: 0,
fontStyle: 'italic',
color: 'text.secondary',
},
}}
>
<Markdown>{viewingHistoryItem.specification}</Markdown>
@ -272,7 +305,11 @@ export function SpecificationModal({
<TabPanel value={tabIndex} index={0}>
{isLoading && (
<Box sx={{ py: 4 }} data-testid="specification-loading">
<Typography variant="body2" color="text.secondary" gutterBottom>
<Typography
variant="body2"
color="text.secondary"
gutterBottom
>
Генерируем техническое задание...
</Typography>
<LinearProgress />
@ -280,7 +317,11 @@ export function SpecificationModal({
)}
{error && (
<Alert severity="error" sx={{ my: 2 }} data-testid="specification-error">
<Alert
severity="error"
sx={{ my: 2 }}
data-testid="specification-error"
>
{error.message || 'Не удалось сгенерировать ТЗ'}
</Alert>
)}
@ -307,7 +348,11 @@ export function SpecificationModal({
{!isLoading && !error && !isEditing && specification && (
<Box>
{idea?.specificationGeneratedAt && (
<Typography variant="caption" color="text.secondary" sx={{ mb: 1, display: 'block' }}>
<Typography
variant="caption"
color="text.secondary"
sx={{ mb: 1, display: 'block' }}
>
Сгенерировано: {formatDate(idea.specificationGeneratedAt)}
</Typography>
)}
@ -319,7 +364,11 @@ export function SpecificationModal({
borderRadius: 1,
maxHeight: '55vh',
overflow: 'auto',
'& h1, & h2, & h3, & h4, & h5, & h6': { mt: 2, mb: 1, '&:first-of-type': { mt: 0 } },
'& h1, & h2, & h3, & h4, & h5, & h6': {
mt: 2,
mb: 1,
'&:first-of-type': { mt: 0 },
},
'& h1': { fontSize: '1.5rem', fontWeight: 600 },
'& h2': { fontSize: '1.25rem', fontWeight: 600 },
'& h3': { fontSize: '1.1rem', fontWeight: 600 },
@ -327,9 +376,29 @@ export function SpecificationModal({
'& ul, & ol': { pl: 3, mb: 1.5 },
'& li': { mb: 0.5 },
'& strong': { fontWeight: 600 },
'& code': { bgcolor: 'grey.200', px: 0.5, py: 0.25, borderRadius: 0.5, fontFamily: 'monospace', fontSize: '0.875em' },
'& pre': { bgcolor: 'grey.200', p: 1.5, borderRadius: 1, overflow: 'auto', '& code': { bgcolor: 'transparent', p: 0 } },
'& blockquote': { borderLeft: 3, borderColor: 'primary.main', pl: 2, ml: 0, fontStyle: 'italic', color: 'text.secondary' },
'& code': {
bgcolor: 'grey.200',
px: 0.5,
py: 0.25,
borderRadius: 0.5,
fontFamily: 'monospace',
fontSize: '0.875em',
},
'& pre': {
bgcolor: 'grey.200',
p: 1.5,
borderRadius: 1,
overflow: 'auto',
'& code': { bgcolor: 'transparent', p: 0 },
},
'& blockquote': {
borderLeft: 3,
borderColor: 'primary.main',
pl: 2,
ml: 0,
fontStyle: 'italic',
color: 'text.secondary',
},
}}
>
<Markdown>{specification}</Markdown>
@ -353,12 +422,54 @@ export function SpecificationModal({
<Box key={item.id}>
{index > 0 && <Divider />}
<ListItem
data-testid={`specification-history-item-${index}`}
data-testid={`specification-history-item-${String(index)}`}
sx={{ pr: 16 }}
secondaryAction={
<>
<Tooltip title="Просмотреть">
<IconButton
size="small"
onClick={() => handleViewHistoryItem(item)}
data-testid={`specification-history-view-${String(index)}`}
>
<Visibility fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Восстановить">
<IconButton
size="small"
color="primary"
onClick={() =>
handleRestoreFromHistory(item.id)
}
disabled={isRestoring}
data-testid={`specification-history-restore-${String(index)}`}
>
<Restore fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Удалить">
<IconButton
size="small"
color="error"
onClick={() => onDeleteHistoryItem(item.id)}
data-testid={`specification-history-delete-${String(index)}`}
>
<Delete fontSize="small" />
</IconButton>
</Tooltip>
</>
}
>
<ListItemText
primary={
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 1,
}}
>
<Typography variant="body2">
{formatDate(item.createdAt)}
</Typography>
@ -387,38 +498,6 @@ export function SpecificationModal({
</Typography>
}
/>
<ListItemSecondaryAction>
<Tooltip title="Просмотреть">
<IconButton
size="small"
onClick={() => handleViewHistoryItem(item)}
data-testid={`specification-history-view-${index}`}
>
<Visibility fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Восстановить">
<IconButton
size="small"
color="primary"
onClick={() => handleRestoreFromHistory(item.id)}
disabled={isRestoring}
data-testid={`specification-history-restore-${index}`}
>
<Restore fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title="Удалить">
<IconButton
size="small"
color="error"
onClick={() => onDeleteHistoryItem(item.id)}
data-testid={`specification-history-delete-${index}`}
>
<Delete fontSize="small" />
</IconButton>
</Tooltip>
</ListItemSecondaryAction>
</ListItem>
</Box>
))}
@ -446,9 +525,7 @@ export function SpecificationModal({
</Button>
</>
) : viewingHistoryItem ? (
<Button onClick={handleCloseHistoryView}>
Назад к текущему ТЗ
</Button>
<Button onClick={handleCloseHistoryView}>Назад к текущему ТЗ</Button>
) : (
<Button
onClick={onClose}