sdlc-hub/web/src/board/exportJson.ts

36 lines
2.6 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.

// полный снимок доски: все задачи и связи, обе раскладки относительно дорожек (layout — обычная, layoutByDate — «по датам»; h только если задана вручную),
// порядок и свёртка дорожек, фильтры. Текущую раскладку компонент сохраняет в хранилище (saveLayout) перед вызовом
import { JIRA_URL } from "./constants.ts";
import { colWidths, foldedSet, laneOrder, savedLayout } from "./storage.ts";
import type { BoardModel, Filters, Visible } from "./types.ts";
type Saved = Record<string, { x: number; ry: number; w?: number; h?: number }>;
export function exportJson(model: BoardModel, vis: Visible, f: Filters, now: string): unknown {
const savedPos = (savedLayout(false) || {}) as Saved, savedDate = (savedLayout(true) || {}) as Saved;
const shown = new Set(vis.nodes.map((n) => n.key));
const fromSaved = (saved: Saved, k: string) => {
const r = saved[k]; if (!r) return null;
const o: { x: number; ry: number; w?: number; h?: number } = { x: r.x, ry: r.ry };
if (typeof r.w === "number") o.w = r.w; // запись без w допустима (как в эталоне)
if (typeof r.h === "number") o.h = r.h;
return o;
};
const nodes = model.nodes.filter((n) => !n.stub).map((n) => ({
key: n.key, title: n.title, status: n.status, priority: n.prio, kind: n.kind, due: n.due || null, assignee: n.who || null, sprint: n.sprint || null, epic: n.epic,
url: `${JIRA_URL}/browse/${n.key}`, visible: shown.has(n.key), layout: fromSaved(savedPos, n.key), layoutByDate: fromSaved(savedDate, n.key),
}));
const order = laneOrder();
return {
format: "arm-ka-links/1", exportedAt: now, source: model.fileName,
filters: { sprints: [...f.sprints], assignees: [...f.who], neighbors: f.neighbors, onlyLinked: f.onlyLinked, onlyHand: f.onlyHand, criticalPath: f.crit, byDate: f.byDate,
hiddenKinds: [...f.hideKind], hiddenEdges: [...f.hideEdge] },
laneOrder: order.length ? order : vis.lanes.map((l) => l.name), collapsedLanes: [...foldedSet()], dateColumns: colWidths(),
nodes, links: model.links.map((l) => ({ from: l.src, to: l.dst, type: l.type })),
};
}
// имя файла выгрузки: links-<имя исходного файла без .csv>-<дата>.json
export function exportFileName(model: BoardModel, now: string): string {
return `links-${(model.fileName || "board").replace(/[^\wА-Яа-яЁё.-]+/g, "_").replace(/\.csv$/i, "")}-${now.slice(0, 10)}.json`;
}