fix(web): уведомления вкладки корректировок — внутри бокса, видны в полноэкранном режиме (#206)

I-1: локальный notification.useNotification с getContainer на бокс вкладки; M-6, M-8: комментарии.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-28 22:15:41 +04:00
parent d43149022b
commit f4a4f01c28

View File

@ -1,5 +1,6 @@
// Вкладка «Таблица корректировки»: загрузка, состояния, панель и таблица. Правки (окно, решения по строкам) — в следующих задачах.
import { App, Button, ConfigProvider, Spin } from 'antd';
// Вкладка «Таблица корректировки»: загрузка, состояния, панель, таблица, решения по строкам, отмена и окно корректировки.
// Данные и фильтры держит она.
import { Button, ConfigProvider, Spin, notification as antdNotification } from 'antd';
import { type ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { ApiError } from '../../api/client';
import { useVisibleColumns } from '../../components/GenericTable/useVisibleColumns';
@ -7,7 +8,6 @@ import { allocate, exportCorrectionTable, revokeCorrection } from '../../service
import type { VersionCard } from '../../types/consolidations/version_members';
import type { AllocationIn, CorrectionAggregateOut } from '../../types/corrections';
import { saveBlob, xlsxFilename } from '../../utils/download';
import { useNotificationApi } from '../../utils/useNotification';
import { useNumberDisplay } from '../ConsolidatedOsv/useNumberDisplay';
import { CorrectionEditorModal } from './CorrectionEditorModal';
import { CorrectionTable, type RowActions } from './CorrectionTable';
@ -33,8 +33,17 @@ type Props = { versionId: string; card?: VersionCard | null };
export function CorrectionContent({ versionId, card = null }: Props) {
const { table, loading, error, reload, replace, replaceAggregate } = useCorrectionTable(versionId);
const { notification } = App.useApp();
const notify = useNotificationApi();
const boxRef = useRef<HTMLDivElement>(null);
// уведомления рисуются внутри бокса вкладки: в полноэкранном режиме виден только полноэкранный элемент,
// глобальные уведомления за ним не видны
const [notification, holder] = antdNotification.useNotification({ getContainer: () => boxRef.current ?? document.body });
const notify = useMemo(
() => ({
error: ({ description }: { description: ReactNode }) =>
notification.error({ title: 'Ошибка', description, placement: 'bottomRight' }),
}),
[notification],
);
// по умолчанию — «тыс. руб.», 2 знака, как в дизайне
const { unit, setUnit, precision, setPrecision, format } = useNumberDisplay({ unit: 'тыс. руб.', precision: 2 });
const [filters, setFilters] = useState<TableFilters>(EMPTY_FILTERS);
@ -49,7 +58,6 @@ export function CorrectionContent({ versionId, card = null }: Props) {
const [revoking, setRevoking] = useState<CorrectionAggregateOut | null>(null);
// ключ агрегата, окно корректировки которого открыто
const [editing, setEditing] = useState<string | null>(null);
const boxRef = useRef<HTMLDivElement>(null);
// ошибка загрузки — уведомление с текстом сервера и кнопкой «Повторить»
useEffect(() => {
@ -124,7 +132,8 @@ export function CorrectionContent({ versionId, card = null }: Props) {
return next;
});
// ошибка правки: текст сервера в уведомлении; 409 (версию закрыли, блокировку забрали, корректировку уже изменили) — ещё перечитываем таблицу
// ошибка правки: текст сервера в уведомлении;
// 409 (версию закрыли, блокировку забрали, корректировку уже изменили) — ещё перечитываем таблицу
const fail = (e: unknown, fallback: string) => {
const out = errorOutcome(e, fallback);
notify.error({ description: out.message });
@ -227,6 +236,7 @@ export function CorrectionContent({ versionId, card = null }: Props) {
height: fullscreen ? '100vh' : undefined,
overflow: 'hidden',
}}>
{holder}
<CorrectionToolbar
rules={table?.rules ?? []}
filters={filters}