Skip to content

Commit

Permalink
fix: Task search
Browse files Browse the repository at this point in the history
  • Loading branch information
lewislarsen committed Jan 10, 2025
1 parent e71ee4e commit 76a5dab
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 66 deletions.
12 changes: 11 additions & 1 deletion app/Livewire/BackupTasks/Tables/IndexTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,17 @@ private function getFilteredQuery(): Builder
}

if ($this->search !== '') {
$query->where('label', 'like', "%{$this->search}%");
$connection = config('database.default');
$driver = config("database.connections.{$connection}.driver");

if ($driver === 'pgsql') {
// Use ilike for PostgreSQL to make the search case-insensitive
$query->where('label', 'ilike', "%{$this->search}%");
} else {
// TODO: Investigate approaches like 'ilike' in other engines to improve the experience.
// Use like for other database engines
$query->where('label', 'like', "%{$this->search}%");
}
}

return $query->orderByRaw('favourited_at IS NULL')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('backup_tasks', function (Blueprint $table) {
$table->index('label');
});
}
};
142 changes: 77 additions & 65 deletions resources/views/livewire/backup-tasks/tables/index-table.blade.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
<div>
<div class="mt-4">
@if ($filteredCount === 0 &&Auth::user()->backupTasks()->exists())
<x-no-content withBackground>
<x-slot name="icon">
@svg('hugeicons-filter', 'inline h-16 w-16 text-primary-900 dark:text-white')
</x-slot>
<x-slot name="title">
{{ __('No backup tasks match your filters!') }}
</x-slot>
<x-slot name="description">
{{ __('Try adjusting your filter criteria or clear your filter.') }}
</x-slot>
<x-slot name="action">
<x-danger-button type="button" class="mt-4" wire:click="resetFilters">
{{ __('Reset Filters') }}
</x-danger-button>
</x-slot>
</x-no-content>
<div class="mb-4">
<x-no-content withBackground>
<x-slot name="icon">
@svg('hugeicons-filter', 'inline h-16 w-16 text-primary-900 dark:text-white')
</x-slot>
<x-slot name="title">
{{ __('No backup tasks match your filters!') }}
</x-slot>
<x-slot name="description">
{{ __('Try adjusting your filter criteria or clear your filter.') }}
</x-slot>
<x-slot name="action">
<x-danger-button type="button" class="mt-4" wire:click="resetFilters">
{{ __('Reset Filters') }}
</x-danger-button>
</x-slot>
</x-no-content>
</div>
@elseif (! Auth::user()->backupTasks()->exists())
<x-no-content withBackground>
<x-slot name="icon">
Expand Down Expand Up @@ -45,52 +47,58 @@
<x-hugeicons-archive-02 class="h-6 w-6 text-primary-600 dark:text-primary-400" />
</x-slot>

<div class="mb-4 flex flex-wrap items-center gap-4">
<div class="flex-grow">
<x-input-label for="search" :value="__('Search')" />
<x-text-input
id="search"
name="search"
type="text"
class="mt-1 block w-full"
wire:model.live="search"
:placeholder="__('Search by label')"
/>
</div>
<div>
<x-input-label for="status" :value="__('Status')" />
<x-select id="status" class="mt-1 block w-full" wire:model.live="status" name="status">
<option value="">{{ __('All') }}</option>
@foreach ($statuses as $statusOption)
<option value="{{ $statusOption }}">{{ __(ucfirst($statusOption)) }}</option>
@endforeach
</x-select>
</div>
<div>
<x-input-label for="tag" :value="__('Tag')" />
<x-select id="tag" name="tag" class="mt-1 block w-full" wire:model.live="selectedTag">
<option value="">{{ __('All Tags') }}</option>
@foreach ($tags as $tag)
<option value="{{ $tag->id }}">{{ $tag->label }}</option>
@endforeach
</x-select>
</div>
<div class="mt-7 flex items-end">
<x-secondary-button wire:click="resetFilters" iconOnly title="{{ __('Clear filter') }}">
@svg('hugeicons-filter-remove')
</x-secondary-button>
<div class="mb-4">
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
<div>
<x-input-label for="search" :value="__('Search')" />
<x-text-input
id="search"
name="search"
type="text"
class="mt-1 block w-full"
wire:model.live="search"
:placeholder="__('Search by label')"
/>
</div>
<div>
<x-input-label for="status" :value="__('Status')" />
<x-select id="status" class="mt-1 block w-full" wire:model.live="status" name="status">
<option value="">{{ __('All') }}</option>
@foreach ($statuses as $statusOption)
<option value="{{ $statusOption }}">{{ __(ucfirst($statusOption)) }}</option>
@endforeach
</x-select>
</div>
<div>
<x-input-label for="tag" :value="__('Tag')" />
<x-select id="tag" name="tag" class="mt-1 block w-full" wire:model.live="selectedTag">
<option value="">{{ __('All Tags') }}</option>
@foreach ($tags as $tag)
<option value="{{ $tag->id }}">{{ $tag->label }}</option>
@endforeach
</x-select>
</div>
<div class="flex items-end">
@if ($selectedTag || $status || $search)
<x-secondary-button wire:click="resetFilters" iconOnly title="{{ __('Clear filter') }}">
@svg('hugeicons-filter-remove')
</x-secondary-button>
@endif
</div>
</div>
</div>

@if ($backupTasks->isEmpty() && $filteredCount > 0)
<x-no-content>
<x-slot name="title">
{{ __('No backup tasks match your filters') }}
</x-slot>
<x-slot name="description">
{{ __('Try adjusting your search or filter criteria.') }}
</x-slot>
</x-no-content>
<div class="mb-4">
<x-no-content>
<x-slot name="title">
{{ __('No backup tasks match your filters') }}
</x-slot>
<x-slot name="description">
{{ __('Try adjusting your search or filter criteria.') }}
</x-slot>
</x-no-content>
</div>
@else
<x-table.table-header>
<div class="col-span-12 md:col-span-3">
Expand Down Expand Up @@ -121,11 +129,15 @@ class="mt-1 block w-full"
</div>
@endif
</div>
<script>
document.addEventListener('livewire:initialized', () => {
Livewire.on('urlParametersCleared', () => {
history.replaceState(null, '', window.location.pathname);
});
});
</script>
</div>
<script>
document.addEventListener('livewire:initialized', () => {
Livewire.on('urlParametersUpdated', ({ queryParams }) => {
history.replaceState(null, '', `?${queryParams}`);
});
Livewire.on('urlParametersCleared', () => {
history.replaceState(null, '', window.location.pathname);
});
});
</script>

0 comments on commit 76a5dab

Please sign in to comment.