Холст доски: высота слоя измерения, сужение выборки, ширина полосы дат (#21)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
86f5ccc981
commit
089c4fb78d
@ -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}
|
||||
|
||||
@ -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 (
|
||||
<>
|
||||
<button onClick={() => setVis(narrow)}>сузить</button>
|
||||
<BoardCanvas vis={vis} byDate={false} snap today="2026-10-14" store={store} sprintSel={new Set<string>()} emptyText="пусто"
|
||||
onToggleLane={vi.fn()} onMoveLane={vi.fn()} onColWidth={vi.fn()} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
renderWithProviders(<Harness />);
|
||||
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/);
|
||||
});
|
||||
});
|
||||
|
||||
@ -135,7 +135,7 @@ export function BoardCanvas({ vis, byDate, snap, today, store, sprintSel, emptyT
|
||||
return (
|
||||
<>
|
||||
{byDate && !empty && layout?.dateCols && placed && (
|
||||
<DatesBar cols={layout.dateCols} width={placed.width} scrollLeft={scroll.left} inRef={datesInRef} onColWidth={onColWidth} />
|
||||
<DatesBar cols={layout.dateCols} width={placed.width} scrollLeft={scroll.left} wrapW={scroll.wrapW} inRef={datesInRef} onColWidth={onColWidth} />
|
||||
)}
|
||||
<div className={"stage" + (byDate && !empty ? " bydate" : "")}>
|
||||
<div className="wrap" ref={wrapRef} onScroll={syncScroll}>
|
||||
@ -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]) => (
|
||||
<Card key={k} node={byKey[k]} box={box} rel={rel[k]} multiSprint={multiSprint} sprintSel={sprintSel}
|
||||
onPointerDown={onCardDown} onAutoSize={onAutoSize} />
|
||||
))}
|
||||
|
||||
@ -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<HTMLDivElement | null>;
|
||||
export function DatesBar({ cols, width, scrollLeft, wrapW, inRef, onColWidth }: {
|
||||
cols: DateCol[]; width: number; scrollLeft: number; wrapW: number; inRef: RefObject<HTMLDivElement | null>;
|
||||
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 (
|
||||
<div className="dates-bar">
|
||||
<div className="dates-in" ref={inRef}>
|
||||
<div className="dates-in" ref={inRef} style={{ width: wrapW }}>
|
||||
<div className="dates-track" style={{ width, transform: `translateX(${-scrollLeft}px)` }}>
|
||||
{cols.map((c) => (
|
||||
<Fragment key={c.date}>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user