sdlc-hub/web/src/modules/jira/agile/EpicsPanel.tsx

50 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.

// панель «Эпики» бэклога и её узкий вариант — выбор «Эпик» (spec web-app); оба только меняют фильтр, Jira не трогают
import { Select } from "../../../ui/index.ts";
import { NONE, type EpicEntry } from "./filters.ts";
interface Props { entries: EpicEntry[]; value: string; onChange(v: string): void; hideDone: boolean }
// выполненные скрываются при «Скрыть выполненные», кроме выбранного; выбранный, которого нет в данных, остаётся пунктом по ключу
function listed({ entries, value, hideDone }: Pick<Props, "entries" | "value" | "hideDone">): EpicEntry[] {
const list = entries.filter((e) => !(hideDone && e.done && e.key !== value));
if (value && value !== NONE && !entries.some((e) => e.key === value)) list.push({ key: value, title: value, count: 0, done: false });
return list;
}
export function EpicsPanel(props: Props) {
const { value, onChange } = props;
const item = (v: string, title: string, key?: string, count?: number) => (
<li key={v}>
<button type="button" className="agile-epics__item" aria-pressed={value === v} onClick={() => onChange(value === v ? "" : v)}>
<span className="agile-epics__title">{title}</span>
{key && key !== title && <span className="agile-epics__key">{key}</span>}
{count !== undefined && <span className="agile-epics__count">{count}</span>}
</button>
</li>
);
return (
<aside className="agile-epics" aria-label="Эпики">
<ul className="agile-epics__list">
<li>
<button type="button" className="agile-epics__item" aria-pressed={value === ""} onClick={() => onChange("")}>
<span className="agile-epics__title">Все задачи</span>
</button>
</li>
{listed(props).map((e) => item(e.key, e.title, e.key, e.count))}
{item(NONE, "Без эпика")}
</ul>
</aside>
);
}
// forced — панель «Эпики» скрыта, а выбранный эпик должен оставаться виден и снимаем (M-3)
export function EpicSelect(props: Props & { forced?: boolean }) {
return (
<Select aria-label="Эпик" className={`agile-epic-select${props.forced ? " is-forced" : ""}`} value={props.value} onChange={(e) => props.onChange(e.target.value)}>
<option value="">Все задачи</option>
{listed(props).map((e) => <option key={e.key} value={e.key}>{e.title}</option>)}
<option value={NONE}>Без эпика</option>
</Select>
);
}