Перенесён диапазон arm-web 8345f5e..a3c0010 (3 коммитов, 22 файлов набора синхронизации) скриптом docs/scripts/sync-web.sh. После переноса web/ и arm-web@test идентичны по набору. Коммиты arm-web: - ff1e45c file id as option value for react rendering - 0242486 fix(#49): зелёный make check и исправления после ревью (AURORA-144) - 0fdbd80 feat: add comments frontend, checklist modal, files delete, select options in document review Co-Authored-By: sync-web.sh <noreply@aepif.ru>
89 lines
3.3 KiB
TypeScript
89 lines
3.3 KiB
TypeScript
import { Button, Modal, Tooltip, Typography, message, theme } from 'antd';
|
||
import { type ReactNode, useState } from 'react';
|
||
import { ApiError } from '../../api/client';
|
||
import { removeFile } from '../../services/api/files';
|
||
import type { DocumentRow } from './documentRows';
|
||
|
||
const { Text } = Typography;
|
||
|
||
const OptionCard = ({ title, detail, action }: { title: string; detail: string; action: ReactNode }) => {
|
||
const { token } = theme.useToken();
|
||
return (
|
||
<div
|
||
style={{
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'space-between',
|
||
gap: 16,
|
||
padding: 12,
|
||
border: `1px solid ${token.colorBorder}`,
|
||
borderRadius: token.borderRadius,
|
||
}}>
|
||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||
<Text strong>{title}</Text>
|
||
<Text type='secondary'>{detail}</Text>
|
||
</div>
|
||
{action}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
type DeleteReasonModalProps = {
|
||
targetRow: DocumentRow;
|
||
open: boolean;
|
||
onCancel: () => void;
|
||
/** файл удалён — обновить список */
|
||
onDelete: () => void;
|
||
onReplace: () => void;
|
||
/** замена = загрузка нового файла: только в версии в работе, как кнопка «Загрузить документы» */
|
||
canReplace: boolean;
|
||
};
|
||
|
||
/** Удаление или замена — файлом целиком (`DELETE /files/{file_id}`): уходят все документы файла. */
|
||
export default function DeleteReasonModal({ targetRow, open, onCancel, onDelete, onReplace, canReplace }: DeleteReasonModalProps) {
|
||
const [isDeleting, setIsDeleting] = useState(false);
|
||
const handleDelete = async () => {
|
||
setIsDeleting(true);
|
||
try {
|
||
await removeFile(targetRow.fileId);
|
||
message.success('Файл удалён');
|
||
onDelete();
|
||
} catch (e: unknown) {
|
||
// 409 — например, в файле подтверждённый документ; сервер объясняет причину
|
||
message.error(e instanceof ApiError ? e.message : 'Не удалось удалить файл');
|
||
} finally {
|
||
setIsDeleting(false);
|
||
}
|
||
};
|
||
return (
|
||
<Modal title='Удаление документа' open={open} onCancel={onCancel} footer={null} destroyOnHidden>
|
||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||
<p style={{ color: '#667085', margin: 0 }}>Выберите причину удаления документа «{targetRow.name}»</p>
|
||
<p style={{ color: 'red', fontSize: 11, margin: 0 }}>Будет удален/заменён сам файл и все его документы</p>
|
||
|
||
<OptionCard
|
||
title='Ошибочный документ'
|
||
detail='Документ будет удален без возможности восстановления.'
|
||
action={
|
||
<Button type='primary' danger loading={isDeleting} onClick={handleDelete}>
|
||
Удалить
|
||
</Button>
|
||
}
|
||
/>
|
||
|
||
<OptionCard
|
||
title='Замена документа'
|
||
detail='Загрузите актуальный файл и укажите причину замены.'
|
||
action={
|
||
<Tooltip title={canReplace ? undefined : 'Замена доступна только в версии в работе'}>
|
||
<Button type='primary' disabled={!canReplace} onClick={onReplace}>
|
||
Заменить
|
||
</Button>
|
||
</Tooltip>
|
||
}
|
||
/>
|
||
</div>
|
||
</Modal>
|
||
);
|
||
}
|