- Sidebar: после создания консолидации перечитывается список группы - useLegalEntityFiles: убран biome-ignore в зависимостях эффекта - FilesDrawer: курсор и pointer-events у недоступной кнопки загрузки - design.md: решения R-4..R-8 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
110 lines
4.2 KiB
TypeScript
110 lines
4.2 KiB
TypeScript
import { CloseOutlined, UploadOutlined } from '@ant-design/icons';
|
||
import { Button, Drawer, Switch, Tooltip, Typography } from 'antd';
|
||
import { useEffect, useState } from 'react';
|
||
import { fetchLegalEntity } from '../../services/api/directories/company_groups';
|
||
import { isInWork, useCurrentConsolidation } from '../../store/slices/consolidations/selectors';
|
||
import { useAppSelector } from '../../store/store';
|
||
import type { FileOut, LegalEntityBrief } from '../../types/api';
|
||
import { FilesList } from './FilesList';
|
||
import { UploadDocumentsModal } from './UploadDocumentsModal';
|
||
import { consolidationLabel } from './consolidationLabel';
|
||
import { useLegalEntityFiles } from './useLegalEntityFiles';
|
||
|
||
const UPLOAD_DISABLED_HINT = 'Загрузка доступна только в версии в работе';
|
||
|
||
export function DocumentsDrawer({ open, onClose }: { open: boolean; onClose: () => void }) {
|
||
const [uploadOpen, setUploadOpen] = useState(false);
|
||
const [entity, setEntity] = useState<LegalEntityBrief | null>(null);
|
||
const [showAll, setShowAll] = useState(false);
|
||
const { current_legal_entity_id, consolidations } = useAppSelector((s) => s.consolidations);
|
||
const current = useCurrentConsolidation();
|
||
// консолидация не определена (версии нет в списке ГК) — режим «все» без переключателя (design D-3)
|
||
const desk = current !== null && !showAll;
|
||
const consolidationId = desk ? current.consolidation_id : null;
|
||
const { files, loading, reload } = useLegalEntityFiles(current_legal_entity_id, consolidationId, open);
|
||
const canUpload = current !== null && isInWork(current.version_status);
|
||
const labelFor = desk
|
||
? undefined
|
||
: (f: FileOut) => consolidationLabel(f.consolidation_id, consolidations, current?.consolidation_id ?? null);
|
||
|
||
useEffect(() => {
|
||
setShowAll(false); // новая панель открывается столом консоли
|
||
setEntity(null);
|
||
if (!open || !current_legal_entity_id) return;
|
||
let cancelled = false;
|
||
fetchLegalEntity(current_legal_entity_id)
|
||
.then((e) => {
|
||
if (!cancelled) setEntity(e);
|
||
})
|
||
.catch(() => {
|
||
// без имени: шапка остаётся с подписью, панель не падает
|
||
});
|
||
return () => {
|
||
cancelled = true;
|
||
};
|
||
}, [open, current_legal_entity_id]);
|
||
|
||
const uploadButton = (
|
||
<Button
|
||
type='primary'
|
||
icon={<UploadOutlined />}
|
||
disabled={!current_legal_entity_id || !canUpload}
|
||
onClick={() => setUploadOpen(true)}
|
||
style={canUpload ? { background: '#237804' } : { pointerEvents: 'none' }}>
|
||
Загрузить документы
|
||
</Button>
|
||
);
|
||
|
||
return (
|
||
<Drawer
|
||
open={open}
|
||
onClose={onClose}
|
||
destroyOnHidden
|
||
size={820}
|
||
closable={false}
|
||
extra={<Button icon={<CloseOutlined />} aria-label='Закрыть' onClick={onClose} />}
|
||
title={
|
||
<div>
|
||
<Typography.Text type='secondary' style={{ fontSize: 11, letterSpacing: 0.5, textTransform: 'uppercase' }}>
|
||
Первичные документы
|
||
</Typography.Text>
|
||
{entity && (
|
||
<>
|
||
<div style={{ fontSize: 20, fontWeight: 500, marginTop: 4 }}>{entity.name}</div>
|
||
<Typography.Text type='secondary' style={{ fontSize: 13, fontWeight: 400 }}>
|
||
{entity.inn}
|
||
</Typography.Text>
|
||
</>
|
||
)}
|
||
</div>
|
||
}>
|
||
<div style={{ marginBottom: 16, display: 'flex', alignItems: 'center', gap: 16 }}>
|
||
{canUpload ? (
|
||
uploadButton
|
||
) : (
|
||
<Tooltip title={UPLOAD_DISABLED_HINT}>
|
||
<span style={{ display: 'inline-block', cursor: 'not-allowed' }}>{uploadButton}</span>
|
||
</Tooltip>
|
||
)}
|
||
{current !== null && (
|
||
<span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||
<Switch size='small' checked={showAll} onChange={setShowAll} />
|
||
<Typography.Text>Все документы организации</Typography.Text>
|
||
</span>
|
||
)}
|
||
</div>
|
||
<FilesList files={files} loading={loading} labelFor={labelFor} />
|
||
{current_legal_entity_id && (
|
||
<UploadDocumentsModal
|
||
legalEntityId={current_legal_entity_id}
|
||
consolidationId={current?.consolidation_id ?? null}
|
||
organizationName={entity?.name ?? null}
|
||
open={uploadOpen}
|
||
onClose={() => setUploadOpen(false)}
|
||
onUploaded={() => void reload()}
|
||
/>
|
||
)}
|
||
</Drawer>
|
||
);
|
||
}
|