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 && (
- onConfirmDate?.(col)}>
- {pending ? 'Дата подтверждена (до сохранения)' : 'Подтвердить дату'}
-
+ // короткая подпись, чтобы кнопка помещалась в колонку 112 px и ширина не прыгала (T11.1); длинный текст — в подсказке
+
+ onConfirmDate?.(col)}>
+ {pending ? 'Подтверждено' : 'Подтвердить'}
+
+
)}
);
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 && (
-
- {draft.confirm_report_date ? 'Дата подтверждена (до сохранения)' : 'Подтвердить дату'}
-
+
+
+ {draft.confirm_report_date ? 'Подтверждено' : 'Подтвердить'}
+
+
)}
>
) : (
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)}
+ 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)
+ focusRow(unresolved[0].key)}>
+ {unresolvedHint(unresolved.length)}
+
+ )}
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({
/>
)}
-
+
);
}