96 lines
3.9 KiB
PHP
96 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Projects;
|
|
|
|
use Illuminate\Support\Str;
|
|
use Ramsey\Uuid\Uuid;
|
|
|
|
class ProjectConfigurationIdentity
|
|
{
|
|
/** @return array<string, string> */
|
|
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<string, mixed> $configuration @return array<string, mixed> */
|
|
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<string, mixed> $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<string, mixed> */
|
|
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;
|
|
}
|
|
}
|