Sync acceptance criteria toggle state to children
linter / quality (pull_request) Successful in 1m16s
tests / ci (8.4) (pull_request) Failing after 1m38s

This commit is contained in:
2026-05-20 13:34:28 +00:00
parent 4fb25ccecd
commit 2bc7745e53
4 changed files with 201 additions and 11 deletions
@@ -35,14 +35,15 @@ class AcceptanceCriteriaChecklistMapper
public static function normalize(mixed $value): array
{
if (is_array($value)) {
return self::normalizeFromArray($value);
return self::syncDescendantCheckedState(
self::normalizeFromArray($value),
);
}
return [];
}
/**
* @param Ticket $ticket
* @param array<int, array{id?: int, checked: bool, indent: int, text: string}> $items
*/
public static function syncTicket(Ticket $ticket, array $items): void
@@ -167,6 +168,28 @@ class AcceptanceCriteriaChecklistMapper
return max(0, min(self::MAX_INDENT_LEVEL, $indent));
}
/**
* @param array<int, array{id?: int, checked: bool, indent: int, text: string}> $items
* @return array<int, array{id?: int, checked: bool, indent: int, text: string}>
*/
private static function syncDescendantCheckedState(array $items): array
{
$checkedStateByIndent = [];
foreach ($items as $index => $item) {
$indent = $item['indent'];
if ($indent > 0 && array_key_exists($indent - 1, $checkedStateByIndent)) {
$items[$index]['checked'] = $checkedStateByIndent[$indent - 1];
}
$checkedStateByIndent[$indent] = $items[$index]['checked'];
$checkedStateByIndent = array_slice($checkedStateByIndent, 0, $indent + 1, true);
}
return $items;
}
/**
* @param iterable<AcceptanceCriterion> $criteria
* @return array<int, array{id?: int, checked: bool, indent: int, text: string}>