arm-web/src/widgets/DocumentReview/StatementTable.tsx

74 lines
2.5 KiB
TypeScript

import { Input, Table, Tooltip } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { ColumnOut, ValueOut } from '../../types/api';
import { formatAmount, parseAmountInput } from '../../utils/money';
import { columnTitle } from './reviewView';
import { type GridRow, cellFlags, cellKey } from './statementGrid';
type Props = {
columns: ColumnOut[];
rows: GridRow[];
editable: boolean;
draft: Record<string, string>;
onDraftChange: (key: string, text: string, originalAmount: string | null) => void;
};
const ATTENTION_BG = '#fff7e6';
const MODIFIED_BG = '#e6f4ff';
function cellBackground(value: ValueOut | undefined): string | undefined {
const flags = cellFlags(value);
if (flags.modified) {
return MODIFIED_BG;
}
return flags.attention ? ATTENTION_BG : undefined;
}
function cellTip(value: ValueOut): string | undefined {
if (value.is_modified) {
return `Исходное: ${formatAmount(value.original_amount, { fraction: 'auto', empty: '-' })}`;
}
return value.confidence ? `Уверенность: ${value.confidence}%` : undefined;
}
export function StatementTable({ columns, rows, editable, draft, onDraftChange }: Props) {
const tableColumns: ColumnsType<GridRow> = [
{ key: 'name', title: 'Наименование показателя', dataIndex: 'name' },
{ key: 'code', title: 'Код', dataIndex: 'code', width: 70, align: 'center' as const },
...columns.map((col) => ({
key: col.id,
title: columnTitle(col),
width: 140,
align: 'right' as const,
onCell: (row: GridRow) => {
return { style: { background: cellBackground(row.cells[col.id]) } };
},
render: (_: unknown, row: GridRow) => {
const value = row.cells[col.id];
if (!value) {
return null;
}
const key = cellKey(row.lineId, col.id);
const tip = cellTip(value);
if (!editable) {
return <Tooltip title={tip}>{formatAmount(value.amount, { fraction: 'auto', empty: '-' })}</Tooltip>;
}
const text = draft[key] ?? value.amount ?? '';
const invalid = key in draft && !parseAmountInput(text).ok;
return (
<Tooltip title={invalid ? 'Неверный формат суммы' : tip}>
<Input
size='small'
status={invalid ? 'error' : undefined}
value={text}
onChange={(e) => onDraftChange(key, e.target.value, value.amount)}
style={{ textAlign: 'right' }}
/>
</Tooltip>
);
},
})),
];
return <Table<GridRow> size='small' bordered rowKey='key' columns={tableColumns} dataSource={rows} pagination={false} />;
}