Skip to content

Commit fe65d95

Browse files
authored
Merge pull request #6 from AllanKoder/sorting-filters-on-all-tabs
Sorting filters on all resource tabs
2 parents d55a464 + 830b65c commit fe65d95

6 files changed

Lines changed: 59 additions & 37 deletions

File tree

app/Http/Controllers/ComputerScienceResourceController.php

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,26 @@
44

55
use App\Http\Requests\ComputerScienceResource\StoreResourceRequest;
66
use App\Models\ComputerScienceResource;
7+
use App\Models\ResourceEdits;
8+
use App\Models\ResourceReview;
79
use App\Services\CommentService;
10+
use App\Services\UpvoteService;
811
use Illuminate\Http\Request;
912
use Illuminate\Support\Facades\Auth;
1013
use Illuminate\Support\Facades\Log;
1114
use Inertia\Inertia;
1215

1316
class ComputerScienceResourceController extends Controller
1417
{
18+
protected $commentService;
19+
protected $upvoteService;
20+
21+
function __construct(CommentService $commentService, UpvoteService $upvoteService)
22+
{
23+
$this->commentService = $commentService;
24+
$this->upvoteService = $upvoteService;
25+
}
26+
1527
/**
1628
* Display a listing of the resource.
1729
*/
@@ -54,7 +66,7 @@ public function store(StoreResourceRequest $request)
5466

5567
// Add topics as tags
5668
$resource->topic_tags = $validatedData['topic_tags'];
57-
69+
5870
// Add programming languages as tags (if provided)
5971
if (isset($validatedData['programming_language_tags'])) {
6072
$resource->programming_language_tags = $validatedData['programming_language_tags'];
@@ -67,51 +79,59 @@ public function store(StoreResourceRequest $request)
6779

6880
Log::debug("Created resource " . json_encode($resource));
6981

70-
return redirect(route('resources.show', ['computerScienceResource'=>$resource->id]))
82+
return redirect(route('resources.show', ['computerScienceResource' => $resource->id]))
7183
->with('success', 'Created Resource Succesfully!');
7284
}
7385

7486
/**
7587
* Display the specified resource.
7688
*/
77-
public function show(Request $request, CommentService $commentService, ComputerScienceResource $computerScienceResource, string $tab = 'reviews')
89+
public function show(Request $request, ComputerScienceResource $computerScienceResource, string $tab = 'reviews')
7890
{
7991
$validTabs = ['reviews', 'discussion', 'edits'];
80-
92+
8193
if (!in_array($tab, $validTabs)) {
8294
// Redirect to default if invalid
8395
return redirect()->route('resources.show', [
8496
'computerScienceResource' => $computerScienceResource->id,
8597
'tab' => 'reviews',
8698
]);
8799
}
88-
100+
89101
// return the resource and tab
90102
$data = [
91103
'tab' => $tab,
92104
'resource' => $computerScienceResource,
93105
];
94-
106+
107+
$sortBy = $request->query('sort_by', 'top');
95108
// Load only the necessary tab data
96109
if ($tab === 'reviews') {
97-
$data['reviews'] = Inertia::defer(fn () =>
98-
$computerScienceResource->reviews()->orderByDesc('created_at')->get()
110+
$data['reviews'] = Inertia::defer(
111+
function () use ($computerScienceResource, $sortBy) {
112+
$query = ResourceReview::where('computer_science_resource_id', $computerScienceResource->id);
113+
$query = $this->upvoteService->applySort($query, $sortBy, ResourceReview::class);
114+
return $query->get();
115+
}
99116
);
100117
} elseif ($tab === 'edits') {
101-
$data['resourceEdits'] = Inertia::defer(fn () =>
102-
$computerScienceResource->edits
118+
$data['resourceEdits'] = Inertia::defer(
119+
function () use ($computerScienceResource, $sortBy) {
120+
$query = ResourceEdits::where('computer_science_resource_id', $computerScienceResource->id);
121+
$query = $this->upvoteService->applySort($query, $sortBy, ResourceEdits::class);
122+
return $query->get();
123+
}
103124
);
104125
} elseif ($tab === 'discussion') {
105-
$sortBy = $request->query('sort_by', 'top');
106-
$data['discussion'] = Inertia::defer(fn () =>
107-
$commentService->getPaginatedComments('resource', $computerScienceResource->id, 0, 150, $sortBy)
126+
$data['discussion'] = Inertia::defer(
127+
fn() =>
128+
$this->commentService->getPaginatedComments('resource', $computerScienceResource->id, 0, 150, $sortBy)
108129
);
109-
$data['discussionSortByValue'] = $sortBy;
110130
}
111-
131+
112132
return Inertia::render('Resources/Show', $data);
113133
}
114-
134+
115135

116136
/**
117137
* Remove the specified resource from storage.

app/Services/CommentService.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function __construct(ModelResolverService $resolver)
2828
* @return array
2929
*/
3030
// TODO: Refactor commentable types, and commentable types short for all other objects
31-
public function getPaginatedComments(string $commentableTypeShort, int $commentableId, int $index, int $paginationLimit = -1, string $sortBy = 'top'): array
31+
public function getPaginatedComments(string $commentableTypeShorthand, int $commentableId, int $index, int $paginationLimit = -1, string $sortBy = 'top'): array
3232
{
3333
if ($paginationLimit == -1)
3434
{
@@ -37,17 +37,15 @@ public function getPaginatedComments(string $commentableTypeShort, int $commenta
3737

3838
Validator::make([
3939
'index' => $index,
40-
'commentable_type_short' => $commentableTypeShort,
40+
'commentable_type_short' => $commentableTypeShorthand,
4141
'pagination_limit' => $paginationLimit,
42-
'sort_by' => $sortBy,
4342
], [
4443
'index' => ['required', 'integer', 'min:0'],
4544
'commentable_type_short' => ['required', Rule::in(config('comment.commentable_types_shorthand'))],
4645
'pagination_limit' => ['required', 'integer', 'max:' . config('comment.pagination_limit')],
47-
'sort_by' => ['required', 'string', Rule::in(config('comment.sortable_options'))],
4846
])->validate();
4947

50-
$commentableType = $this->modelResolver->getModelClass($commentableTypeShort);
48+
$commentableType = $this->modelResolver->getModelClass($commentableTypeShorthand);
5149
Log::debug("Request is, commentable_type: {$commentableType}. id: {$commentableId}. index: {$index}");
5250

5351
// Get the root comments:
@@ -58,7 +56,7 @@ public function getPaginatedComments(string $commentableTypeShort, int $commenta
5856
]);
5957

6058
// Apply sorting on the comments
61-
app(UpvoteService::class)->applySort($query, $sortBy, Comment::class);
59+
$query = app(UpvoteService::class)->applySort($query, $sortBy, Comment::class);
6260

6361
$rootComments = $query->get();
6462
Log::debug("Root comments: " . json_encode($rootComments));

resources/js/Components/Comments/Commentable.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { ref, provide, readonly, nextTick, onMounted, reactive } from "vue";
33
import axios from "axios";
44
import CommentActionsForm from "@/Components/Comments/CommentActionsForm.vue";
5-
import SortByDropdown from "@/Components/Comments/SortByDropdown.vue";
5+
import SortByDropdown from "@/Components/Comments/SortUpvotesByDropdown.vue";
66
import CommentList from "./CommentList.vue";
77
88
const props = defineProps({

resources/js/Components/Comments/SortByDropdown.vue renamed to resources/js/Components/Comments/SortUpvotesByDropdown.vue

File renamed without changes.

resources/js/Components/Resources/Discussion/DiscussionSorting.vue renamed to resources/js/Components/Resources/ResourceUpvoteSorting.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup>
22
import { router } from '@inertiajs/vue3';
33
import { defineProps } from 'vue';
4-
import SortByDropdown from "@/Components/Comments/SortByDropdown.vue";
4+
import SortByDropdown from "@/Components/Comments/SortUpvotesByDropdown.vue";
55
66
const props = defineProps({
77
resourceId: {
@@ -10,16 +10,19 @@ const props = defineProps({
1010
},
1111
initialValue: {
1212
type: String,
13-
required: true
13+
default: 'top',
14+
},
15+
tab: {
16+
type: String,
17+
default: 'discussion',
1418
}
1519
})
1620
1721
function handleSortChange(newSortType) {
18-
if (props.initialValue == newSortType) return;
1922
// Change the sort_by parameter
2023
const baseUrl = route('resources.show', {
2124
computerScienceResource: props.resourceId,
22-
tab: 'discussion',
25+
tab: props.tab,
2326
});
2427
2528
// Create a new URL object based on the current location
@@ -39,5 +42,6 @@ function handleSortChange(newSortType) {
3942
<template>
4043
<SortByDropdown
4144
@change="handleSortChange"
45+
:initial-value="initialValue"
4246
></SortByDropdown>
4347
</template>

resources/js/Pages/Resources/Show.vue

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import ResourceReviews from "@/Components/Resources/Reviews/ResourceReviews.vue";
1212
import Commentable from "@/Components/Comments/Commentable.vue";
1313
import ResourceEdits from "@/Components/Resources/ResourceEdit/ResourceEdits.vue";
14-
import DiscussionSorting from "@/Components/Resources/Discussion/DiscussionSorting.vue";
14+
import ResourceUpvoteSorting from "@/Components/Resources/ResourceUpvoteSorting.vue";
1515
import { getConfigData } from "@/Helpers/config";
1616
1717
const props = defineProps({
@@ -27,10 +27,6 @@ const props = defineProps({
2727
type: Object,
2828
required: false,
2929
},
30-
discussionSortByValue: {
31-
type: String,
32-
required: false,
33-
},
3430
reviews: {
3531
type: Array,
3632
required: false,
@@ -48,6 +44,9 @@ const tabs = [
4844
{ label: "Discussion", value: "discussion" },
4945
{ label: "Proposed Edits", value: "edits" },
5046
];
47+
48+
const urlParams = new URLSearchParams(window.location.search);
49+
const sortingType = urlParams.get('sort_by') || 'top';
5150
</script>
5251

5352
<template>
@@ -220,6 +219,12 @@ const tabs = [
220219

221220
<!-- Tab Panels -->
222221
<div class="px-6 pb-6">
222+
<ResourceUpvoteSorting
223+
:resource-id="props.resource.id"
224+
:initial-value="sortingType"
225+
:tab="props.tab"
226+
></ResourceUpvoteSorting>
227+
223228
<div v-if="props.tab === 'reviews'">
224229
<Deferred data="reviews">
225230
<template #fallback>
@@ -233,11 +238,6 @@ const tabs = [
233238
</div>
234239

235240
<div v-else-if="props.tab === 'discussion'">
236-
<DiscussionSorting
237-
:resource-id="props.resource.id"
238-
:initial-value="props.discussionSortByValue"
239-
></DiscussionSorting>
240-
241241
<Deferred data="discussion">
242242
<template #fallback>
243243
<div>Loading...</div>

0 commit comments

Comments
 (0)