From 089c4fb78d435c17faeef05e855135625209348c Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Wed, 14 Oct 2026 23:09:47 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A5=D0=BE=D0=BB=D1=81=D1=82=20=D0=B4=D0=BE?= =?UTF-8?q?=D1=81=D0=BA=D0=B8:=20=D0=B2=D1=8B=D1=81=D0=BE=D1=82=D0=B0=20?= =?UTF-8?q?=D1=81=D0=BB=D0=BE=D1=8F=20=D0=B8=D0=B7=D0=BC=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F,=20=D1=81=D1=83=D0=B6=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=BA=D0=B8,=20=D1=88?= =?UTF-8?q?=D0=B8=D1=80=D0=B8=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=BB=D0=BE=D1=81?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=B0=D1=82=20(#21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- web/src/board/board.css | 2 +- web/src/board/components/BoardCanvas.test.tsx | 26 +++++++++++++++++++ web/src/board/components/BoardCanvas.tsx | 4 +-- web/src/board/components/DatesBar.tsx | 6 ++--- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/web/src/board/board.css b/web/src/board/board.css index 454be46..53faf54 100644 --- a/web/src/board/board.css +++ b/web/src/board/board.css @@ -157,5 +157,5 @@ td.k{font-family:var(--font-mono);font-size:12px;white-space:nowrap} .card .open-card:hover,.card .open-card:focus-visible{color:var(--accent);outline:none} /* слой измерения: карточки шириной CW с высотой по содержимому, невидим */ .measure{position:absolute;left:-100000px;top:0;visibility:hidden;pointer-events:none} -.measure .card{position:static} +.measure .card{position:static;height:auto} .measure .card .title{-webkit-line-clamp:unset} diff --git a/web/src/board/components/BoardCanvas.test.tsx b/web/src/board/components/BoardCanvas.test.tsx index 909f536..757fe14 100644 --- a/web/src/board/components/BoardCanvas.test.tsx +++ b/web/src/board/components/BoardCanvas.test.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import { fireEvent, screen, within } from "@testing-library/react"; import { readFileSync } from "node:fs"; import { join } from "node:path"; @@ -85,4 +86,29 @@ describe("BoardCanvas", () => { draw({ vis: computeVisible(model, { ...noFilters(), who: new Set(["Никто"]) }, [], "2026-10-14"), emptyText: "Фильтры не оставили" }); expect(screen.getByText("Фильтры не оставили")).toBeInTheDocument(); }); + + it("сужение выборки при смене фильтра не роняет холст (карточки старой раскладки пропускаются)", () => { + const wide = computeVisible(model, noFilters(), [], "2026-10-14"); + const narrow = computeVisible(model, { ...noFilters(), who: new Set(["Иванов Иван Иванович"]) }, [], "2026-10-14"); + expect(narrow.nodes.length).toBeLessThan(wide.nodes.length); + function Harness() { + const [vis, setVis] = useState(wide); + return ( + <> + + ()} emptyText="пусто" + onToggleLane={vi.fn()} onMoveLane={vi.fn()} onColWidth={vi.fn()} /> + + ); + } + renderWithProviders(); + expect(board().querySelectorAll(".card[data-key]")).toHaveLength(wide.nodes.length); + fireEvent.click(screen.getByText("сузить")); + expect(board().querySelectorAll(".card[data-key]").length).toBeLessThanOrEqual(narrow.nodes.length); + }); + + it("полоса дат получает ширину обёртки доски", () => { + draw({ byDate: true }); + expect((document.querySelector(".dates-in") as HTMLElement).style.width).toMatch(/px$|^0/); + }); }); diff --git a/web/src/board/components/BoardCanvas.tsx b/web/src/board/components/BoardCanvas.tsx index 35d0565..f213dda 100644 --- a/web/src/board/components/BoardCanvas.tsx +++ b/web/src/board/components/BoardCanvas.tsx @@ -135,7 +135,7 @@ export function BoardCanvas({ vis, byDate, snap, today, store, sprintSel, emptyT return ( <> {byDate && !empty && layout?.dateCols && placed && ( - + )}
@@ -153,7 +153,7 @@ export function BoardCanvas({ vis, byDate, snap, today, store, sprintSel, emptyT targetClass={dragTarget && dragTarget.to === i ? (i < dragTarget.from ? "target" : i > dragTarget.from ? "target-after" : "") : ""} onDragTarget={(to) => setDragTarget(to === null ? null : { from: i, to })} /> ))} - {Object.entries(placed.pos).map(([k, box]) => ( + {Object.entries(placed.pos).filter(([k]) => byKey[k]).map(([k, box]) => ( ))} diff --git a/web/src/board/components/DatesBar.tsx b/web/src/board/components/DatesBar.tsx index 5cccbc4..dda5021 100644 --- a/web/src/board/components/DatesBar.tsx +++ b/web/src/board/components/DatesBar.tsx @@ -3,8 +3,8 @@ import { COLW, GRID } from "../constants.ts"; import { dateText, dateTitle, type DateCol } from "../layout/layout.ts"; // липкая полоса подписей дат над доской: сдвиг — как у горизонтальной прокрутки доски; ручка границы меняет ширину колонки -export function DatesBar({ cols, width, scrollLeft, inRef, onColWidth }: { - cols: DateCol[]; width: number; scrollLeft: number; inRef: RefObject; +export function DatesBar({ cols, width, scrollLeft, wrapW, inRef, onColWidth }: { + cols: DateCol[]; width: number; scrollLeft: number; wrapW: number; inRef: RefObject; onColWidth(date: string, w: number | null): void; }) { const raf = useRef(0); @@ -28,7 +28,7 @@ export function DatesBar({ cols, width, scrollLeft, inRef, onColWidth }: { const cls = (c: DateCol) => (c.cls ? " " + c.cls : ""); return (
-
+
{cols.map((c) => (