From 830b65c35a615a07fed8652a80f5dc4315a94c62 Mon Sep 17 00:00:00 2001 From: Allan Kong Date: Sat, 26 Apr 2025 15:58:09 -0600 Subject: [PATCH] Sorting filters on all resource tabs --- .../ComputerScienceResourceController.php | 52 +++++++++++++------ app/Services/CommentService.php | 10 ++-- .../js/Components/Comments/Commentable.vue | 2 +- ...Dropdown.vue => SortUpvotesByDropdown.vue} | 0 ...nSorting.vue => ResourceUpvoteSorting.vue} | 12 +++-- resources/js/Pages/Resources/Show.vue | 20 +++---- 6 files changed, 59 insertions(+), 37 deletions(-) rename resources/js/Components/Comments/{SortByDropdown.vue => SortUpvotesByDropdown.vue} (100%) rename resources/js/Components/Resources/{Discussion/DiscussionSorting.vue => ResourceUpvoteSorting.vue} (78%) diff --git a/app/Http/Controllers/ComputerScienceResourceController.php b/app/Http/Controllers/ComputerScienceResourceController.php index c1732f6e..93566ac6 100644 --- a/app/Http/Controllers/ComputerScienceResourceController.php +++ b/app/Http/Controllers/ComputerScienceResourceController.php @@ -4,7 +4,10 @@ use App\Http\Requests\ComputerScienceResource\StoreResourceRequest; use App\Models\ComputerScienceResource; +use App\Models\ResourceEdits; +use App\Models\ResourceReview; use App\Services\CommentService; +use App\Services\UpvoteService; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; @@ -12,6 +15,15 @@ class ComputerScienceResourceController extends Controller { + protected $commentService; + protected $upvoteService; + + function __construct(CommentService $commentService, UpvoteService $upvoteService) + { + $this->commentService = $commentService; + $this->upvoteService = $upvoteService; + } + /** * Display a listing of the resource. */ @@ -54,7 +66,7 @@ public function store(StoreResourceRequest $request) // Add topics as tags $resource->topic_tags = $validatedData['topic_tags']; - + // Add programming languages as tags (if provided) if (isset($validatedData['programming_language_tags'])) { $resource->programming_language_tags = $validatedData['programming_language_tags']; @@ -67,17 +79,17 @@ public function store(StoreResourceRequest $request) Log::debug("Created resource " . json_encode($resource)); - return redirect(route('resources.show', ['computerScienceResource'=>$resource->id])) + return redirect(route('resources.show', ['computerScienceResource' => $resource->id])) ->with('success', 'Created Resource Succesfully!'); } /** * Display the specified resource. */ - public function show(Request $request, CommentService $commentService, ComputerScienceResource $computerScienceResource, string $tab = 'reviews') + public function show(Request $request, ComputerScienceResource $computerScienceResource, string $tab = 'reviews') { $validTabs = ['reviews', 'discussion', 'edits']; - + if (!in_array($tab, $validTabs)) { // Redirect to default if invalid return redirect()->route('resources.show', [ @@ -85,33 +97,41 @@ public function show(Request $request, CommentService $commentService, ComputerS 'tab' => 'reviews', ]); } - + // return the resource and tab $data = [ 'tab' => $tab, 'resource' => $computerScienceResource, ]; - + + $sortBy = $request->query('sort_by', 'top'); // Load only the necessary tab data if ($tab === 'reviews') { - $data['reviews'] = Inertia::defer(fn () => - $computerScienceResource->reviews()->orderByDesc('created_at')->get() + $data['reviews'] = Inertia::defer( + function () use ($computerScienceResource, $sortBy) { + $query = ResourceReview::where('computer_science_resource_id', $computerScienceResource->id); + $query = $this->upvoteService->applySort($query, $sortBy, ResourceReview::class); + return $query->get(); + } ); } elseif ($tab === 'edits') { - $data['resourceEdits'] = Inertia::defer(fn () => - $computerScienceResource->edits + $data['resourceEdits'] = Inertia::defer( + function () use ($computerScienceResource, $sortBy) { + $query = ResourceEdits::where('computer_science_resource_id', $computerScienceResource->id); + $query = $this->upvoteService->applySort($query, $sortBy, ResourceEdits::class); + return $query->get(); + } ); } elseif ($tab === 'discussion') { - $sortBy = $request->query('sort_by', 'top'); - $data['discussion'] = Inertia::defer(fn () => - $commentService->getPaginatedComments('resource', $computerScienceResource->id, 0, 150, $sortBy) + $data['discussion'] = Inertia::defer( + fn() => + $this->commentService->getPaginatedComments('resource', $computerScienceResource->id, 0, 150, $sortBy) ); - $data['discussionSortByValue'] = $sortBy; } - + return Inertia::render('Resources/Show', $data); } - + /** * Remove the specified resource from storage. diff --git a/app/Services/CommentService.php b/app/Services/CommentService.php index 292306de..5c267ec8 100644 --- a/app/Services/CommentService.php +++ b/app/Services/CommentService.php @@ -28,7 +28,7 @@ function __construct(ModelResolverService $resolver) * @return array */ // TODO: Refactor commentable types, and commentable types short for all other objects - public function getPaginatedComments(string $commentableTypeShort, int $commentableId, int $index, int $paginationLimit = -1, string $sortBy = 'top'): array + public function getPaginatedComments(string $commentableTypeShorthand, int $commentableId, int $index, int $paginationLimit = -1, string $sortBy = 'top'): array { if ($paginationLimit == -1) { @@ -37,17 +37,15 @@ public function getPaginatedComments(string $commentableTypeShort, int $commenta Validator::make([ 'index' => $index, - 'commentable_type_short' => $commentableTypeShort, + 'commentable_type_short' => $commentableTypeShorthand, 'pagination_limit' => $paginationLimit, - 'sort_by' => $sortBy, ], [ 'index' => ['required', 'integer', 'min:0'], 'commentable_type_short' => ['required', Rule::in(config('comment.commentable_types_shorthand'))], 'pagination_limit' => ['required', 'integer', 'max:' . config('comment.pagination_limit')], - 'sort_by' => ['required', 'string', Rule::in(config('comment.sortable_options'))], ])->validate(); - $commentableType = $this->modelResolver->getModelClass($commentableTypeShort); + $commentableType = $this->modelResolver->getModelClass($commentableTypeShorthand); Log::debug("Request is, commentable_type: {$commentableType}. id: {$commentableId}. index: {$index}"); // Get the root comments: @@ -58,7 +56,7 @@ public function getPaginatedComments(string $commentableTypeShort, int $commenta ]); // Apply sorting on the comments - app(UpvoteService::class)->applySort($query, $sortBy, Comment::class); + $query = app(UpvoteService::class)->applySort($query, $sortBy, Comment::class); $rootComments = $query->get(); Log::debug("Root comments: " . json_encode($rootComments)); diff --git a/resources/js/Components/Comments/Commentable.vue b/resources/js/Components/Comments/Commentable.vue index 5e14ec12..a1f67801 100644 --- a/resources/js/Components/Comments/Commentable.vue +++ b/resources/js/Components/Comments/Commentable.vue @@ -2,7 +2,7 @@ import { ref, provide, readonly, nextTick, onMounted, reactive } from "vue"; import axios from "axios"; import CommentActionsForm from "@/Components/Comments/CommentActionsForm.vue"; -import SortByDropdown from "@/Components/Comments/SortByDropdown.vue"; +import SortByDropdown from "@/Components/Comments/SortUpvotesByDropdown.vue"; import CommentList from "./CommentList.vue"; const props = defineProps({ diff --git a/resources/js/Components/Comments/SortByDropdown.vue b/resources/js/Components/Comments/SortUpvotesByDropdown.vue similarity index 100% rename from resources/js/Components/Comments/SortByDropdown.vue rename to resources/js/Components/Comments/SortUpvotesByDropdown.vue diff --git a/resources/js/Components/Resources/Discussion/DiscussionSorting.vue b/resources/js/Components/Resources/ResourceUpvoteSorting.vue similarity index 78% rename from resources/js/Components/Resources/Discussion/DiscussionSorting.vue rename to resources/js/Components/Resources/ResourceUpvoteSorting.vue index 2a4446bf..2dadbb83 100644 --- a/resources/js/Components/Resources/Discussion/DiscussionSorting.vue +++ b/resources/js/Components/Resources/ResourceUpvoteSorting.vue @@ -1,7 +1,7 @@