Merge pull request 'KAN-7 Made Templates Overwritable' (#89) from koda/kan-7-made-templates-overwritable into epic/kan-3
Reviewed-on: OpenSource/KanbanGit#89 Reviewed-by: Eric <eric-peters6@gmx.de>
This commit was merged in pull request #89.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Actions\Notifications;
|
||||
|
||||
use App\Actions\Projects\DuplicateProjectConfiguration;
|
||||
use App\Actions\Projects\ResolveProjectTemplateState;
|
||||
use App\Enums\DiscordAllowedMentionType;
|
||||
use App\Enums\NotificationChannel;
|
||||
use App\Enums\NotificationEventType;
|
||||
@@ -15,6 +17,7 @@ class BuildProjectNotificationSettingsPayload
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ListProjectNotificationActions $listProjectNotificationActions,
|
||||
private readonly ResolveProjectTemplateState $resolveProjectTemplateState,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -33,6 +36,9 @@ class BuildProjectNotificationSettingsPayload
|
||||
)->resolve(),
|
||||
'project' => ProjectResource::make($project)->resolve(),
|
||||
'status' => $status,
|
||||
'templateState' => $this->resolveProjectTemplateState->handle($project, [
|
||||
DuplicateProjectConfiguration::COPY_NOTIFICATION_ACTIONS,
|
||||
]),
|
||||
'templateVariables' => $this->templateVariables(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ use App\Models\Project;
|
||||
|
||||
class BuildProjectBoardSettingsPayload
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ResolveProjectTemplateState $resolveProjectTemplateState,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
@@ -27,6 +31,9 @@ class BuildProjectBoardSettingsPayload
|
||||
)->resolve(),
|
||||
'project' => ProjectResource::make($project)->resolve(),
|
||||
'status' => $status,
|
||||
'templateState' => $this->resolveProjectTemplateState->handle($project, [
|
||||
DuplicateProjectConfiguration::COPY_BOARD_WORKFLOW,
|
||||
]),
|
||||
'ticketStatuses' => TicketStatusResource::collection(
|
||||
$project->ticketStatuses()
|
||||
->with(['allowedTargetStatuses.boardColumn', 'boardColumn'])
|
||||
|
||||
@@ -13,6 +13,10 @@ use App\Models\TicketFieldDefinition;
|
||||
|
||||
class BuildProjectTicketMetadataSettingsPayload
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ResolveProjectTemplateState $resolveProjectTemplateState,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
@@ -23,6 +27,13 @@ class BuildProjectTicketMetadataSettingsPayload
|
||||
'project' => ProjectResource::make($project)->resolve(),
|
||||
'error' => $error,
|
||||
'status' => $status,
|
||||
'templateState' => $this->resolveProjectTemplateState->handle($project, [
|
||||
DuplicateProjectConfiguration::COPY_PROJECT_SETTINGS,
|
||||
DuplicateProjectConfiguration::COPY_TICKET_TYPES,
|
||||
DuplicateProjectConfiguration::COPY_TICKET_PRIORITIES,
|
||||
DuplicateProjectConfiguration::COPY_TICKET_FIELDS,
|
||||
DuplicateProjectConfiguration::COPY_TICKET_LINK_TYPES,
|
||||
]),
|
||||
'ticketFieldDefinitions' => TicketFieldDefinitionResource::collection($project->ticketFieldDefinitions()->get())->resolve(),
|
||||
'ticketLinkTypes' => TicketLinkTypeResource::collection($project->ticketLinkTypes()->get())->resolve(),
|
||||
'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(),
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Projects;
|
||||
|
||||
use App\Models\Project;
|
||||
use App\Models\ProjectTemplate;
|
||||
|
||||
class ResolveProjectTemplateState
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DuplicateProjectConfiguration $duplicateProjectConfiguration,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param list<string>|null $areas
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public function handle(Project $project, ?array $areas = null): ?array
|
||||
{
|
||||
$project->loadMissing('projectTemplate');
|
||||
|
||||
/** @var ProjectTemplate|null $projectTemplate */
|
||||
$projectTemplate = $project->projectTemplate;
|
||||
|
||||
if ($projectTemplate === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$selectedAreas = $areas === null
|
||||
? DuplicateProjectConfiguration::copyableAreas()
|
||||
: $this->duplicateProjectConfiguration->normalizeCopyAreas($areas);
|
||||
|
||||
$templateConfiguration = collect($projectTemplate->configuration_snapshot ?? [])
|
||||
->only($selectedAreas)
|
||||
->all();
|
||||
$currentConfiguration = $this->duplicateProjectConfiguration->export($project, $selectedAreas);
|
||||
|
||||
$overriddenAreas = [];
|
||||
$inheritedAreas = [];
|
||||
|
||||
foreach ($selectedAreas as $area) {
|
||||
$label = $this->labelForArea($area);
|
||||
$hasTemplateValue = array_key_exists($area, $templateConfiguration);
|
||||
$hasCurrentValue = array_key_exists($area, $currentConfiguration);
|
||||
|
||||
if (! $hasTemplateValue && ! $hasCurrentValue) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($hasTemplateValue && $hasCurrentValue && $currentConfiguration[$area] === $templateConfiguration[$area]) {
|
||||
$inheritedAreas[] = [
|
||||
'label' => $label,
|
||||
'value' => $area,
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$overriddenAreas[] = [
|
||||
'label' => $label,
|
||||
'value' => $area,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'effectiveConfiguration' => array_replace($templateConfiguration, array_intersect_key($currentConfiguration, array_flip(array_column($overriddenAreas, 'value')))),
|
||||
'inheritedAreas' => $inheritedAreas,
|
||||
'inheritsFromTemplate' => true,
|
||||
'overriddenAreas' => $overriddenAreas,
|
||||
'templateId' => $projectTemplate->id,
|
||||
'templateName' => $projectTemplate->name,
|
||||
'templateSlug' => $projectTemplate->slug,
|
||||
];
|
||||
}
|
||||
|
||||
private function labelForArea(string $area): string
|
||||
{
|
||||
foreach (DuplicateProjectConfiguration::copyAreaOptions() as $option) {
|
||||
if ($option['value'] === $area) {
|
||||
return $option['label'];
|
||||
}
|
||||
}
|
||||
|
||||
return $area;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ namespace App\Actions\Repositories;
|
||||
|
||||
use App\Actions\Git\Data\GitRepository;
|
||||
use App\Actions\Git\GitProviderManager;
|
||||
use App\Actions\Projects\DuplicateProjectConfiguration;
|
||||
use App\Actions\Projects\ResolveProjectTemplateState;
|
||||
use App\Http\Resources\AvailableGitRepositorySourceResource;
|
||||
use App\Http\Resources\ProjectResource;
|
||||
use App\Http\Resources\RepositoryConnectionResource;
|
||||
@@ -18,6 +20,7 @@ class BuildProjectRepositorySettingsPayload
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GitProviderManager $gitProviderManager,
|
||||
private readonly ResolveProjectTemplateState $resolveProjectTemplateState,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -41,6 +44,9 @@ class BuildProjectRepositorySettingsPayload
|
||||
'project' => ProjectResource::make($project)->resolve(),
|
||||
'repositoryConnections' => RepositoryConnectionResource::collection($repositoryConnections)->resolve(),
|
||||
'status' => $status,
|
||||
'templateState' => $this->resolveProjectTemplateState->handle($project, [
|
||||
DuplicateProjectConfiguration::COPY_REPOSITORY_CONNECTIONS,
|
||||
]),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user