Заглушка модели в useBoardSource стабильна между рендерами, readTheme не возвращает null. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
3.9 KiB
TypeScript
68 lines
3.9 KiB
TypeScript
import { useCallback, useMemo, useState } from "react";
|
|
import { initialSprints, initialWho } from "./analysis/facets.ts";
|
|
import type { LayoutStore } from "./components/BoardCanvas.tsx";
|
|
import * as st from "./storage.ts";
|
|
import type { BoardModel, Filters, JsonImport } from "./types.ts";
|
|
|
|
export interface BoardPrefsApi {
|
|
filters: Filters; snap: boolean; table: boolean; problems: boolean; store: LayoutStore;
|
|
toggle(name: st.FlagName | "snap" | "table" | "problems"): void;
|
|
setSprints(s: Set<string>): void;
|
|
setWho(s: Set<string>): void;
|
|
toggleHidden(what: "kind" | "edge", value: string): void;
|
|
toggleLane(name: string): void;
|
|
moveLane(current: string[], name: string, to: number): void;
|
|
setColWidth(date: string, w: number | null): void;
|
|
resetLayout(): void;
|
|
applyJson(r: JsonImport): void;
|
|
}
|
|
|
|
const readStore = (version: number): LayoutStore =>
|
|
({ laneOrder: st.laneOrder(), folded: st.foldedSet(), colWidths: st.colWidths(), version });
|
|
const pick = (model: BoardModel, f: Filters) =>
|
|
({ model, sprints: initialSprints(model, f, st.rememberedSprints()), who: initialWho(model, f, st.rememberedWho()) });
|
|
|
|
// настройки доски из хранилища links.html: флаги, скрытые виды и типы, выбор спринтов и исполнителей, раскладка
|
|
export function useBoardPrefs(model: BoardModel): BoardPrefsApi {
|
|
const [prefs, setPrefs] = useState<st.BoardPrefs>(() => { st.migrateMode(); st.migrateStore(); return st.readPrefs(); });
|
|
const [store, setStore] = useState<LayoutStore>(() => readStore(0));
|
|
const [sel, setSel] = useState(() => pick(model, prefs.filters));
|
|
if (sel.model !== model) setSel(pick(model, prefs.filters)); // новая модель — выбор заново, как fillSprints/fillWho
|
|
const bump = useCallback(() => setStore((s) => readStore(s.version + 1)), []);
|
|
|
|
const filters = useMemo<Filters>(() => ({ ...prefs.filters, sprints: sel.sprints, who: sel.who }), [prefs.filters, sel]);
|
|
|
|
const toggle = useCallback((name: st.FlagName | "snap" | "table" | "problems") => {
|
|
setPrefs((p) => {
|
|
if (name === "snap" || name === "table" || name === "problems") { st.writeFlag(name, !p[name]); return { ...p, [name]: !p[name] }; }
|
|
st.writeFlag(name, !p.filters[name]);
|
|
return { ...p, filters: { ...p.filters, [name]: !p.filters[name] } };
|
|
});
|
|
}, []);
|
|
const setSprints = useCallback((s: Set<string>) => { st.writeSprints(s); setSel((x) => ({ ...x, sprints: new Set(s) })); }, []);
|
|
const setWho = useCallback((s: Set<string>) => { st.writeWho(s); setSel((x) => ({ ...x, who: new Set(s) })); }, []);
|
|
const toggleHidden = useCallback((what: "kind" | "edge", value: string) => {
|
|
setPrefs((p) => {
|
|
const key = what === "kind" ? "hideKind" : "hideEdge";
|
|
const next = new Set(p.filters[key]);
|
|
if (next.has(value)) next.delete(value); else next.add(value);
|
|
const filters = { ...p.filters, [key]: next };
|
|
st.writeHidden(filters.hideKind, filters.hideEdge);
|
|
return { ...p, filters };
|
|
});
|
|
}, []);
|
|
const toggleLane = useCallback((name: string) => { st.toggleLane(name); bump(); }, [bump]);
|
|
const moveLane = useCallback((current: string[], name: string, to: number) => { if (st.moveLane(current, name, to)) bump(); }, [bump]);
|
|
const setColWidth = useCallback((date: string, w: number | null) => { st.setColWidth(date, w); bump(); }, [bump]);
|
|
const resetLayout = useCallback(() => { st.resetLayout(prefs.filters.byDate); bump(); }, [prefs.filters.byDate, bump]);
|
|
const applyJson = useCallback((r: JsonImport) => {
|
|
const patch = st.applyJsonSettings(r);
|
|
setPrefs((p) => ({ ...p, filters: { ...p.filters, ...patch } }));
|
|
setSel(pick(model, { ...prefs.filters, ...patch }));
|
|
bump();
|
|
}, [model, prefs.filters, bump]);
|
|
|
|
return { filters, snap: prefs.snap, table: prefs.table, problems: prefs.problems, store,
|
|
toggle, setSprints, setWho, toggleHidden, toggleLane, moveLane, setColWidth, resetLayout, applyJson };
|
|
}
|