Untitled

 avatar
unknown
php
2 years ago
5.9 kB
6
Indexable
<?php

namespace App\Http\Livewire\Production\Tasks\Comments;

use App\Models\ProductionAssignmentLinkComment;
use App\Models\ProductionTask;
use App\Models\ProductionTaskComment;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Component;

class Index extends Component
{
    public ProductionTask $task;

    public array $selected = [];

    public array $options = [];

    public Collection $links;

    public array $allComments = [];

    public ?string $sortBy = '';

    protected $listeners = [
        'refreshComments' => 'mountAllComments',
    ];

    public function mount()
    {
        $this->mountLinks();
        $this->mountOptions();

        $this->mountAllComments();
    }

    public function render()
    {
        $comments = $this->sortCollection(collect($this->filteredComments()));

        return view('production.tasks.comments.index', compact('comments'));
    }

    public function deleteComment(int $id, string $selected)
    {
        $comment = $selected === 'task_comment'
            ? $this->task->comments()->findOrFail($id)
            : $this->task->researchAssignment->linkComments()->findOrFail($id);

        abort_if($comment->user_id != auth()->id(), 403);

        $comment->delete();

        $this->mountAllComments();
    }

    public function mountAllComments()
    {
        $this->allComments = collect($this->linkComments())
            ->merge($this->taskComments())
            ->values()
            ->toArray();
    }

    public function getSortOptionsProperty(): array
    {
        return [
            ['id' => 'timestamp_first', 'name' => 'Timestamp first'],
            ['id' => 'timestamp_last', 'name' => 'Timestamp last'],
            ['id' => 'creation_first', 'name' => 'Creation first'],
            ['id' => 'creation_last', 'name' => 'Creation last'],
        ];
    }

    protected function filteredComments(): array
    {
        if (blank($this->selected)) {
            return $this->allComments;
        }

        return collect($this->allComments)
            ->whereIn('filterable_key', $this->selected)
            ->values()
            ->toArray();
    }

    protected function taskComments(): array
    {
        return $this->task->comments()
            ->parents()
            ->with('user', 'replies.user')
            ->get()
            ->map(fn(ProductionTaskComment $comment) => $this->transformTaskComment($comment))
            ->toArray();
    }

    protected function linkComments(): array
    {
        return $this->task->researchAssignment
            ->linkComments()
            ->parents()
            ->with('user', 'replies.user')
            ->get()
            ->map(fn(ProductionAssignmentLinkComment $comment) => $this->transformLinkComment($comment))
            ->toArray();
    }

    protected function mountLinks()
    {
        $this->links = $this->task->researchAssignment->links()->get();
    }

    protected function mountOptions()
    {
        $this->options = [
            ['id' => 'task', 'name' => 'Task Comments'],
        ];

        foreach ($this->links as $key => $link) {
            $this->options[] = ['id' => $link->id, 'name' => 'Link ' . $key + 1];
        }

    }

    protected function transformTaskComment(ProductionTaskComment $comment): array
    {
        $replies = $comment->replies
            ->map(fn(ProductionTaskComment $comment) => $this->transformTaskComment($comment));

        return [
            'filterable_key' => 'task',
            'id' => $comment->id,
            'type' => 'task_comment',
            'user_id' => auth()->id(),
            'user_image' => $comment->user->image_url ?? null,
            'user_name' => $comment->user->name ?? null,
            'rich_text' => $comment->rich_text,
            'created_at' => $comment->created_at->toDateTimeString(),
            'created_at_diff_for_humans' => $comment->created_at->diffForHumans(),
            'parent_id' => $comment->parent_id,
            'link_key' => null,
            'link_id' => null,
            'timestamp' => null,
            'replies' => $this->sortCollection($replies),
        ];
    }

    protected function transformLinkComment(ProductionAssignmentLinkComment $comment): array
    {
        $replies = $comment->replies
            ->map(fn(ProductionAssignmentLinkComment $comment) => $this->transformLinkComment($comment));

        $index = $this->links->search(function ($item) use ($comment) {
            return $item->id == $comment->production_assignment_link_id;
        });

        return [
            'filterable_key' => $comment->production_assignment_link_id,
            'id' => $comment->id,
            'type' => 'link_comment',
            'user_id' => auth()->id(),
            'user_image' => $comment->user->image_url ?? null,
            'user_name' => $comment->user->name ?? null,
            'rich_text' => $comment->rich_text,
            'created_at' => $comment->created_at->toDateTimeString(),
            'created_at_diff_for_humans' => $comment->created_at->diffForHumans(),
            'parent_id' => $comment->parent_id,
            'link_id' => $comment->production_assignment_link_id,
            'link_key' => $index + 1,
            'timestamp' => $comment->timestamp,
            'replies' => $this->sortCollection($replies),
        ];
    }

    protected function sortCollection(\Illuminate\Support\Collection $collection): array
    {
        return $collection
            ->when($this->sortBy === 'timestamp_first', fn($query) => $query->sortBy('timestamp'))
            ->when($this->sortBy === 'timestamp_last', fn($query) => $query->sortByDesc('timestamp'))
            ->when($this->sortBy === 'creation_first', fn($query) => $query->sortBy('created_at'))
            ->when($this->sortBy === 'creation_last', fn($query) => $query->sortByDesc('created_at'))
            ->values()
            ->toArray();
    }
}
Editor is loading...