*/ public static function relations(): array { return [ 'board_columns' => 'boardColumns', 'ticket_statuses' => 'ticketStatuses', 'ticket_types' => 'ticketTypes', 'ticket_priorities' => 'ticketPriorities', 'ticket_fields' => 'ticketFieldDefinitions', 'ticket_link_types' => 'ticketLinkTypes', 'repository_connections' => 'repositoryConnections', 'notification_actions' => 'notificationActions', ]; } /** @param array $configuration @return array */ public function normalize(array $configuration): array { foreach (self::relations() as $area => $relation) { if (! array_key_exists($area, $configuration)) { continue; } foreach ($configuration[$area] as $index => &$item) { $item['configuration_key'] ??= (string) Uuid::uuid5( Uuid::NAMESPACE_URL, 'kanbangit:'.$area.':'.$index.':'.$this->signature($area, $item), ); } unset($item); } $columns = array_column($configuration['board_columns'] ?? [], 'configuration_key'); foreach ($configuration['ticket_statuses'] ?? [] as $index => $status) { if (! array_key_exists('board_column_key', $status)) { $columnIndex = $status['board_column_index'] ?? null; $status['board_column_key'] = $columnIndex === null ? null : ($columns[$columnIndex] ?? null); } unset($status['board_column_index']); $configuration['ticket_statuses'][$index] = $status; } $statuses = array_column($configuration['ticket_statuses'] ?? [], 'configuration_key'); foreach ($configuration['status_transitions'] ?? [] as $index => $transition) { if (array_key_exists('status_key', $transition)) { continue; } if (! isset($statuses[$index])) { continue; } $configuration['status_transitions'][$index] = [ 'status_key' => $statuses[$index], 'target_keys' => array_values(array_filter(array_map( static fn (int $target): ?string => $statuses[$target] ?? null, $transition, ))), ]; } return $configuration; } /** @param array $item */ public function signature(string $area, array $item): string { return $area === 'repository_connections' ? ($item['provider'] ?? '').':'.($item['base_url'] ?? '').':'.($item['repository_full_name'] ?? '') : (string) ($item['name'] ?? $item['label'] ?? ''); } /** @return array */ public function defaults(): array { $configuration = array_fill_keys(DuplicateProjectConfiguration::copyableAreas(), []); $configuration['project_settings'] = ['show_author' => true, 'show_story_points' => true]; $configuration['ticket_statuses'] = [[ 'configuration_key' => (string) Str::uuid(), 'name' => 'Backlog', 'position' => 1, 'board_column_key' => null, ]]; $configuration['ticket_types'] = [ ['configuration_key' => (string) Str::uuid(), 'name' => 'Task', 'position' => 1, 'is_parent' => false], ['configuration_key' => (string) Str::uuid(), 'name' => 'Release', 'position' => 2, 'is_parent' => true], ]; $configuration['ticket_priorities'] = [[ 'configuration_key' => (string) Str::uuid(), 'name' => 'Medium', 'position' => 1, ]]; $configuration['status_transitions'] = [[ 'status_key' => $configuration['ticket_statuses'][0]['configuration_key'], 'target_keys' => [], ]]; return $configuration; } }