search)) { return Document::select('id', 'title', 'slug', 'path', 'updated_at') ->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検索を使用(日本語対応) $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; } public function updated($propertyName) { if ($propertyName === 'search') { $this->selectedIndex = 0; } } public function selectNext() { $results = $this->results; if ($this->selectedIndex < count($results) - 1) { $this->selectedIndex++; } } public function selectPrevious() { if ($this->selectedIndex > 0) { $this->selectedIndex--; } } public function selectDocument() { $results = $this->results; if (isset($results[$this->selectedIndex])) { $document = $results[$this->selectedIndex]; // id が存在することを確認 if (!empty($document['id'])) { return $this->redirect(route('documents.show', $document['id'])); } } } public function render() { return view('livewire.quick-switcher'); } }