diff --git a/src/widgets/DocumentReview/ColumnHeader.tsx b/src/widgets/DocumentReview/ColumnHeader.tsx index 7c44e3f..b585d98 100644 --- a/src/widgets/DocumentReview/ColumnHeader.tsx +++ b/src/widgets/DocumentReview/ColumnHeader.tsx @@ -51,9 +51,18 @@ export function ColumnHeader({ col, issues, editing, draftDate, error = false, o style={{ marginTop: 4, fontWeight: 400 }} /> {canConfirm && ( - + // короткая подпись, чтобы кнопка помещалась в колонку 112 px и ширина не прыгала (T11.1); длинный текст — в подсказке + + + )} ); diff --git a/src/widgets/DocumentReview/StatementHeaderBlock.tsx b/src/widgets/DocumentReview/StatementHeaderBlock.tsx index 56d1094..01f2480 100644 --- a/src/widgets/DocumentReview/StatementHeaderBlock.tsx +++ b/src/widgets/DocumentReview/StatementHeaderBlock.tsx @@ -45,7 +45,12 @@ export function StatementHeaderBlock({ header, documentType, editing, draft, onD const reportDate = formatReportDate(header.report_date.value); return (
- +
+ {/* фиксированная раскладка: ширина блока не зависит от содержимого и подписи кнопки (T11.6) */} + + + + {headerFields(header, byField).map((r) => ( @@ -54,7 +59,6 @@ export function StatementHeaderBlock({ header, documentType, editing, draft, onD style={{ ...cell, fontWeight: 600, - minWidth: r.field === 'organization_name' ? 320 : 160, background: fieldBackground(r.modified, r.attention), }}> {r.issues.length > 0 && ( @@ -74,9 +78,16 @@ export function StatementHeaderBlock({ header, documentType, editing, draft, onD onChange={(e) => onDraftChange(r.field, e.target.value)} /> {r.canConfirm && onConfirmDate && ( - + + + )} ) : ( diff --git a/src/widgets/DocumentReview/StatementReview.tsx b/src/widgets/DocumentReview/StatementReview.tsx index 1ab3ac7..bc61dad 100644 --- a/src/widgets/DocumentReview/StatementReview.tsx +++ b/src/widgets/DocumentReview/StatementReview.tsx @@ -208,7 +208,9 @@ export function StatementReview({ document, onChanged }: { document: DocumentOut confirmDescription = confirmFailures.map((f) =>
{failureText(f)}
); } else if (confirmLines.length > 0) { confirmDescription = ( - focusRow(confirmLines[0].line_id)}>{unresolvedHint(confirmLines.length)} + ); } else if (duplicateId) { confirmDescription = ( @@ -242,9 +244,6 @@ export function StatementReview({ document, onChanged }: { document: DocumentOut onClick={confirm}> Подтвердить данные - {unresolved.length > 0 && ( - focusRow(unresolved[0].key)}>{unresolvedHint(unresolved.length)} - )} ); @@ -259,6 +258,12 @@ export function StatementReview({ document, onChanged }: { document: DocumentOut
+ {unresolved.length > 0 && ( + // настоящая кнопка: достижима Tab, срабатывает по Enter; отдельной строкой, чтобы не ломать заголовок (T11.7) + + )} void; }; +const ICON_WIDTH = 18; // значок уровня с отступом: у ребёнка вычитается из отступа, чтобы текст не съезжал const CHILD_INDENT = 20; // отступ названия строки детализации под родителем function lineWeight(r: LayoutRow): number | undefined { @@ -89,7 +90,7 @@ export function StatementTable({ const rowIssues = places.byRow.get(r.key) ?? []; const rowWorst = worstSeverity(rowIssues); const text = ( - + {r.displayName || '—'} {r.secondaryName && ( @@ -111,9 +112,11 @@ export function StatementTable({ ) : ( namedText ); - if (!rowWorst) return named; + // отступ ребёнка — на общей обёртке: значок уровня остаётся внутри отступа и не сдвигает текст (T11.8) + const indent = r.child ? CHILD_INDENT : undefined; + if (!rowWorst) return
{named}
; return ( - <> +
(
{i.message}
@@ -123,16 +126,16 @@ export function StatementTable({
{named} - +
); }, }, { key: 'code', title: 'Код', - width: editable ? 160 : 60, + width: editable ? 160 : 84, align: 'center' as const, - onCell: (r) => (r.kind === 'section' ? sectionSpan(r, false) : { style: { background: labelBackground(r) } }), + onCell: (r) => (r.kind === 'section' ? sectionSpan(r, false) : { style: { background: labelBackground(r), whiteSpace: 'nowrap' } }), render: (_: unknown, r: LayoutRow) => { if (r.kind !== 'line') return null; const lineId = r.row.lineId; @@ -161,7 +164,7 @@ export function StatementTable({ onConfirmDate={onColumnDateConfirm} /> ), - width: 112, + width: 128, align: 'right' as const, onCell: (r: LayoutRow) => r.kind === 'section' @@ -198,6 +201,7 @@ export function StatementTable({ return ( size='small' + tableLayout='fixed' bordered rowKey='key' columns={tableColumns} diff --git a/src/widgets/DocumentReview/ValueCell.tsx b/src/widgets/DocumentReview/ValueCell.tsx index c5d920c..6681191 100644 --- a/src/widgets/DocumentReview/ValueCell.tsx +++ b/src/widgets/DocumentReview/ValueCell.tsx @@ -1,9 +1,9 @@ import { CheckOutlined, UndoOutlined } from '@ant-design/icons'; -import { Button, Input, Tooltip } from 'antd'; +import { Button, Input, Tooltip, Typography } from 'antd'; import type { IssueOut, ValueOut } from '../../types/api'; -import { formatAmount, parseAmountInput } from '../../utils/money'; +import { parseAmountInput } from '../../utils/money'; import { SeverityIcon } from './IssuesPanel'; -import { cellTipLines } from './cellView'; +import { cellTipLines, valueCellText } from './cellView'; import type { CellConfirmState } from './editRules'; import { worstSeverity } from './issuePlaces'; @@ -51,17 +51,19 @@ export function ValueCell({ }: Props) { const lines = cellTipLines(value, issues); const worst = worstSeverity(issues); - // значок — в левом углу ячейки; поверх ввода и текста, не двигает суммы - const corner = worst && ; + const shown = valueCellText(value); + // значок уровня — внутри ячейки, слева от суммы, по центру по вертикали (T11.3) + const corner = worst && ; const tip = lines.length > 0 ? lines.map((line, i) =>
{line}
) : undefined; if (!editable) { return ( + // подсказка на всей ячейке: блок на всю ширину колонки (T11.4) - +
{corner} - {value.is_confirmed && } - {formatAmount(value.amount, { fraction: 'auto', empty: '-' })} - + {value.is_confirmed && } + {shown.muted ? {shown.text} : shown.text} +
); } @@ -70,7 +72,7 @@ export function ValueCell({ const pending = confirmState === 'pending-confirm' || confirmState === 'pending-unconfirm'; return ( - +
{corner} : undefined} value={text} onChange={(e) => onDraftChange(draftKey, e.target.value, value.amount)} - // значок записи лежит в левом углу поверх поля — освобождаем ему место, чтобы не налезал на галочку и текст - style={{ textAlign: 'right', paddingLeft: worst ? 14 : undefined }} + style={{ textAlign: 'right', minWidth: 0, flex: 1 }} /> {confirmState && ( @@ -93,7 +94,7 @@ export function ValueCell({ /> )} - +
); }