sdlc-hub/web/src/board/components/ProblemsDrawer.tsx
Andrey Epifancev 66bcb7e293 feat(web): страница доски — панель, фильтры, легенда, проблемы, таблица, экспорт (#21)
Заглушка модели в useBoardSource стабильна между рендерами, readTheme не возвращает null.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 23:14:13 +04:00

31 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { JIRA_URL } from "../constants.ts";
import type { ProblemItem, Problems } from "../types.ts";
export const problemCount = (p: Problems) => p.dates.length + p.unassigned.length + p.late.length;
const K = ({ k }: { k: string }) => <a className="k" href={`${JIRA_URL}/browse/${k}`} target="_blank" rel="noopener">{k}</a>;
function Section({ title, list }: { title: string; list: ProblemItem[] }) {
if (!list.length) return null;
return (
<>
<h4>{title} ({list.length})</h4>
<ul>{list.map((x, i) => <li key={i}><K k={x.a.key} /> → <K k={x.b.key} /> <span className="why">— {x.text}</span></li>)}</ul>
</>
);
}
export function ProblemsDrawer({ problems, onClose }: { problems: Problems; onClose(): void }) {
return (
<aside className="drawer">
<div className="drawer-head"><b>Проблемы на доске</b><button type="button" className="btn sm" onClick={onClose}>Закрыть</button></div>
<div>
{!problemCount(problems) && <div className="ok">По датам, исполнителям и статусам блокеров на видимой части доски проблем нет.</div>}
<Section title="Срок блокера не раньше срока зависимой задачи" list={problems.dates} />
<Section title="Блокер без исполнителя" list={problems.unassigned} />
<Section title="Блокер не начат, а срок зависимой задачи близко" list={problems.late} />
<Section title="Передачи между исполнителями (точки ожидания)" list={problems.hand} />
</div>
</aside>
);
}