Make QuickSwitcher search across all locales
Delegates to DocumentService::search which queries DocumentTranslation and collapses to distinct documents. Display titles use the Document title accessor (current locale + fallback).
This commit is contained in:
@@ -4,65 +4,32 @@
|
||||
|
||||
use App\Models\Document;
|
||||
use App\Services\DocumentService;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Computed;
|
||||
use Livewire\Component;
|
||||
|
||||
class QuickSwitcher extends Component
|
||||
{
|
||||
public $search = '';
|
||||
public $selectedIndex = 0;
|
||||
public string $search = '';
|
||||
public int $selectedIndex = 0;
|
||||
|
||||
#[Computed]
|
||||
public function results()
|
||||
{
|
||||
if (empty($this->search)) {
|
||||
return Document::select('id', 'title', 'slug', 'path', 'updated_at')
|
||||
$documents = Document::with('translations')
|
||||
->orderBy('updated_at', 'desc')
|
||||
->limit(10)
|
||||
->get()
|
||||
->map(fn($doc) => [
|
||||
'id' => $doc->id,
|
||||
'title' => $doc->title,
|
||||
'slug' => $doc->slug,
|
||||
'directory' => dirname($doc->path),
|
||||
])
|
||||
->toArray();
|
||||
->get();
|
||||
} else {
|
||||
$documents = app(DocumentService::class)->search($this->search, 10);
|
||||
}
|
||||
|
||||
// FULLTEXT検索を使用(日本語対応)
|
||||
$results = Document::select('id', 'title', 'slug', 'path', 'updated_at')
|
||||
->whereRaw('MATCH(title, content) AGAINST(? IN BOOLEAN MODE)', [$this->search])
|
||||
->orderBy('updated_at', 'desc')
|
||||
->limit(10)
|
||||
->get()
|
||||
->map(fn($doc) => [
|
||||
'id' => $doc->id,
|
||||
'title' => $doc->title,
|
||||
'slug' => $doc->slug,
|
||||
'directory' => dirname($doc->path),
|
||||
])
|
||||
->toArray();
|
||||
|
||||
// FULLTEXT検索で結果がない場合は LIKE 検索にフォールバック
|
||||
if (empty($results)) {
|
||||
$results = Document::select('id', 'title', 'slug', 'path', 'updated_at')
|
||||
->where(function($query) {
|
||||
$query->where('title', 'like', '%' . $this->search . '%')
|
||||
->orWhere('content', 'like', '%' . $this->search . '%');
|
||||
})
|
||||
->orderBy('updated_at', 'desc')
|
||||
->limit(10)
|
||||
->get()
|
||||
->map(fn($doc) => [
|
||||
'id' => $doc->id,
|
||||
'title' => $doc->title,
|
||||
'slug' => $doc->slug,
|
||||
'directory' => dirname($doc->path),
|
||||
])
|
||||
->toArray();
|
||||
}
|
||||
|
||||
return $results;
|
||||
return $documents->map(fn ($doc) => [
|
||||
'id' => $doc->id,
|
||||
'title' => $doc->title,
|
||||
'slug' => $doc->slug,
|
||||
'directory' => dirname($doc->path),
|
||||
])->values()->toArray();
|
||||
}
|
||||
|
||||
public function updated($propertyName)
|
||||
@@ -92,8 +59,6 @@ public function selectDocument()
|
||||
$results = $this->results;
|
||||
if (isset($results[$this->selectedIndex])) {
|
||||
$document = $results[$this->selectedIndex];
|
||||
|
||||
// slug が存在することを確認
|
||||
if (!empty($document['slug'])) {
|
||||
return $this->redirect(route('documents.show', $document['slug']));
|
||||
}
|
||||
|
||||
@@ -102,4 +102,29 @@ public function test_editor_for_missing_locale_shows_empty_form_with_new_locale_
|
||||
// The blade should render a tab marked active for ja with empty inputs
|
||||
$response->assertSeeText(__('messages.locale_names.ja', [], 'en'));
|
||||
}
|
||||
|
||||
public function test_quick_switcher_finds_documents_by_any_locale_title(): void
|
||||
{
|
||||
$doc = Document::factory()->create(['default_locale' => 'en', 'slug' => 'qs']);
|
||||
$doc->translations()->where('locale', 'en')->update(['title' => 'Getting Started', 'content' => 'EN body']);
|
||||
DocumentTranslation::factory()->create([
|
||||
'document_id' => $doc->id,
|
||||
'locale' => 'ja',
|
||||
'title' => 'はじめに',
|
||||
'content' => '本文',
|
||||
]);
|
||||
|
||||
$component = \Livewire\Livewire::test(\App\Livewire\QuickSwitcher::class)
|
||||
->set('search', 'はじめに');
|
||||
|
||||
$results = $component->get('results');
|
||||
$this->assertCount(1, $results);
|
||||
$this->assertSame($doc->id, $results[0]['id']);
|
||||
|
||||
$component2 = \Livewire\Livewire::test(\App\Livewire\QuickSwitcher::class)
|
||||
->set('search', 'Getting');
|
||||
$results2 = $component2->get('results');
|
||||
$this->assertCount(1, $results2);
|
||||
$this->assertSame($doc->id, $results2[0]['id']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user