From ec26f956b1bb772a1a2b2fbfef1f105d6f0c4c7f Mon Sep 17 00:00:00 2001 From: Xinecraft Date: Sat, 21 Dec 2024 18:06:08 +0530 Subject: [PATCH] improve filter multi field to support relations --- .../Admin/CommandQueueController.php | 5 +- .../Admin/RecruitmentSubmissionController.php | 48 +- app/Http/Controllers/BanWardenController.php | 1 + app/Queries/Filters/FilterMultipleFields.php | 33 +- .../Admin/CommandQueue/IndexCommandQueue.vue | 473 +++++++++++------- 5 files changed, 375 insertions(+), 185 deletions(-) diff --git a/app/Http/Controllers/Admin/CommandQueueController.php b/app/Http/Controllers/Admin/CommandQueueController.php index 129b1ae29..ca9dea2db 100644 --- a/app/Http/Controllers/Admin/CommandQueueController.php +++ b/app/Http/Controllers/Admin/CommandQueueController.php @@ -48,7 +48,7 @@ public function index() ]; $commandQueues = QueryBuilder::for(CommandQueue::class) - ->with(['server:id,name,hostname', 'player:id,uuid,username']) + ->with(['server:id,name,hostname', 'player:id,uuid,username,skin_texture_id', 'user:id,name,username,profile_photo_path']) ->allowedFilters([ ...$fields, 'server.name', @@ -60,6 +60,9 @@ public function index() 'output', 'tag', 'player_uuid', + 'player.username', + 'user.username', + 'user.name', ])), ]) ->allowedSorts($fields) diff --git a/app/Http/Controllers/Admin/RecruitmentSubmissionController.php b/app/Http/Controllers/Admin/RecruitmentSubmissionController.php index d18b2391b..d37df167c 100644 --- a/app/Http/Controllers/Admin/RecruitmentSubmissionController.php +++ b/app/Http/Controllers/Admin/RecruitmentSubmissionController.php @@ -73,7 +73,17 @@ public function indexOpen(Request $request) 'user.name', 'lastActor.name', 'lastCommentor.name', - AllowedFilter::custom('q', new FilterMultipleFields(['id', 'data', 'status'])), + AllowedFilter::custom('q', new FilterMultipleFields([ + 'id', + 'data', + 'status', + 'user.name', + 'user.username', + 'lastActor.name', + 'lastActor.username', + 'lastCommentor.name', + 'lastCommentor.username', + ])), ]) ->allowedSorts($fields) ->defaultSort('-updated_at') @@ -142,7 +152,17 @@ public function indexClosed(Request $request) 'user.name', 'lastActor.name', 'lastCommentor.name', - AllowedFilter::custom('q', new FilterMultipleFields(['id', 'data', 'status'])), + AllowedFilter::custom('q', new FilterMultipleFields([ + 'id', + 'data', + 'status', + 'user.name', + 'user.username', + 'lastActor.name', + 'lastActor.username', + 'lastCommentor.name', + 'lastCommentor.username', + ])), ]) ->allowedSorts($fields) ->defaultSort('-updated_at') @@ -167,17 +187,17 @@ public function show(Request $request, RecruitmentSubmission $submission) 'lastActor:id,name,username', ]); $submission['i_can_act'] = $request->user()->can('actOn', $submission) - && in_array($submission->status, [ - RecruitmentSubmissionStatus::PENDING, - RecruitmentSubmissionStatus::INPROGRESS, - RecruitmentSubmissionStatus::ONHOLD, - ]); + && in_array($submission->status, [ + RecruitmentSubmissionStatus::PENDING, + RecruitmentSubmissionStatus::INPROGRESS, + RecruitmentSubmissionStatus::ONHOLD, + ]); $submission['i_can_delete'] = $request->user()->can('delete', $submission) - && in_array($submission->status, [ - RecruitmentSubmissionStatus::APPROVED, - RecruitmentSubmissionStatus::REJECTED, - RecruitmentSubmissionStatus::WITHDRAWN, - ]); + && in_array($submission->status, [ + RecruitmentSubmissionStatus::APPROVED, + RecruitmentSubmissionStatus::REJECTED, + RecruitmentSubmissionStatus::WITHDRAWN, + ]); $submission['i_can_send_message'] = in_array($submission->status, [ RecruitmentSubmissionStatus::PENDING, RecruitmentSubmissionStatus::INPROGRESS, @@ -204,7 +224,7 @@ public function act(Request $request, RecruitmentSubmission $submission) $this->authorize('actOn', $submission); $request->validate([ - 'action' => 'required|in:'.implode(',', [ + 'action' => 'required|in:' . implode(',', [ RecruitmentSubmissionStatus::INPROGRESS, RecruitmentSubmissionStatus::ONHOLD, RecruitmentSubmissionStatus::APPROVED, @@ -251,7 +271,7 @@ public function postMessage(Request $request, RecruitmentSubmission $submission) { $request->validate([ 'message' => 'required|max:2000', - 'type' => ['required', 'in:'.implode(',', [CommentType::RECRUITMENT_STAFF_WHISPER, CommentType::RECRUITMENT_STAFF_MESSAGE])], + 'type' => ['required', 'in:' . implode(',', [CommentType::RECRUITMENT_STAFF_WHISPER, CommentType::RECRUITMENT_STAFF_MESSAGE])], ]); $comment = $submission->comment($request->message, $request->type); diff --git a/app/Http/Controllers/BanWardenController.php b/app/Http/Controllers/BanWardenController.php index 0bae83c01..00aa16801 100644 --- a/app/Http/Controllers/BanWardenController.php +++ b/app/Http/Controllers/BanWardenController.php @@ -67,6 +67,7 @@ public function index() 'creator_username', 'remover_username', 'remover_uuid', + 'victimPlayer.username', ])), ]) ->allowedSorts($fields) diff --git a/app/Queries/Filters/FilterMultipleFields.php b/app/Queries/Filters/FilterMultipleFields.php index bb09b2570..b86631f9e 100644 --- a/app/Queries/Filters/FilterMultipleFields.php +++ b/app/Queries/Filters/FilterMultipleFields.php @@ -3,12 +3,16 @@ namespace App\Queries\Filters; use App\Utils\Helpers\Helper; +use Illuminate\Support\Str; use Spatie\QueryBuilder\Filters\Filter; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Relations\Relation; class FilterMultipleFields implements Filter { - public function __construct(public $fields) {} + public function __construct(public $fields) + { + } public function __invoke(Builder $query, $value, string $property): Builder { @@ -17,10 +21,35 @@ public function __invoke(Builder $query, $value, string $property): Builder $query->where(function ($query) use ($fields, $value) { foreach ($fields as $field) { $val = Helper::escapeLike($value); - $query->orWhere($field, 'LIKE', "%" . $val . "%"); + // Handle Relation Field + if ($this->isRelationProperty($query, $field)) { + $query->orWhereHas(Str::before($field, '.'), function ($query) use ($field, $val) { + $query->where(Str::after($field, '.'), 'LIKE', "%" . $val . "%"); + }); + continue; + } else { + // Handle No Relation Field + $query->orWhere($field, 'LIKE', "%" . $val . "%"); + } } }); return $query; } + + + private function isRelationProperty(Builder $query, string $property): bool + { + if (!Str::contains($property, '.')) { + return false; + } + + $firstRelationship = explode('.', $property)[0]; + + if (!method_exists($query->getModel(), $firstRelationship)) { + return false; + } + + return is_a($query->getModel()->{$firstRelationship}(), Relation::class); + } } diff --git a/resources/default/js/Pages/Admin/CommandQueue/IndexCommandQueue.vue b/resources/default/js/Pages/Admin/CommandQueue/IndexCommandQueue.vue index 975057d73..af3e44862 100644 --- a/resources/default/js/Pages/Admin/CommandQueue/IndexCommandQueue.vue +++ b/resources/default/js/Pages/Admin/CommandQueue/IndexCommandQueue.vue @@ -5,8 +5,13 @@ import { useHelpers } from '@/Composables/useHelpers'; import { useTranslations } from '@/Composables/useTranslations'; import DataTable from '@/Components/DataTable/DataTable.vue'; import DtRowItem from '@/Components/DataTable/DtRowItem.vue'; -import { TrashIcon, ArrowPathIcon } from '@heroicons/vue/24/outline'; +import { TrashIcon, ArrowPathIcon, EyeIcon } from '@heroicons/vue/24/outline'; import CommonStatusBadge from '@/Shared/CommonStatusBadge.vue'; +import JetDialogModal from '@/Jetstream/DialogModal.vue'; +import JetSecondaryButton from '@/Jetstream/SecondaryButton.vue'; +import { ref } from 'vue'; +import { Link } from '@inertiajs/vue3'; +import UserDisplayname from '@/Components/UserDisplayname.vue'; const { can } = useAuthorizable(); const { __ } = useTranslations(); @@ -100,187 +105,319 @@ const headerRow = [ class: 'w-1/12 text-right', }, ]; + +let showingDetailsModel = ref(false); +let selectedCommandQueue = ref({}); + +const showDetails = (commandQueue) => { + selectedCommandQueue.value = commandQueue; + showingDetailsModel.value = true; +};