Merge pull request 'codex/resource-based-responses' (#33) from codex/resource-based-responses into main
Reviewed-on: OpenSource/KanbanGit#33 Reviewed-by: Koda <koda@twyco.de>
This commit was merged in pull request #33.
This commit is contained in:
@@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Actions\Projects;
|
|
||||||
|
|
||||||
use App\Models\Project;
|
|
||||||
use App\Models\Ticket;
|
|
||||||
use App\Models\User;
|
|
||||||
|
|
||||||
class BuildProjectBacklogPageProps
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*/
|
|
||||||
public function handle(
|
|
||||||
Project $project,
|
|
||||||
bool $canEditTickets,
|
|
||||||
bool $canCreateTickets,
|
|
||||||
?string $status,
|
|
||||||
): array {
|
|
||||||
return [
|
|
||||||
'backlogTicketStatuses' => $project->ticketStatuses()
|
|
||||||
->whereNull('board_column_id')
|
|
||||||
->get(),
|
|
||||||
'canCreateTickets' => $canCreateTickets,
|
|
||||||
'canEditTickets' => $canEditTickets,
|
|
||||||
'project' => $project,
|
|
||||||
'status' => $status,
|
|
||||||
'ticketStatusOptions' => $project->ticketStatuses()
|
|
||||||
->with('boardColumn')
|
|
||||||
->get(),
|
|
||||||
'ticketPriorities' => $project->ticketPriorities()->get(),
|
|
||||||
'ticketTypes' => $project->ticketTypes()->get(),
|
|
||||||
'tickets' => Ticket::query()
|
|
||||||
->with([
|
|
||||||
'ticketPriority',
|
|
||||||
'ticketStatus.allowedTargetStatuses.boardColumn',
|
|
||||||
'ticketStatus.boardColumn',
|
|
||||||
'ticketType',
|
|
||||||
])
|
|
||||||
->where('project_id', $project->id)
|
|
||||||
->whereHas('ticketStatus', fn ($query) => $query->whereNull('board_column_id'))
|
|
||||||
->orderByDesc('sequence_number')
|
|
||||||
->get(),
|
|
||||||
'users' => User::query()
|
|
||||||
->orderBy('name')
|
|
||||||
->get(),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Actions\Projects;
|
|
||||||
|
|
||||||
use App\Models\Project;
|
|
||||||
|
|
||||||
class BuildProjectBoardPageProps
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*/
|
|
||||||
public function handle(
|
|
||||||
Project $project,
|
|
||||||
bool $canEditTickets,
|
|
||||||
bool $canCreateTickets,
|
|
||||||
?string $status,
|
|
||||||
): array {
|
|
||||||
return [
|
|
||||||
'boardColumns' => $project->boardColumns()
|
|
||||||
->with([
|
|
||||||
'ticketStatuses',
|
|
||||||
'tickets' => fn ($query) => $query
|
|
||||||
->with([
|
|
||||||
'ticketPriority',
|
|
||||||
'ticketStatus.allowedTargetStatuses.boardColumn',
|
|
||||||
'ticketStatus.boardColumn',
|
|
||||||
'ticketType',
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
->get(),
|
|
||||||
'canCreateTickets' => $canCreateTickets,
|
|
||||||
'canEditTickets' => $canEditTickets,
|
|
||||||
'project' => $project,
|
|
||||||
'status' => $status,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Actions\Tickets;
|
|
||||||
|
|
||||||
use App\Models\Ticket;
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
|
|
||||||
class BuildProjectTicketUpdateAttributes
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param array<string, mixed> $validated
|
|
||||||
* @return array{
|
|
||||||
* acceptance_criteria: string|null,
|
|
||||||
* assignee_user_id: int|null,
|
|
||||||
* author_user_id: int|null,
|
|
||||||
* blocked_comment: string|null,
|
|
||||||
* description: string|null,
|
|
||||||
* is_blocked: bool,
|
|
||||||
* parent_ticket_id: int|null,
|
|
||||||
* story_points: int|null,
|
|
||||||
* ticket_priority_id: int,
|
|
||||||
* ticket_type_id: int,
|
|
||||||
* title: string
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
public function handle(Ticket $ticket, array $validated): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'acceptance_criteria' => Arr::get($validated, 'acceptance_criteria'),
|
|
||||||
'assignee_user_id' => Arr::exists($validated, 'assignee_user_id')
|
|
||||||
? Arr::get($validated, 'assignee_user_id')
|
|
||||||
: $ticket->assignee_user_id,
|
|
||||||
'author_user_id' => Arr::exists($validated, 'author_user_id')
|
|
||||||
? Arr::get($validated, 'author_user_id')
|
|
||||||
: $ticket->author_user_id,
|
|
||||||
'blocked_comment' => Arr::get($validated, 'blocked_comment'),
|
|
||||||
'description' => Arr::get($validated, 'description'),
|
|
||||||
'is_blocked' => Arr::get($validated, 'is_blocked', false),
|
|
||||||
'parent_ticket_id' => Arr::get($validated, 'parent_ticket_id'),
|
|
||||||
'story_points' => Arr::exists($validated, 'story_points')
|
|
||||||
? Arr::get($validated, 'story_points')
|
|
||||||
: $ticket->story_points,
|
|
||||||
'ticket_priority_id' => Arr::get($validated, 'ticket_priority_id'),
|
|
||||||
'ticket_type_id' => Arr::get($validated, 'ticket_type_id'),
|
|
||||||
'title' => Arr::get($validated, 'title'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@ use App\Models\Ticket;
|
|||||||
use App\Models\TicketFieldDefinition;
|
use App\Models\TicketFieldDefinition;
|
||||||
use App\Models\TicketFieldValue;
|
use App\Models\TicketFieldValue;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
@@ -20,29 +21,31 @@ class UpdateProjectTicket
|
|||||||
/**
|
/**
|
||||||
* @param array{
|
* @param array{
|
||||||
* acceptance_criteria: string|null,
|
* acceptance_criteria: string|null,
|
||||||
* assignee_user_id: int|null,
|
* assignee_user_id?: int|null,
|
||||||
* author_user_id: int|null,
|
* author_user_id?: int|null,
|
||||||
* blocked_comment: string|null,
|
* blocked_comment: string|null,
|
||||||
* description: string|null,
|
* description: string|null,
|
||||||
|
* field_values?: array<int, array{
|
||||||
|
* ticket_field_definition_id: int,
|
||||||
|
* value_number?: float|int|string|null,
|
||||||
|
* value_user_id?: int|string|null
|
||||||
|
* }>,
|
||||||
* is_blocked: bool,
|
* is_blocked: bool,
|
||||||
* story_points: int|null,
|
* story_points?: int|null,
|
||||||
* ticket_priority_id: int,
|
* ticket_priority_id: int,
|
||||||
* ticket_type_id: int,
|
* ticket_type_id: int,
|
||||||
* parent_ticket_id: int|null,
|
* parent_ticket_id: int|null,
|
||||||
* title: string
|
* title: string
|
||||||
* } $ticketAttributes
|
* } $validated
|
||||||
* @param array<int, array{
|
|
||||||
* ticket_field_definition_id: int,
|
|
||||||
* value_number?: float|int|string|null,
|
|
||||||
* value_user_id?: int|string|null
|
|
||||||
* }> $fieldValueAttributes
|
|
||||||
*/
|
*/
|
||||||
public function handle(
|
public function handle(
|
||||||
Ticket $ticket,
|
Ticket $ticket,
|
||||||
User $actor,
|
User $actor,
|
||||||
array $ticketAttributes,
|
array $validated,
|
||||||
array $fieldValueAttributes,
|
|
||||||
): bool {
|
): bool {
|
||||||
|
$fieldValueAttributes = Arr::get($validated, 'field_values', []);
|
||||||
|
$ticketAttributes = $this->buildTicketAttributes($ticket, $validated);
|
||||||
|
|
||||||
return DB::transaction(function () use ($actor, $fieldValueAttributes, $ticket, $ticketAttributes): bool {
|
return DB::transaction(function () use ($actor, $fieldValueAttributes, $ticket, $ticketAttributes): bool {
|
||||||
if (! $ticketAttributes['is_blocked']) {
|
if (! $ticketAttributes['is_blocked']) {
|
||||||
$ticketAttributes['blocked_comment'] = null;
|
$ticketAttributes['blocked_comment'] = null;
|
||||||
@@ -212,6 +215,57 @@ class UpdateProjectTicket
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array{
|
||||||
|
* acceptance_criteria: string|null,
|
||||||
|
* assignee_user_id?: int|null,
|
||||||
|
* author_user_id?: int|null,
|
||||||
|
* blocked_comment: string|null,
|
||||||
|
* description: string|null,
|
||||||
|
* is_blocked: bool,
|
||||||
|
* parent_ticket_id: int|null,
|
||||||
|
* story_points?: int|null,
|
||||||
|
* ticket_priority_id: int,
|
||||||
|
* ticket_type_id: int,
|
||||||
|
* title: string
|
||||||
|
* } $validated
|
||||||
|
* @return array{
|
||||||
|
* acceptance_criteria: string|null,
|
||||||
|
* assignee_user_id: int|null,
|
||||||
|
* author_user_id: int|null,
|
||||||
|
* blocked_comment: string|null,
|
||||||
|
* description: string|null,
|
||||||
|
* is_blocked: bool,
|
||||||
|
* parent_ticket_id: int|null,
|
||||||
|
* story_points: int|null,
|
||||||
|
* ticket_priority_id: int,
|
||||||
|
* ticket_type_id: int,
|
||||||
|
* title: string
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
private function buildTicketAttributes(Ticket $ticket, array $validated): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'acceptance_criteria' => Arr::get($validated, 'acceptance_criteria'),
|
||||||
|
'assignee_user_id' => Arr::exists($validated, 'assignee_user_id')
|
||||||
|
? Arr::get($validated, 'assignee_user_id')
|
||||||
|
: $ticket->assignee_user_id,
|
||||||
|
'author_user_id' => Arr::exists($validated, 'author_user_id')
|
||||||
|
? Arr::get($validated, 'author_user_id')
|
||||||
|
: $ticket->author_user_id,
|
||||||
|
'blocked_comment' => Arr::get($validated, 'blocked_comment'),
|
||||||
|
'description' => Arr::get($validated, 'description'),
|
||||||
|
'is_blocked' => Arr::get($validated, 'is_blocked', false),
|
||||||
|
'parent_ticket_id' => Arr::get($validated, 'parent_ticket_id'),
|
||||||
|
'story_points' => Arr::exists($validated, 'story_points')
|
||||||
|
? Arr::get($validated, 'story_points')
|
||||||
|
: $ticket->story_points,
|
||||||
|
'ticket_priority_id' => Arr::get($validated, 'ticket_priority_id'),
|
||||||
|
'ticket_type_id' => Arr::get($validated, 'ticket_type_id'),
|
||||||
|
'title' => Arr::get($validated, 'title'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed> $changes
|
* @param array<string, mixed> $changes
|
||||||
* @param array<int, string> $summaryLabels
|
* @param array<int, string> $summaryLabels
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ namespace App\Http\Controllers\Admin;
|
|||||||
use App\Actions\Permissions\PermissionService;
|
use App\Actions\Permissions\PermissionService;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Admin\SyncUserGlobalPermissionsRequest;
|
use App\Http\Requests\Admin\SyncUserGlobalPermissionsRequest;
|
||||||
|
use App\Http\Resources\PermissionOptionResource;
|
||||||
|
use App\Http\Resources\UserResource;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
@@ -21,11 +23,15 @@ class UserManagementController extends Controller
|
|||||||
{
|
{
|
||||||
return Inertia::render('admin/users/Index', [
|
return Inertia::render('admin/users/Index', [
|
||||||
'directPermissions' => $this->permissionService->assignmentMap(User::class),
|
'directPermissions' => $this->permissionService->assignmentMap(User::class),
|
||||||
'permissionOptions' => $this->permissionService->permissionOptions(User::class, null),
|
'permissionOptions' => PermissionOptionResource::collection(
|
||||||
|
$this->permissionService->permissionOptions(User::class, null),
|
||||||
|
)->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'users' => User::query()
|
'users' => UserResource::collection(
|
||||||
->orderBy('name')
|
User::query()
|
||||||
->get(),
|
->orderBy('name')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,12 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Actions\Permissions\PermissionService;
|
use App\Actions\Permissions\PermissionService;
|
||||||
use App\Actions\Projects\BuildProjectBoardPageProps;
|
|
||||||
use App\Actions\Tickets\CreateTicketWorklogEntry;
|
use App\Actions\Tickets\CreateTicketWorklogEntry;
|
||||||
use App\Enums\Permission;
|
use App\Enums\Permission;
|
||||||
use App\Enums\TicketWorklogEntryType;
|
use App\Enums\TicketWorklogEntryType;
|
||||||
use App\Http\Requests\MoveProjectTicketRequest;
|
use App\Http\Requests\MoveProjectTicketRequest;
|
||||||
|
use App\Http\Resources\BoardColumnResource;
|
||||||
|
use App\Http\Resources\ProjectResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Ticket;
|
use App\Models\Ticket;
|
||||||
use App\Models\TicketStatus;
|
use App\Models\TicketStatus;
|
||||||
@@ -20,7 +21,6 @@ use Inertia\Response;
|
|||||||
class ProjectBoardController extends Controller
|
class ProjectBoardController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly BuildProjectBoardPageProps $buildProjectBoardPageProps,
|
|
||||||
private readonly CreateTicketWorklogEntry $createTicketWorklogEntry,
|
private readonly CreateTicketWorklogEntry $createTicketWorklogEntry,
|
||||||
private readonly PermissionService $permissionService,
|
private readonly PermissionService $permissionService,
|
||||||
) {}
|
) {}
|
||||||
@@ -34,12 +34,28 @@ class ProjectBoardController extends Controller
|
|||||||
403,
|
403,
|
||||||
);
|
);
|
||||||
|
|
||||||
return Inertia::render('projects/Board', $this->buildProjectBoardPageProps->handle(
|
$canManageTickets = $this->permissionService->allows($user, Permission::ProjectWrite, $project);
|
||||||
$project,
|
|
||||||
$this->permissionService->allows($user, Permission::ProjectWrite, $project),
|
return Inertia::render('projects/Board', [
|
||||||
$this->permissionService->allows($user, Permission::ProjectWrite, $project),
|
'boardColumns' => BoardColumnResource::collection(
|
||||||
session('status'),
|
$project->boardColumns()
|
||||||
));
|
->with([
|
||||||
|
'ticketStatuses',
|
||||||
|
'tickets' => fn ($query) => $query
|
||||||
|
->with([
|
||||||
|
'ticketPriority',
|
||||||
|
'ticketStatus.allowedTargetStatuses.boardColumn',
|
||||||
|
'ticketStatus.boardColumn',
|
||||||
|
'ticketType',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'canCreateTickets' => $canManageTickets,
|
||||||
|
'canEditTickets' => $canManageTickets,
|
||||||
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
|
'status' => session('status'),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function move(
|
public function move(
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ use App\Http\Requests\StoreTicketStatusRequest;
|
|||||||
use App\Http\Requests\UpdateBoardColumnRequest;
|
use App\Http\Requests\UpdateBoardColumnRequest;
|
||||||
use App\Http\Requests\UpdateTicketStatusRequest;
|
use App\Http\Requests\UpdateTicketStatusRequest;
|
||||||
use App\Http\Requests\UpdateTicketStatusTransitionsRequest;
|
use App\Http\Requests\UpdateTicketStatusTransitionsRequest;
|
||||||
|
use App\Http\Resources\BoardColumnResource;
|
||||||
|
use App\Http\Resources\ProjectResource;
|
||||||
|
use App\Http\Resources\TicketStatusResource;
|
||||||
use App\Models\BoardColumn;
|
use App\Models\BoardColumn;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\TicketStatus;
|
use App\Models\TicketStatus;
|
||||||
@@ -35,17 +38,23 @@ class ProjectBoardSettingsController extends Controller
|
|||||||
);
|
);
|
||||||
|
|
||||||
return Inertia::render('projects/settings/Board', [
|
return Inertia::render('projects/settings/Board', [
|
||||||
'backlogTicketStatuses' => $project->ticketStatuses()
|
'backlogTicketStatuses' => TicketStatusResource::collection(
|
||||||
->whereNull('board_column_id')
|
$project->ticketStatuses()
|
||||||
->get(),
|
->whereNull('board_column_id')
|
||||||
'boardColumns' => $project->boardColumns()
|
->get(),
|
||||||
->with('ticketStatuses')
|
)->resolve(),
|
||||||
->get(),
|
'boardColumns' => BoardColumnResource::collection(
|
||||||
'project' => $project,
|
$project->boardColumns()
|
||||||
|
->with('ticketStatuses')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'ticketStatuses' => $project->ticketStatuses()
|
'ticketStatuses' => TicketStatusResource::collection(
|
||||||
->with(['allowedTargetStatuses.boardColumn', 'boardColumn'])
|
$project->ticketStatuses()
|
||||||
->get(),
|
->with(['allowedTargetStatuses.boardColumn', 'boardColumn'])
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,22 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Actions\Permissions\PermissionService;
|
use App\Actions\Permissions\PermissionService;
|
||||||
use App\Actions\Projects\BuildProjectBacklogPageProps;
|
|
||||||
use App\Actions\ProjectTicketMetadata\InitializeProjectTicketMetadata;
|
use App\Actions\ProjectTicketMetadata\InitializeProjectTicketMetadata;
|
||||||
use App\Enums\Permission;
|
use App\Enums\Permission;
|
||||||
use App\Http\Requests\DeleteProjectRequest;
|
use App\Http\Requests\DeleteProjectRequest;
|
||||||
use App\Http\Requests\StoreProjectRequest;
|
use App\Http\Requests\StoreProjectRequest;
|
||||||
use App\Http\Requests\SyncProjectPermissionsRequest;
|
use App\Http\Requests\SyncProjectPermissionsRequest;
|
||||||
|
use App\Http\Resources\PermissionOptionResource;
|
||||||
|
use App\Http\Resources\ProjectResource;
|
||||||
|
use App\Http\Resources\TeamResource;
|
||||||
|
use App\Http\Resources\TicketPriorityResource;
|
||||||
|
use App\Http\Resources\TicketResource;
|
||||||
|
use App\Http\Resources\TicketStatusResource;
|
||||||
|
use App\Http\Resources\TicketTypeResource;
|
||||||
|
use App\Http\Resources\UserResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
|
use App\Models\Ticket;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -21,7 +29,6 @@ use Inertia\Response;
|
|||||||
class ProjectController extends Controller
|
class ProjectController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly BuildProjectBacklogPageProps $buildProjectBacklogPageProps,
|
|
||||||
private readonly InitializeProjectTicketMetadata $initializeProjectTicketMetadata,
|
private readonly InitializeProjectTicketMetadata $initializeProjectTicketMetadata,
|
||||||
private readonly PermissionService $permissionService,
|
private readonly PermissionService $permissionService,
|
||||||
) {}
|
) {}
|
||||||
@@ -38,7 +45,7 @@ class ProjectController extends Controller
|
|||||||
|
|
||||||
if ($viewableProjectIds === []) {
|
if ($viewableProjectIds === []) {
|
||||||
return Inertia::render('projects/Index', [
|
return Inertia::render('projects/Index', [
|
||||||
'projects' => [],
|
'projects' => ProjectResource::collection(collect())->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -47,8 +54,7 @@ class ProjectController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Inertia::render('projects/Index', [
|
return Inertia::render('projects/Index', [
|
||||||
'projects' => $projectQuery
|
'projects' => ProjectResource::collection($projectQuery->get())->resolve(),
|
||||||
->get(),
|
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -83,7 +89,7 @@ class ProjectController extends Controller
|
|||||||
|
|
||||||
return Inertia::render('projects/Show', [
|
return Inertia::render('projects/Show', [
|
||||||
'canManageAccess' => $this->permissionService->allows($user, Permission::ProjectAdmin, $project),
|
'canManageAccess' => $this->permissionService->allows($user, Permission::ProjectAdmin, $project),
|
||||||
'project' => $project,
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,18 +102,50 @@ class ProjectController extends Controller
|
|||||||
403,
|
403,
|
||||||
);
|
);
|
||||||
|
|
||||||
return Inertia::render('projects/Backlog', $this->buildProjectBacklogPageProps->handle(
|
$canManageTickets = $this->permissionService->allows($user, Permission::ProjectWrite, $project);
|
||||||
$project,
|
|
||||||
$this->permissionService->allows($user, Permission::ProjectWrite, $project),
|
return Inertia::render('projects/Backlog', [
|
||||||
$this->permissionService->allows($user, Permission::ProjectWrite, $project),
|
'backlogTicketStatuses' => TicketStatusResource::collection(
|
||||||
session('status'),
|
$project->ticketStatuses()
|
||||||
));
|
->whereNull('board_column_id')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'canCreateTickets' => $canManageTickets,
|
||||||
|
'canEditTickets' => $canManageTickets,
|
||||||
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
|
'status' => session('status'),
|
||||||
|
'ticketStatusOptions' => TicketStatusResource::collection(
|
||||||
|
$project->ticketStatuses()
|
||||||
|
->with('boardColumn')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(),
|
||||||
|
'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->get())->resolve(),
|
||||||
|
'tickets' => TicketResource::collection(
|
||||||
|
Ticket::query()
|
||||||
|
->with([
|
||||||
|
'ticketPriority',
|
||||||
|
'ticketStatus.allowedTargetStatuses.boardColumn',
|
||||||
|
'ticketStatus.boardColumn',
|
||||||
|
'ticketType',
|
||||||
|
])
|
||||||
|
->where('project_id', $project->id)
|
||||||
|
->whereHas('ticketStatus', fn ($query) => $query->whereNull('board_column_id'))
|
||||||
|
->orderByDesc('sequence_number')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'users' => UserResource::collection(
|
||||||
|
User::query()
|
||||||
|
->orderBy('name')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function general(Request $request, Project $project): Response
|
public function general(Request $request, Project $project): Response
|
||||||
{
|
{
|
||||||
return Inertia::render('projects/settings/General', [
|
return Inertia::render('projects/settings/General', [
|
||||||
'project' => $project,
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -122,25 +160,23 @@ class ProjectController extends Controller
|
|||||||
|
|
||||||
return Inertia::render('projects/Access', [
|
return Inertia::render('projects/Access', [
|
||||||
'directPermissions' => $this->permissionService->assignmentMap(User::class, $project),
|
'directPermissions' => $this->permissionService->assignmentMap(User::class, $project),
|
||||||
'permissionOptions' => $this->permissionService->permissionOptions(User::class, Project::class),
|
'permissionOptions' => PermissionOptionResource::collection(
|
||||||
'project' => $project,
|
$this->permissionService->permissionOptions(User::class, Project::class),
|
||||||
|
)->resolve(),
|
||||||
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'teamPermissions' => $this->permissionService->assignmentMap(Team::class, $project),
|
'teamPermissions' => $this->permissionService->assignmentMap(Team::class, $project),
|
||||||
'teams' => Team::query()
|
'teams' => TeamResource::collection(
|
||||||
->with('users')
|
Team::query()
|
||||||
->orderBy('name')
|
->with('users')
|
||||||
->get()
|
->orderBy('name')
|
||||||
->map(fn (Team $team): array => [
|
->get(),
|
||||||
'id' => $team->id,
|
)->resolve(),
|
||||||
'name' => $team->name,
|
'users' => UserResource::collection(
|
||||||
'created_at' => $team->created_at?->toISOString(),
|
User::query()
|
||||||
'updated_at' => $team->updated_at?->toISOString(),
|
->orderBy('name')
|
||||||
'user_ids' => $team->users->modelKeys(),
|
->get(),
|
||||||
'users' => $team->users->values(),
|
)->resolve(),
|
||||||
]),
|
|
||||||
'users' => User::query()
|
|
||||||
->orderBy('name')
|
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ use App\Actions\Permissions\PermissionService;
|
|||||||
use App\Enums\Permission;
|
use App\Enums\Permission;
|
||||||
use App\Http\Requests\StoreRepositoryConnectionRequest;
|
use App\Http\Requests\StoreRepositoryConnectionRequest;
|
||||||
use App\Http\Requests\UpdateRepositoryConnectionRequest;
|
use App\Http\Requests\UpdateRepositoryConnectionRequest;
|
||||||
|
use App\Http\Resources\AvailableGitRepositorySourceResource;
|
||||||
|
use App\Http\Resources\ProjectResource;
|
||||||
|
use App\Http\Resources\RepositoryConnectionResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\RepositoryConnection;
|
use App\Models\RepositoryConnection;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@@ -36,27 +39,21 @@ class ProjectRepositorySettingsController extends Controller
|
|||||||
403,
|
403,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$repositoryConnections = $project->repositoryConnections()
|
||||||
|
->get()
|
||||||
|
->each(function (RepositoryConnection $repositoryConnection) use ($user): void {
|
||||||
|
$repositoryConnection->setAttribute(
|
||||||
|
'has_personal_access',
|
||||||
|
$this->hasPersonalAccess($user, $repositoryConnection),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return Inertia::render('projects/settings/Repositories', [
|
return Inertia::render('projects/settings/Repositories', [
|
||||||
'availableRepositorySources' => $this->availableRepositorySources($user),
|
'availableRepositorySources' => AvailableGitRepositorySourceResource::collection(
|
||||||
'project' => $project,
|
$this->availableRepositorySources($user),
|
||||||
'repositoryConnections' => $project->repositoryConnections()
|
)->resolve(),
|
||||||
->get()
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
->map(fn (RepositoryConnection $repositoryConnection): array => [
|
'repositoryConnections' => RepositoryConnectionResource::collection($repositoryConnections)->resolve(),
|
||||||
'base_url' => $repositoryConnection->base_url,
|
|
||||||
'created_at' => $repositoryConnection->created_at?->toISOString(),
|
|
||||||
'has_personal_access' => $this->hasPersonalAccess($user, $repositoryConnection),
|
|
||||||
'id' => $repositoryConnection->id,
|
|
||||||
'owner_name' => $repositoryConnection->owner_name,
|
|
||||||
'project_id' => $repositoryConnection->project_id,
|
|
||||||
'provider' => $repositoryConnection->provider->value,
|
|
||||||
'provider_label' => $repositoryConnection->provider->label(),
|
|
||||||
'provider_repository_id' => $repositoryConnection->provider_repository_id,
|
|
||||||
'repository_full_name' => $repositoryConnection->repository_full_name,
|
|
||||||
'repository_name' => $repositoryConnection->repository_name,
|
|
||||||
'repository_url' => $repositoryConnection->repository_url,
|
|
||||||
'updated_at' => $repositoryConnection->updated_at?->toISOString(),
|
|
||||||
])
|
|
||||||
->values(),
|
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,24 @@ use App\Actions\Git\BuildSuggestedTicketBranchName;
|
|||||||
use App\Actions\Git\ResolveTicketBranchMatches;
|
use App\Actions\Git\ResolveTicketBranchMatches;
|
||||||
use App\Actions\Git\ResolveTicketPullRequestMatches;
|
use App\Actions\Git\ResolveTicketPullRequestMatches;
|
||||||
use App\Actions\Permissions\PermissionService;
|
use App\Actions\Permissions\PermissionService;
|
||||||
use App\Actions\Tickets\BuildProjectTicketUpdateAttributes;
|
|
||||||
use App\Actions\Tickets\CreateProjectTicket;
|
use App\Actions\Tickets\CreateProjectTicket;
|
||||||
use App\Actions\Tickets\UpdateProjectTicket;
|
use App\Actions\Tickets\UpdateProjectTicket;
|
||||||
use App\Enums\Permission;
|
use App\Enums\Permission;
|
||||||
use App\Http\Requests\StoreProjectTicketRequest;
|
use App\Http\Requests\StoreProjectTicketRequest;
|
||||||
use App\Http\Requests\UpdateProjectTicketRequest;
|
use App\Http\Requests\UpdateProjectTicketRequest;
|
||||||
|
use App\Http\Resources\ProjectResource;
|
||||||
|
use App\Http\Resources\TicketFieldDefinitionResource;
|
||||||
|
use App\Http\Resources\TicketLinkResource;
|
||||||
|
use App\Http\Resources\TicketLinkTypeResource;
|
||||||
|
use App\Http\Resources\TicketPriorityResource;
|
||||||
|
use App\Http\Resources\TicketReferenceResource;
|
||||||
|
use App\Http\Resources\TicketRepositoryBranchResource;
|
||||||
|
use App\Http\Resources\TicketRepositoryPullRequestResource;
|
||||||
|
use App\Http\Resources\TicketResource;
|
||||||
|
use App\Http\Resources\TicketStatusResource;
|
||||||
|
use App\Http\Resources\TicketTreeNodeResource;
|
||||||
|
use App\Http\Resources\TicketTypeResource;
|
||||||
|
use App\Http\Resources\UserResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Ticket;
|
use App\Models\Ticket;
|
||||||
use App\Models\TicketLink;
|
use App\Models\TicketLink;
|
||||||
@@ -25,7 +37,6 @@ use Inertia\Response;
|
|||||||
class ProjectTicketController extends Controller
|
class ProjectTicketController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly BuildProjectTicketUpdateAttributes $buildProjectTicketUpdateAttributes,
|
|
||||||
private readonly BuildSuggestedTicketBranchName $buildSuggestedTicketBranchName,
|
private readonly BuildSuggestedTicketBranchName $buildSuggestedTicketBranchName,
|
||||||
private readonly CreateProjectTicket $createProjectTicket,
|
private readonly CreateProjectTicket $createProjectTicket,
|
||||||
private readonly PermissionService $permissionService,
|
private readonly PermissionService $permissionService,
|
||||||
@@ -54,17 +65,21 @@ class ProjectTicketController extends Controller
|
|||||||
|
|
||||||
return Inertia::render('projects/TicketCreate', [
|
return Inertia::render('projects/TicketCreate', [
|
||||||
'defaultTicketStatusId' => $defaultTicketStatus?->id,
|
'defaultTicketStatusId' => $defaultTicketStatus?->id,
|
||||||
'project' => $project,
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
'source' => $source,
|
'source' => $source,
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'ticketPriorities' => $project->ticketPriorities()->get(),
|
'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(),
|
||||||
'ticketStatusOptions' => $project->ticketStatuses()
|
'ticketStatusOptions' => TicketStatusResource::collection(
|
||||||
->with('boardColumn')
|
$project->ticketStatuses()
|
||||||
->get(),
|
->with('boardColumn')
|
||||||
'ticketTypes' => $project->ticketTypes()->get(),
|
->get(),
|
||||||
'users' => User::query()
|
)->resolve(),
|
||||||
->orderBy('name')
|
'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->get())->resolve(),
|
||||||
->get(),
|
'users' => UserResource::collection(
|
||||||
|
User::query()
|
||||||
|
->orderBy('name')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,50 +133,65 @@ class ProjectTicketController extends Controller
|
|||||||
return Inertia::render('projects/Ticket', [
|
return Inertia::render('projects/Ticket', [
|
||||||
'canEditTicket' => $canEditTicket,
|
'canEditTicket' => $canEditTicket,
|
||||||
'canManageProject' => $canManageProject,
|
'canManageProject' => $canManageProject,
|
||||||
'childTicketTree' => $this->buildChildTicketTree($ticket),
|
'childTicketTree' => TicketTreeNodeResource::collection(
|
||||||
'linkedTickets' => $this->linkedTickets($ticket),
|
$ticket->childTickets()
|
||||||
'parentTicketOptions' => Ticket::query()
|
->with('ticketType')
|
||||||
->where('project_id', $project->id)
|
->get(),
|
||||||
->whereKeyNot($ticket->id)
|
)->resolve(),
|
||||||
->whereHas('ticketType', fn ($query) => $query->where('is_parent', true))
|
'linkedTickets' => TicketLinkResource::collection(
|
||||||
->orderByDesc('sequence_number')
|
TicketLink::query()
|
||||||
->get()
|
->with(['sourceTicket', 'targetTicket', 'ticketLinkType'])
|
||||||
->map(fn (Ticket $parentTicket): array => [
|
->where(function ($query) use ($ticket): void {
|
||||||
'id' => $parentTicket->id,
|
$query
|
||||||
'ticket_key' => $parentTicket->ticket_key,
|
->where('source_ticket_id', $ticket->id)
|
||||||
'title' => $parentTicket->title,
|
->orWhere('target_ticket_id', $ticket->id);
|
||||||
]),
|
})
|
||||||
'project' => $project,
|
->orderBy('id')
|
||||||
'repositoryBranches' => $this->resolveTicketBranchMatches->handle(
|
->get()
|
||||||
$user,
|
->each(fn (TicketLink $ticketLink) => $ticketLink->setAttribute('current_ticket_id', $ticket->id)),
|
||||||
$project,
|
)->resolve(),
|
||||||
$ticket,
|
'parentTicketOptions' => TicketReferenceResource::collection(
|
||||||
),
|
Ticket::query()
|
||||||
'repositoryPullRequests' => $this->resolveTicketPullRequestMatches->handle(
|
->where('project_id', $project->id)
|
||||||
$user,
|
->whereKeyNot($ticket->id)
|
||||||
$project,
|
->whereHas('ticketType', fn ($query) => $query->where('is_parent', true))
|
||||||
$ticket,
|
->orderByDesc('sequence_number')
|
||||||
),
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
|
'repositoryBranches' => TicketRepositoryBranchResource::collection(
|
||||||
|
$this->resolveTicketBranchMatches->handle(
|
||||||
|
$user,
|
||||||
|
$project,
|
||||||
|
$ticket,
|
||||||
|
),
|
||||||
|
)->resolve(),
|
||||||
|
'repositoryPullRequests' => TicketRepositoryPullRequestResource::collection(
|
||||||
|
$this->resolveTicketPullRequestMatches->handle(
|
||||||
|
$user,
|
||||||
|
$project,
|
||||||
|
$ticket,
|
||||||
|
),
|
||||||
|
)->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'suggestedBranchName' => $this->buildSuggestedTicketBranchName->handle($ticket),
|
'suggestedBranchName' => $this->buildSuggestedTicketBranchName->handle($ticket),
|
||||||
'ticket' => $displayTicket,
|
'ticket' => TicketResource::make($displayTicket)->resolve(),
|
||||||
'ticketFieldDefinitions' => $project->ticketFieldDefinitions()->get(),
|
'ticketFieldDefinitions' => TicketFieldDefinitionResource::collection($project->ticketFieldDefinitions()->get())->resolve(),
|
||||||
'ticketLinkOptions' => Ticket::query()
|
'ticketLinkOptions' => TicketReferenceResource::collection(
|
||||||
->where('project_id', $project->id)
|
Ticket::query()
|
||||||
->whereKeyNot($ticket->id)
|
->where('project_id', $project->id)
|
||||||
->orderByDesc('sequence_number')
|
->whereKeyNot($ticket->id)
|
||||||
->get()
|
->orderByDesc('sequence_number')
|
||||||
->map(fn (Ticket $linkedTicket): array => [
|
->get(),
|
||||||
'id' => $linkedTicket->id,
|
)->resolve(),
|
||||||
'ticket_key' => $linkedTicket->ticket_key,
|
'ticketLinkTypes' => TicketLinkTypeResource::collection($project->ticketLinkTypes()->get())->resolve(),
|
||||||
'title' => $linkedTicket->title,
|
'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(),
|
||||||
]),
|
'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->get())->resolve(),
|
||||||
'ticketLinkTypes' => $project->ticketLinkTypes()->get(),
|
'users' => UserResource::collection(
|
||||||
'ticketPriorities' => $project->ticketPriorities()->get(),
|
User::query()
|
||||||
'ticketTypes' => $project->ticketTypes()->get(),
|
->orderBy('name')
|
||||||
'users' => User::query()
|
->get(),
|
||||||
->orderBy('name')
|
)->resolve(),
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,14 +208,11 @@ class ProjectTicketController extends Controller
|
|||||||
);
|
);
|
||||||
|
|
||||||
$validated = $request->validated();
|
$validated = $request->validated();
|
||||||
$fieldValues = Arr::get($validated, 'field_values', []);
|
|
||||||
$ticketAttributes = $this->buildProjectTicketUpdateAttributes->handle($ticket, $validated);
|
|
||||||
|
|
||||||
$wasUpdated = $this->updateProjectTicket->handle(
|
$wasUpdated = $this->updateProjectTicket->handle(
|
||||||
$ticket,
|
$ticket,
|
||||||
$user,
|
$user,
|
||||||
$ticketAttributes,
|
$validated,
|
||||||
$fieldValues,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$statusMessage = $wasUpdated
|
$statusMessage = $wasUpdated
|
||||||
@@ -195,74 +222,4 @@ class ProjectTicketController extends Controller
|
|||||||
return to_route('projects.tickets.show', [$project, $ticket])
|
return to_route('projects.tickets.show', [$project, $ticket])
|
||||||
->with('status', $statusMessage);
|
->with('status', $statusMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<int, array{
|
|
||||||
* children: array<int, mixed>,
|
|
||||||
* id: int,
|
|
||||||
* ticket_key: string,
|
|
||||||
* ticket_type_name: string|null,
|
|
||||||
* title: string
|
|
||||||
* }>
|
|
||||||
*/
|
|
||||||
private function buildChildTicketTree(Ticket $ticket): array
|
|
||||||
{
|
|
||||||
return $ticket->childTickets()
|
|
||||||
->with('ticketType')
|
|
||||||
->get()
|
|
||||||
->map(fn (Ticket $childTicket): array => [
|
|
||||||
'children' => $this->buildChildTicketTree($childTicket),
|
|
||||||
'id' => $childTicket->id,
|
|
||||||
'ticket_key' => $childTicket->ticket_key,
|
|
||||||
'ticket_type_name' => $childTicket->ticketType?->name,
|
|
||||||
'title' => $childTicket->title,
|
|
||||||
])
|
|
||||||
->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<int, array{
|
|
||||||
* created_at: string|null,
|
|
||||||
* id: int,
|
|
||||||
* linked_ticket: array{id: int, ticket_key: string, title: string},
|
|
||||||
* source_ticket_id: int,
|
|
||||||
* target_ticket_id: int,
|
|
||||||
* ticket_link_type: mixed,
|
|
||||||
* ticket_link_type_id: int,
|
|
||||||
* updated_at: string|null
|
|
||||||
* }>
|
|
||||||
*/
|
|
||||||
private function linkedTickets(Ticket $ticket): array
|
|
||||||
{
|
|
||||||
return TicketLink::query()
|
|
||||||
->with(['sourceTicket', 'targetTicket', 'ticketLinkType'])
|
|
||||||
->where(function ($query) use ($ticket): void {
|
|
||||||
$query
|
|
||||||
->where('source_ticket_id', $ticket->id)
|
|
||||||
->orWhere('target_ticket_id', $ticket->id);
|
|
||||||
})
|
|
||||||
->orderBy('id')
|
|
||||||
->get()
|
|
||||||
->map(function (TicketLink $ticketLink) use ($ticket): array {
|
|
||||||
$linkedTicket = $ticketLink->source_ticket_id === $ticket->id
|
|
||||||
? $ticketLink->targetTicket
|
|
||||||
: $ticketLink->sourceTicket;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'created_at' => $ticketLink->created_at?->toISOString(),
|
|
||||||
'id' => $ticketLink->id,
|
|
||||||
'linked_ticket' => [
|
|
||||||
'id' => $linkedTicket->id,
|
|
||||||
'ticket_key' => $linkedTicket->ticket_key,
|
|
||||||
'title' => $linkedTicket->title,
|
|
||||||
],
|
|
||||||
'source_ticket_id' => $ticketLink->source_ticket_id,
|
|
||||||
'target_ticket_id' => $ticketLink->target_ticket_id,
|
|
||||||
'ticket_link_type' => $ticketLink->ticketLinkType,
|
|
||||||
'ticket_link_type_id' => $ticketLink->ticket_link_type_id,
|
|
||||||
'updated_at' => $ticketLink->updated_at?->toISOString(),
|
|
||||||
];
|
|
||||||
})
|
|
||||||
->all();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ use App\Http\Requests\UpdateProjectNamedSettingRequest;
|
|||||||
use App\Http\Requests\UpdateProjectTicketMetadataSettings;
|
use App\Http\Requests\UpdateProjectTicketMetadataSettings;
|
||||||
use App\Http\Requests\UpdateProjectTicketTypeRequest;
|
use App\Http\Requests\UpdateProjectTicketTypeRequest;
|
||||||
use App\Http\Requests\UpdateTicketFieldDefinitionRequest;
|
use App\Http\Requests\UpdateTicketFieldDefinitionRequest;
|
||||||
|
use App\Http\Resources\FieldTypeOptionResource;
|
||||||
|
use App\Http\Resources\ProjectResource;
|
||||||
|
use App\Http\Resources\TicketFieldDefinitionResource;
|
||||||
|
use App\Http\Resources\TicketLinkTypeResource;
|
||||||
|
use App\Http\Resources\TicketPriorityResource;
|
||||||
|
use App\Http\Resources\TicketTypeResource;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Ticket;
|
use App\Models\Ticket;
|
||||||
use App\Models\TicketFieldDefinition;
|
use App\Models\TicketFieldDefinition;
|
||||||
@@ -41,19 +47,14 @@ class ProjectTicketMetadataSettingsController extends Controller
|
|||||||
$this->abortUnlessCanManage($request, $project);
|
$this->abortUnlessCanManage($request, $project);
|
||||||
|
|
||||||
return Inertia::render('projects/settings/Metadata', [
|
return Inertia::render('projects/settings/Metadata', [
|
||||||
'fieldTypeOptions' => collect(TicketFieldDefinition::FIELD_TYPES)
|
'fieldTypeOptions' => FieldTypeOptionResource::collection(collect(TicketFieldDefinition::FIELD_TYPES))->resolve(),
|
||||||
->map(fn (string $fieldType): array => [
|
'project' => ProjectResource::make($project)->resolve(),
|
||||||
'label' => ucfirst($fieldType),
|
|
||||||
'value' => $fieldType,
|
|
||||||
])
|
|
||||||
->all(),
|
|
||||||
'project' => $project,
|
|
||||||
'error' => session('error'),
|
'error' => session('error'),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'ticketFieldDefinitions' => $project->ticketFieldDefinitions()->get(),
|
'ticketFieldDefinitions' => TicketFieldDefinitionResource::collection($project->ticketFieldDefinitions()->get())->resolve(),
|
||||||
'ticketLinkTypes' => $project->ticketLinkTypes()->get(),
|
'ticketLinkTypes' => TicketLinkTypeResource::collection($project->ticketLinkTypes()->get())->resolve(),
|
||||||
'ticketPriorities' => $project->ticketPriorities()->get(),
|
'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(),
|
||||||
'ticketTypes' => $project->ticketTypes()->withCount('tickets')->get(),
|
'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->withCount('tickets')->get())->resolve(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use App\Actions\Git\GitProviderManager;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Settings\StoreUserGitConnectionRequest;
|
use App\Http\Requests\Settings\StoreUserGitConnectionRequest;
|
||||||
use App\Http\Requests\Settings\UpdateUserGitConnectionRequest;
|
use App\Http\Requests\Settings\UpdateUserGitConnectionRequest;
|
||||||
|
use App\Http\Resources\UserGitConnectionResource;
|
||||||
use App\Models\UserGitConnection;
|
use App\Models\UserGitConnection;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -25,20 +26,7 @@ class GitConnectionController extends Controller
|
|||||||
{
|
{
|
||||||
|
|
||||||
return Inertia::render('settings/GitConnections', [
|
return Inertia::render('settings/GitConnections', [
|
||||||
'gitConnections' => $request->user()->gitConnections
|
'gitConnections' => UserGitConnectionResource::collection($request->user()->gitConnections)->resolve(),
|
||||||
->map(fn (UserGitConnection $gitConnection): array => [
|
|
||||||
'account_login' => $gitConnection->account_login,
|
|
||||||
'account_name' => $gitConnection->account_name,
|
|
||||||
'base_url' => $gitConnection->base_url,
|
|
||||||
'created_at' => $gitConnection->created_at?->toISOString(),
|
|
||||||
'id' => $gitConnection->id,
|
|
||||||
'provider' => $gitConnection->provider->value,
|
|
||||||
'provider_label' => $gitConnection->provider->label(),
|
|
||||||
'provider_user_id' => $gitConnection->provider_user_id,
|
|
||||||
'updated_at' => $gitConnection->updated_at?->toISOString(),
|
|
||||||
'user_id' => $gitConnection->user_id,
|
|
||||||
])
|
|
||||||
->values(),
|
|
||||||
'status' => $request->session()->get('status'),
|
'status' => $request->session()->get('status'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ use App\Enums\Permission;
|
|||||||
use App\Http\Requests\StoreTeamRequest;
|
use App\Http\Requests\StoreTeamRequest;
|
||||||
use App\Http\Requests\SyncTeamUserPermissionsRequest;
|
use App\Http\Requests\SyncTeamUserPermissionsRequest;
|
||||||
use App\Http\Requests\UpdateTeamMembersRequest;
|
use App\Http\Requests\UpdateTeamMembersRequest;
|
||||||
|
use App\Http\Resources\PermissionOptionResource;
|
||||||
|
use App\Http\Resources\TeamResource;
|
||||||
|
use App\Http\Resources\UserResource;
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
@@ -37,25 +40,21 @@ class TeamController extends Controller
|
|||||||
|
|
||||||
return Inertia::render('teams/Index', [
|
return Inertia::render('teams/Index', [
|
||||||
'canCreateTeams' => $canCreateTeams,
|
'canCreateTeams' => $canCreateTeams,
|
||||||
'permissionOptions' => $this->permissionService->permissionOptions(User::class, Team::class),
|
'permissionOptions' => PermissionOptionResource::collection(
|
||||||
|
$this->permissionService->permissionOptions(User::class, Team::class),
|
||||||
|
)->resolve(),
|
||||||
'status' => session('status'),
|
'status' => session('status'),
|
||||||
'teamPermissions' => $teams
|
'teamPermissions' => $teams
|
||||||
->mapWithKeys(fn (Team $team): array => [
|
->mapWithKeys(fn (Team $team): array => [
|
||||||
$team->id => $this->permissionService->assignmentMap(User::class, $team),
|
$team->id => $this->permissionService->assignmentMap(User::class, $team),
|
||||||
])
|
])
|
||||||
->all(),
|
->all(),
|
||||||
'teams' => $teams
|
'teams' => TeamResource::collection($teams)->resolve(),
|
||||||
->map(fn (Team $team): array => [
|
'users' => UserResource::collection(
|
||||||
'id' => $team->id,
|
User::query()
|
||||||
'name' => $team->name,
|
->orderBy('name')
|
||||||
'created_at' => $team->created_at?->toISOString(),
|
->get(),
|
||||||
'updated_at' => $team->updated_at?->toISOString(),
|
)->resolve(),
|
||||||
'user_ids' => $team->users->modelKeys(),
|
|
||||||
'users' => $team->users->values(),
|
|
||||||
]),
|
|
||||||
'users' => User::query()
|
|
||||||
->orderBy('name')
|
|
||||||
->get(),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class AvailableGitRepositorySourceResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'user_git_connection_id' => Arr::get($this->resource, 'user_git_connection_id'),
|
||||||
|
'provider' => Arr::get($this->resource, 'provider'),
|
||||||
|
'provider_label' => Arr::get($this->resource, 'provider_label'),
|
||||||
|
'base_url' => Arr::get($this->resource, 'base_url'),
|
||||||
|
'account_login' => Arr::get($this->resource, 'account_login'),
|
||||||
|
'account_name' => Arr::get($this->resource, 'account_name'),
|
||||||
|
'error' => Arr::get($this->resource, 'error'),
|
||||||
|
'repositories' => GitRepositoryOptionResource::collection(
|
||||||
|
collect(Arr::get($this->resource, 'repositories', [])),
|
||||||
|
)->resolve(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class BoardColumnResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'position' => $this->position,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'ticket_statuses' => $this->whenLoaded(
|
||||||
|
'ticketStatuses',
|
||||||
|
fn (): array => TicketStatusResource::collection($this->ticketStatuses)->resolve(),
|
||||||
|
),
|
||||||
|
'tickets' => $this->whenLoaded(
|
||||||
|
'tickets',
|
||||||
|
fn (): array => TicketResource::collection($this->tickets)->resolve(),
|
||||||
|
),
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class FieldTypeOptionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
$fieldType = is_string($this->resource)
|
||||||
|
? $this->resource
|
||||||
|
: Arr::get($this->resource, 'value');
|
||||||
|
|
||||||
|
return [
|
||||||
|
'label' => is_string($this->resource)
|
||||||
|
? ucfirst($fieldType)
|
||||||
|
: Arr::get($this->resource, 'label'),
|
||||||
|
'value' => $fieldType,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class GitRepositoryOptionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'provider_repository_id' => Arr::get($this->resource, 'provider_repository_id'),
|
||||||
|
'owner_name' => Arr::get($this->resource, 'owner_name'),
|
||||||
|
'repository_name' => Arr::get($this->resource, 'repository_name'),
|
||||||
|
'full_name' => Arr::get($this->resource, 'full_name'),
|
||||||
|
'repository_url' => Arr::get($this->resource, 'repository_url'),
|
||||||
|
'visibility_label' => Arr::get($this->resource, 'visibility_label'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class PermissionOptionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'label' => Arr::get($this->resource, 'label'),
|
||||||
|
'value' => Arr::get($this->resource, 'value'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class ProjectResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'key' => $this->key,
|
||||||
|
'show_author' => $this->show_author,
|
||||||
|
'show_story_points' => $this->show_story_points,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\RepositoryConnection;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class RepositoryConnectionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
$provider = $this->resource instanceof RepositoryConnection
|
||||||
|
? $this->provider
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $this->resource instanceof RepositoryConnection ? $this->id : Arr::get($this->resource, 'id'),
|
||||||
|
'project_id' => $this->resource instanceof RepositoryConnection ? $this->project_id : Arr::get($this->resource, 'project_id'),
|
||||||
|
'provider' => $provider?->value ?? Arr::get($this->resource, 'provider'),
|
||||||
|
'provider_label' => $provider?->label() ?? Arr::get($this->resource, 'provider_label'),
|
||||||
|
'base_url' => $this->resource instanceof RepositoryConnection ? $this->base_url : Arr::get($this->resource, 'base_url'),
|
||||||
|
'provider_repository_id' => $this->resource instanceof RepositoryConnection
|
||||||
|
? $this->provider_repository_id
|
||||||
|
: Arr::get($this->resource, 'provider_repository_id'),
|
||||||
|
'owner_name' => $this->resource instanceof RepositoryConnection ? $this->owner_name : Arr::get($this->resource, 'owner_name'),
|
||||||
|
'repository_name' => $this->resource instanceof RepositoryConnection
|
||||||
|
? $this->repository_name
|
||||||
|
: Arr::get($this->resource, 'repository_name'),
|
||||||
|
'repository_full_name' => $this->resource instanceof RepositoryConnection
|
||||||
|
? $this->repository_full_name
|
||||||
|
: Arr::get($this->resource, 'repository_full_name'),
|
||||||
|
'repository_url' => $this->resource instanceof RepositoryConnection ? $this->repository_url : Arr::get($this->resource, 'repository_url'),
|
||||||
|
'has_personal_access' => $this->resource instanceof RepositoryConnection
|
||||||
|
? (bool) ($this->resource->getAttribute('has_personal_access') ?? false)
|
||||||
|
: (bool) Arr::get($this->resource, 'has_personal_access', false),
|
||||||
|
'created_at' => $this->resource instanceof RepositoryConnection
|
||||||
|
? $this->created_at?->toISOString()
|
||||||
|
: Arr::get($this->resource, 'created_at'),
|
||||||
|
'updated_at' => $this->resource instanceof RepositoryConnection
|
||||||
|
? $this->updated_at?->toISOString()
|
||||||
|
: Arr::get($this->resource, 'updated_at'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TeamResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'user_ids' => $this->whenLoaded('users', fn (): array => $this->users->modelKeys()),
|
||||||
|
'users' => $this->whenLoaded('users', fn (): array => UserResource::collection($this->users)->resolve()),
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketBranchResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => Arr::get($this->resource, 'name'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketFieldDefinitionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'field_type' => $this->field_type,
|
||||||
|
'label' => $this->label,
|
||||||
|
'position' => $this->position,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketFieldValueResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'ticket_field_definition_id' => $this->ticket_field_definition_id,
|
||||||
|
'ticket_field_definition' => $this->whenLoaded(
|
||||||
|
'ticketFieldDefinition',
|
||||||
|
fn (): ?array => $this->ticketFieldDefinition === null
|
||||||
|
? null
|
||||||
|
: TicketFieldDefinitionResource::make($this->ticketFieldDefinition)->resolve(),
|
||||||
|
),
|
||||||
|
'ticket_id' => $this->ticket_id,
|
||||||
|
'user_value' => $this->whenLoaded(
|
||||||
|
'userValue',
|
||||||
|
fn (): ?array => $this->userValue === null
|
||||||
|
? null
|
||||||
|
: UserResource::make($this->userValue)->resolve(),
|
||||||
|
),
|
||||||
|
'value_number' => $this->value_number,
|
||||||
|
'value_user_id' => $this->value_user_id,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\TicketLink;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketLinkResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
if ($this->resource instanceof TicketLink) {
|
||||||
|
$currentTicketId = (int) ($this->resource->getAttribute('current_ticket_id') ?? 0);
|
||||||
|
$linkedTicket = $this->source_ticket_id === $currentTicketId
|
||||||
|
? $this->targetTicket
|
||||||
|
: $this->sourceTicket;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'linked_ticket' => TicketReferenceResource::make($linkedTicket)->resolve(),
|
||||||
|
'source_ticket_id' => $this->source_ticket_id,
|
||||||
|
'target_ticket_id' => $this->target_ticket_id,
|
||||||
|
'ticket_link_type' => TicketLinkTypeResource::make($this->ticketLinkType)->resolve(),
|
||||||
|
'ticket_link_type_id' => $this->ticket_link_type_id,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => Arr::get($this->resource, 'id'),
|
||||||
|
'linked_ticket' => TicketReferenceResource::make(Arr::get($this->resource, 'linked_ticket'))->resolve(),
|
||||||
|
'source_ticket_id' => Arr::get($this->resource, 'source_ticket_id'),
|
||||||
|
'target_ticket_id' => Arr::get($this->resource, 'target_ticket_id'),
|
||||||
|
'ticket_link_type' => TicketLinkTypeResource::make(Arr::get($this->resource, 'ticket_link_type'))->resolve(),
|
||||||
|
'ticket_link_type_id' => Arr::get($this->resource, 'ticket_link_type_id'),
|
||||||
|
'created_at' => Arr::get($this->resource, 'created_at'),
|
||||||
|
'updated_at' => Arr::get($this->resource, 'updated_at'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketLinkTypeResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'label' => $this->label,
|
||||||
|
'position' => $this->position,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketPriorityResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'position' => $this->position,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketPullRequestResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'html_url' => Arr::get($this->resource, 'html_url'),
|
||||||
|
'number' => Arr::get($this->resource, 'number'),
|
||||||
|
'source_branch' => Arr::get($this->resource, 'source_branch'),
|
||||||
|
'status' => Arr::get($this->resource, 'status'),
|
||||||
|
'title' => Arr::get($this->resource, 'title'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Ticket;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketReferenceResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->resource instanceof Ticket ? $this->id : Arr::get($this->resource, 'id'),
|
||||||
|
'ticket_key' => $this->resource instanceof Ticket ? $this->ticket_key : Arr::get($this->resource, 'ticket_key'),
|
||||||
|
'title' => $this->resource instanceof Ticket ? $this->title : Arr::get($this->resource, 'title'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketRepositoryBranchResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'branches' => TicketBranchResource::collection(collect(Arr::get($this->resource, 'branches', [])))->resolve(),
|
||||||
|
'error' => Arr::get($this->resource, 'error'),
|
||||||
|
'repository_connection' => RepositoryConnectionResource::make(
|
||||||
|
Arr::get($this->resource, 'repository_connection'),
|
||||||
|
)->resolve(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketRepositoryPullRequestResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'error' => Arr::get($this->resource, 'error'),
|
||||||
|
'pull_requests' => TicketPullRequestResource::collection(
|
||||||
|
collect(Arr::get($this->resource, 'pull_requests', [])),
|
||||||
|
)->resolve(),
|
||||||
|
'repository_connection' => RepositoryConnectionResource::make(
|
||||||
|
Arr::get($this->resource, 'repository_connection'),
|
||||||
|
)->resolve(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'acceptance_criteria' => $this->acceptance_criteria,
|
||||||
|
'assignee' => $this->whenLoaded(
|
||||||
|
'assignee',
|
||||||
|
fn (): ?array => $this->assignee === null
|
||||||
|
? null
|
||||||
|
: UserResource::make($this->assignee)->resolve(),
|
||||||
|
),
|
||||||
|
'assignee_user_id' => $this->assignee_user_id,
|
||||||
|
'author' => $this->whenLoaded(
|
||||||
|
'author',
|
||||||
|
fn (): ?array => $this->author === null
|
||||||
|
? null
|
||||||
|
: UserResource::make($this->author)->resolve(),
|
||||||
|
),
|
||||||
|
'author_user_id' => $this->author_user_id,
|
||||||
|
'blocked_comment' => $this->blocked_comment,
|
||||||
|
'description' => $this->description,
|
||||||
|
'field_values' => $this->whenLoaded(
|
||||||
|
'fieldValues',
|
||||||
|
fn (): array => TicketFieldValueResource::collection($this->fieldValues)->resolve(),
|
||||||
|
),
|
||||||
|
'is_blocked' => $this->is_blocked,
|
||||||
|
'parent_ticket_id' => $this->parent_ticket_id,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'sequence_number' => $this->sequence_number,
|
||||||
|
'story_points' => $this->story_points,
|
||||||
|
'ticket_key' => $this->ticket_key,
|
||||||
|
'ticket_priority' => $this->whenLoaded(
|
||||||
|
'ticketPriority',
|
||||||
|
fn (): ?array => $this->ticketPriority === null
|
||||||
|
? null
|
||||||
|
: TicketPriorityResource::make($this->ticketPriority)->resolve(),
|
||||||
|
),
|
||||||
|
'ticket_priority_id' => $this->ticket_priority_id,
|
||||||
|
'ticket_status' => $this->whenLoaded(
|
||||||
|
'ticketStatus',
|
||||||
|
fn (): ?array => $this->ticketStatus === null
|
||||||
|
? null
|
||||||
|
: TicketStatusResource::make($this->ticketStatus)->resolve(),
|
||||||
|
),
|
||||||
|
'ticket_status_id' => $this->ticket_status_id,
|
||||||
|
'ticket_type' => $this->whenLoaded(
|
||||||
|
'ticketType',
|
||||||
|
fn (): ?array => $this->ticketType === null
|
||||||
|
? null
|
||||||
|
: TicketTypeResource::make($this->ticketType)->resolve(),
|
||||||
|
),
|
||||||
|
'ticket_type_id' => $this->ticket_type_id,
|
||||||
|
'title' => $this->title,
|
||||||
|
'worklog_entries' => $this->whenLoaded(
|
||||||
|
'worklogEntries',
|
||||||
|
fn (): array => TicketWorklogEntryResource::collection($this->worklogEntries)->resolve(),
|
||||||
|
),
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketStatusResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'allowed_target_statuses' => $this->whenLoaded(
|
||||||
|
'allowedTargetStatuses',
|
||||||
|
fn (): array => TicketStatusResource::collection($this->allowedTargetStatuses)->resolve(),
|
||||||
|
),
|
||||||
|
'board_column' => $this->whenLoaded(
|
||||||
|
'boardColumn',
|
||||||
|
fn (): ?array => $this->boardColumn === null
|
||||||
|
? null
|
||||||
|
: BoardColumnResource::make($this->boardColumn)->resolve(),
|
||||||
|
),
|
||||||
|
'board_column_id' => $this->board_column_id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'position' => $this->position,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Ticket;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
class TicketTreeNodeResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
if ($this->resource instanceof Ticket) {
|
||||||
|
return [
|
||||||
|
'children' => TicketTreeNodeResource::collection(
|
||||||
|
$this->resource->childTickets()
|
||||||
|
->with('ticketType')
|
||||||
|
->get(),
|
||||||
|
)->resolve(),
|
||||||
|
'id' => $this->id,
|
||||||
|
'ticket_key' => $this->ticket_key,
|
||||||
|
'ticket_type_name' => $this->ticketType?->name,
|
||||||
|
'title' => $this->title,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'children' => TicketTreeNodeResource::collection(collect(Arr::get($this->resource, 'children', [])))->resolve(),
|
||||||
|
'id' => Arr::get($this->resource, 'id'),
|
||||||
|
'ticket_key' => Arr::get($this->resource, 'ticket_key'),
|
||||||
|
'ticket_type_name' => Arr::get($this->resource, 'ticket_type_name'),
|
||||||
|
'title' => Arr::get($this->resource, 'title'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketTypeResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'is_parent' => $this->is_parent,
|
||||||
|
'name' => $this->name,
|
||||||
|
'position' => $this->position,
|
||||||
|
'project_id' => $this->project_id,
|
||||||
|
'tickets_count' => $this->when(isset($this->tickets_count), (int) $this->tickets_count),
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class TicketWorklogEntryResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'actor' => $this->whenLoaded(
|
||||||
|
'actor',
|
||||||
|
fn (): ?array => $this->actor === null
|
||||||
|
? null
|
||||||
|
: UserResource::make($this->actor)->resolve(),
|
||||||
|
),
|
||||||
|
'actor_id' => $this->actor_id,
|
||||||
|
'changes' => $this->changes,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'entry_type' => $this->entry_type?->value,
|
||||||
|
'summary' => $this->summary,
|
||||||
|
'ticket_id' => $this->ticket_id,
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class UserGitConnectionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'provider' => $this->provider->value,
|
||||||
|
'provider_label' => $this->provider->label(),
|
||||||
|
'base_url' => $this->base_url,
|
||||||
|
'provider_user_id' => $this->provider_user_id,
|
||||||
|
'account_login' => $this->account_login,
|
||||||
|
'account_name' => $this->account_name,
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class UserResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'email' => $this->email,
|
||||||
|
'email_verified_at' => $this->email_verified_at?->toISOString(),
|
||||||
|
'created_at' => $this->created_at?->toISOString(),
|
||||||
|
'updated_at' => $this->updated_at?->toISOString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user