/** * Arbeitspakete eines Sprints (work_cycle) filtern. * @param {Array<{ id: string, work_cycle_id?: string, status?: string }>} actions * @param {string | null | undefined} cycleId * @param {{ hideDone?: boolean }} options */ export function filterActionsForWorkCycle(actions, cycleId, { hideDone = true } = {}) { if (!cycleId) return [] let list = Array.isArray(actions) ? actions : [] if (hideDone) { list = list.filter((a) => a.status !== 'done' && a.status !== 'discarded') } return list.filter((a) => a.work_cycle_id === cycleId) } /** * @param {Array<{ work_cycle_id?: string, status?: string }>} actions */ export function countActionsByWorkCycle(actions, { hideDone = true } = {}) { const counts = {} for (const action of actions || []) { if (!action.work_cycle_id) continue if (hideDone && (action.status === 'done' || action.status === 'discarded')) continue counts[action.work_cycle_id] = (counts[action.work_cycle_id] || 0) + 1 } return counts } export const PLANNING_SPRINT_STATUSES = new Set(['planned', 'active', 'at_risk']) /** * @param {Array<{ id: string, status?: string }>} workCycles * @param {string | undefined} excludeCycleId */ export function listCarryoverTargetSprints(workCycles, excludeCycleId) { return (workCycles || []).filter( (cycle) => cycle.id !== excludeCycleId && PLANNING_SPRINT_STATUSES.has(cycle.status), ) } /** * @param {Array<{ id: string, work_cycle_id?: string, status?: string }>} actions * @param {string | undefined} cycleId */ export function listOpenActionsForWorkCycle(actions, cycleId) { return filterActionsForWorkCycle(actions, cycleId, { hideDone: true }) }