AURORA-1683 ревью: клики в поповерах не открывают документ, черновик не переходит на другой документ
I-1: обёртка со stopPropagation вокруг всего Popover (CommentsPopover и FileWarningsPopover);
I-2, M-2: key={doc.id} на боковой панели комментариев; решения R-5…R-12 в design.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
e25dd2e776
commit
8c7146d33e
@ -62,3 +62,11 @@ Goals: комментарий виден после добавления и по
|
||||
| 27.10.2026 | R-2: при нуле комментариев в панели — иконка без числа | макет [39-01] показывает только иконку; «0» шумит в каждой строке | косметика |
|
||||
| 27.10.2026 | R-3: формат времени «dd.mm.yyyy hh:mm» по Москве | даты в панели уже по Москве (`formatMoscowDate`), бэкенд считает даты по Москве | косметика |
|
||||
| 27.10.2026 | R-4: кнопку «Добавить» не прячем без права `DOCUMENT_EDIT`, отказ 403 — сообщением | так работал `CommentModal`; доступ решает сервер (`auth/permissions.ts` — только для меню) | пользователь без права видит кнопку и получает отказ |
|
||||
| 27.10.2026 | R-5: при перечитывании списка после добавления прежний список остаётся на экране до ответа | без мигания индикатора загрузки после «Добавить» | косметика |
|
||||
| 27.10.2026 | R-6: `Drawer size={420}` вместо `width` | antd 6 помечает `width` устаревшим; так же сделано в `FilesDrawer` | нет |
|
||||
| 27.10.2026 | R-7: отступ между полем ввода и «Добавить» — 28 px | счётчик символов `showCount` antd рисуется под полем и наезжал на кнопку (сверка в браузере) | косметика; при смене antd может съехать |
|
||||
| 27.10.2026 | R-8: кнопки строки панели прижаты вправо | кнопка с числом шире пустой, «Удалить» съезжала из столбца | косметика |
|
||||
| 27.10.2026 | R-9: проверка в браузере на копии БД `armka_1683` (alembic 0010), API из worktree с `NATS_ENABLED=false` | общий локальный стенд на 0007, не трогаем | копию удалить при закрытии |
|
||||
| 27.10.2026 | R-10: сценарий спеки «Причина замены документа» в браузере не прогнан | замена требует распознавания (NATS выключен); путь тот же — `postComment` к заменяемому документу + перечитывание панели, список — тот же `GET` | проверить на нашем стенде при выкладке |
|
||||
| 27.10.2026 | R-11: защита от всплытия клика к строке таблицы — обёртка со `stopPropagation` вокруг всего `Popover` (финальное ревью I-1); тот же дефект исправлен и в `FileWarningsPopover` | заголовок, отступы и стрелка поповера antd лежат вне `content`, клик по ним открывал документ; у `FileWarningsPopover` дефект был до ветки, приём тот же | нет |
|
||||
| 27.10.2026 | R-12: `key={doc.id}` на боковой панели экрана документа (финальное ревью I-2, M-2) | `DocumentPage` не пересоздаётся при смене документа — черновик и список прежнего документа переходили на новый, а удалить комментарий нельзя | нет |
|
||||
|
||||
@ -16,5 +16,6 @@
|
||||
## 4. Проверки
|
||||
|
||||
- [x] 4.1 Сценарии в браузере (1600×1000): добавление и перезагрузка, ошибка 403, многострочный и длинный текст, счётчик и
|
||||
поповер в панели, пустой поповер, клики не открывают документ.
|
||||
поповер в панели, пустой поповер, клики не открывают документ. Сценарий «Причина замены документа» не прогнан
|
||||
(R-10 в design.md) — проверить на нашем стенде при выкладке.
|
||||
- [x] 4.2 `npm test`, `npm run lint`, `make web-check`, `openspec validate document-comments-ui --strict`.
|
||||
|
||||
@ -133,7 +133,8 @@ export function DocumentPage() {
|
||||
{!broken && kind === 'statement' && <StatementReview key={doc.id} document={doc} onChanged={load} />}
|
||||
{kind === 'none' && <Empty description='Документ без данных для проверки' />}
|
||||
</main>
|
||||
<DocumentCommentsDrawer documentId={doc.id} open={commentOpen} onClose={() => setCommentOpen(false)} onAdded={load} />
|
||||
{/* key: при смене документа панель пересоздаётся — черновик и список прежнего документа не переходят на новый */}
|
||||
<DocumentCommentsDrawer key={doc.id} documentId={doc.id} open={commentOpen} onClose={() => setCommentOpen(false)} onAdded={load} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -16,11 +16,7 @@ export function CommentsPopover({ documentId, fileName, count }: { documentId: s
|
||||
};
|
||||
|
||||
const content = (
|
||||
<div
|
||||
// клики внутри поповера всплывают по дереву React до onClick строки таблицы и открывали бы документ
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
style={{ width: 360, maxWidth: 420 }}>
|
||||
<div style={{ width: 360, maxWidth: 420 }}>
|
||||
<div style={{ maxHeight: 320, overflowY: 'auto', marginBottom: 8 }}>
|
||||
<CommentsList state={state} emptyText='Комментарий отсутствует' />
|
||||
</div>
|
||||
@ -33,10 +29,14 @@ export function CommentsPopover({ documentId, fileName, count }: { documentId: s
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover trigger='click' title={`Комментарии к документу ${fileName}`} content={content} open={open} onOpenChange={onOpenChange}>
|
||||
<Button icon={<CommentOutlined />} aria-label={`Комментарии: ${count}`} onClick={(e) => e.stopPropagation()}>
|
||||
{count > 0 ? count : null}
|
||||
</Button>
|
||||
</Popover>
|
||||
// Поповер рисуется в портале, но события React всплывают по дереву компонентов до onClick строки таблицы и открывали
|
||||
// бы документ. Обёртка вокруг всего Popover ловит клики по кнопке, заголовку, отступам и содержимому разом.
|
||||
<span onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>
|
||||
<Popover trigger='click' title={`Комментарии к документу ${fileName}`} content={content} open={open} onOpenChange={onOpenChange}>
|
||||
<Button icon={<CommentOutlined />} aria-label={`Комментарии: ${count}`}>
|
||||
{count > 0 ? count : null}
|
||||
</Button>
|
||||
</Popover>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@ -70,11 +70,7 @@ export function FileWarningsPopover({ row, badge }: { row: DocumentRow; badge: {
|
||||
};
|
||||
|
||||
const content = (
|
||||
<div
|
||||
// клики внутри поповера всплывают по дереву React до onClick строки таблицы и открывали бы документ
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
style={{ maxWidth: 420, maxHeight: 320, overflowY: 'auto' }}>
|
||||
<div style={{ maxWidth: 420, maxHeight: 320, overflowY: 'auto' }}>
|
||||
{row.fileWarnings.length > 0 && (
|
||||
<Section title='Предупреждения файла'>
|
||||
{row.fileWarnings.map((w, i) => (
|
||||
@ -104,22 +100,25 @@ export function FileWarningsPopover({ row, badge }: { row: DocumentRow; badge: {
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover trigger='click' title='Предупреждения' content={content} onOpenChange={onOpenChange}>
|
||||
<button
|
||||
type='button'
|
||||
aria-label={`Предупреждения: ${badge.count}`}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
fontSize: 12,
|
||||
whiteSpace: 'nowrap',
|
||||
color: badge.level === 'error' ? '#cf1322' : '#1677ff',
|
||||
}}>
|
||||
<SeverityIcon severity={badge.level} /> {badge.count}
|
||||
</button>
|
||||
</Popover>
|
||||
// клики по кнопке, заголовку и содержимому поповера (он в портале, но события React всплывают по дереву компонентов)
|
||||
// дошли бы до onClick строки таблицы и открыли документ — гасим их обёрткой вокруг всего Popover
|
||||
<span onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>
|
||||
<Popover trigger='click' title='Предупреждения' content={content} onOpenChange={onOpenChange}>
|
||||
<button
|
||||
type='button'
|
||||
aria-label={`Предупреждения: ${badge.count}`}
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
fontSize: 12,
|
||||
whiteSpace: 'nowrap',
|
||||
color: badge.level === 'error' ? '#cf1322' : '#1677ff',
|
||||
}}>
|
||||
<SeverityIcon severity={badge.level} /> {badge.count}
|
||||
</button>
|
||||
</Popover>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user