- маршрут /documents/:document_id возвращён: старые ссылки («Открыть подтверждённую форму») снова открывают документ; ЮЛ и консолидация для переключателя документов берутся из документа и его файла, а не из адреса; в списке переключателя — вторая строка (тип · формат · дата), ББ и ОФР одного PDF различимы - чек-лист: ОФР — ячейка INCOME (было 'OFR' → всегда «Отсутствует»), сборка строк — buildChecklistRows с тестами, rowKey по ЮЛ, типы ответа GET …/checklist - удаление файла по id файла (fileId строки), а не по id документа (было 404); ошибка — без закрытия окна - замена: настоящая загрузка нового файла в ту же консолидацию (автозамена ядра, 05-domain-rules §9.5 п. 3), причина — комментарием к заменяемому документу; кнопка доступна только в версии в работе - комментарий: путь без хвостового «/», типы, закрытие только после успеха, лимит 4000 - счётчики над таблицей формы — модуль reviewCounters (по needs_review, как подсветка) с тестами; buildStatementGrid возвращён к test (падали 3 теста) - PageTitle и store возвращены к test (ширина переключателя — внутри DocumentPage; имя ЮЛ — пропсом) - цвет подписей полей в теме: #667085 (опечатка #665087) - типы во всех новых компонентах: tsc 0 ошибок, ESLint/biome без ошибок, vitest 331/331, сборка Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
import { FileAddOutlined, UploadOutlined } from '@ant-design/icons';
|
||
import { Button, Input, Modal, Upload } from 'antd';
|
||
import { useEffect, useState } from 'react';
|
||
|
||
const { Dragger } = Upload;
|
||
|
||
type ReplaceDocModalProps = {
|
||
open: boolean;
|
||
docName: string;
|
||
organizationName: string | null;
|
||
submitting: boolean;
|
||
onCancel: () => void;
|
||
onSubmit: (file: File, reason: string) => void;
|
||
};
|
||
|
||
export default function ReplaceDocModal({ open, docName, organizationName, submitting, onCancel, onSubmit }: ReplaceDocModalProps) {
|
||
const [reason, setReason] = useState('');
|
||
const [file, setFile] = useState<File | null>(null);
|
||
|
||
// при каждом открытии — пустая форма
|
||
useEffect(() => {
|
||
if (open) {
|
||
setReason('');
|
||
setFile(null);
|
||
}
|
||
}, [open]);
|
||
|
||
return (
|
||
<Modal
|
||
title='Замена документа'
|
||
open={open}
|
||
onCancel={onCancel}
|
||
onOk={() => file && onSubmit(file, reason.trim())}
|
||
okText='Загрузить'
|
||
okButtonProps={{
|
||
icon: <UploadOutlined />,
|
||
disabled: file === null || reason.trim().length === 0,
|
||
}}
|
||
confirmLoading={submitting}>
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||
{organizationName && <span>{organizationName}</span>}
|
||
<div
|
||
style={{
|
||
backgroundColor: 'rgb(248, 250, 252)',
|
||
borderRadius: 6,
|
||
fontSize: 12,
|
||
color: '#667085',
|
||
padding: '8px 10px',
|
||
}}>
|
||
Заменяемый документ: {docName}
|
||
</div>
|
||
|
||
<Input placeholder='Укажите причину замены' value={reason} maxLength={4000} onChange={(e) => setReason(e.target.value)} />
|
||
|
||
<Dragger
|
||
multiple={false}
|
||
style={{ borderStyle: 'dashed' }}
|
||
fileList={file ? [{ uid: 'replace', name: file.name, status: 'done' }] : []}
|
||
maxCount={1}
|
||
accept='.xls,.xlsx,.xlsb,.pdf,.png,.jpg,.jpeg'
|
||
beforeUpload={(f) => {
|
||
setFile(f);
|
||
return false;
|
||
}}
|
||
onRemove={() => setFile(null)}>
|
||
<p className='ant-upload-drag-icon'>
|
||
<FileAddOutlined />
|
||
</p>
|
||
<p className='ant-upload-text' style={{ color: '#667085' }}>
|
||
Перетащите файл сюда
|
||
</p>
|
||
<Button>Выбрать документ</Button>
|
||
</Dragger>
|
||
</div>
|
||
</Modal>
|
||
);
|
||
}
|