51 lines
2.9 KiB
TypeScript
51 lines
2.9 KiB
TypeScript
import type { Project } from "../../../api/types.ts";
|
|
import { PageHeader } from "../../../ui/index.ts";
|
|
import { RefreshButton } from "../RefreshButton.tsx";
|
|
import { AgileGate } from "./AgileGate.tsx";
|
|
import { AgileToolbar } from "./AgileToolbar.tsx";
|
|
import { BoardColumns } from "./BoardColumns.tsx";
|
|
import { ColumnsMenu } from "./ColumnsMenu.tsx";
|
|
import { columnsOf } from "./columns.ts";
|
|
import { assigneeOptions, matches } from "./filters.ts";
|
|
import { AgileIssueRow } from "./IssueRow.tsx";
|
|
import { useAgileView } from "./useAgileView.ts";
|
|
import "./agile.css";
|
|
|
|
// «Kanban» (spec web-app): колонки доски; при включённом бэклоге Jira первая колонка не рисуется, её задачи — в «Бэклог (N)» (R-18).
|
|
// «Скрыть выполненные» здесь нет: даже сохранённое hideDone не применяется (последняя колонка и так ограничена «за 14 дней»)
|
|
export function KanbanPage({ project }: { project: Project }) {
|
|
const { view, set, setQ, filter, reset } = useAgileView(project.label, "kanban");
|
|
const kfilter = { ...filter, hideDone: false };
|
|
return (
|
|
<div data-testid="page-kanban" className="agile agile--wide">
|
|
<PageHeader title="Kanban" actions={<RefreshButton />} />
|
|
<AgileGate project={project} kind="kanban">
|
|
{(d) => {
|
|
const withBacklog = d.board?.kanban_backlog === true;
|
|
const cols = d.board?.columns ?? null;
|
|
const issues = (d.board_issues ?? []).filter((i) => matches(i, kfilter)); // сервер уже убрал задачи первой колонки, если бэклог включён
|
|
const backlog = (d.backlog ?? []).filter((i) => matches(i, kfilter));
|
|
const boardCols = withBacklog && cols ? cols.slice(1) : cols;
|
|
const views = columnsOf(boardCols, issues);
|
|
const allNames = columnsOf(boardCols, d.board_issues ?? []).map((c) => c.name); // меню — по задачам без фильтров (T7.2)
|
|
return (
|
|
<>
|
|
<AgileToolbar filter={kfilter} setQ={setQ} set={set} onReset={reset} showHideDone={false}
|
|
assignees={assigneeOptions([...(d.board_issues ?? []), ...(d.backlog ?? [])], view.assignee)}>
|
|
<ColumnsMenu names={allNames} hidden={view.hiddenColumns} onChange={(hiddenColumns) => set({ hiddenColumns })} />
|
|
</AgileToolbar>
|
|
{withBacklog && (
|
|
<details className="agile-past">
|
|
<summary>{`Бэклог (${backlog.length})`}</summary>
|
|
<ul className="agile-list">{backlog.map((i) => <AgileIssueRow key={i.key} issue={i} />)}</ul>
|
|
</details>
|
|
)}
|
|
<BoardColumns columns={views} lastCaption="за 14 дней" hidden={view.hiddenColumns} />
|
|
</>
|
|
);
|
|
}}
|
|
</AgileGate>
|
|
</div>
|
|
);
|
|
}
|