Skip to content

Commit 41077ec

Browse files
indigoram89claude
andcommitted
Исправление поиска по дереву
- Добавлен поиск по всему дереву, а не только по корневым элементам - Добавлен поиск без учета регистра (case-insensitive) - При поиске показываются найденные узлы с путями к корню - Найденные элементы подсвечиваются желтым цветом - Исправлена логика поиска для работы с вложенными элементами 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent a1d7c5a commit 41077ec

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

resources/js/nested-set-standalone.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@
136136
emits: ['edit', 'delete'],
137137
template: `
138138
<div class="node-item group">
139-
<div class="flex items-center p-3 bg-white border border-gray-200 rounded-lg hover:shadow-md transition-all duration-200">
139+
<div class="flex items-center p-3 bg-white border border-gray-200 rounded-lg hover:shadow-md transition-all duration-200"
140+
:class="{ 'bg-yellow-50 border-yellow-300': node.highlighted }">
140141
<div class="drag-handle cursor-move mr-3 text-gray-400 hover:text-gray-600">
141142
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
142143
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8h16M4 16h16"></path>
@@ -162,7 +163,7 @@
162163
163164
<div class="flex-1">
164165
<div class="flex items-center">
165-
<span class="font-medium text-gray-800">{{ node.name }}</span>
166+
<span class="font-medium" :class="{ 'text-yellow-900': node.highlighted, 'text-gray-800': !node.highlighted }">{{ node.name }}</span>
166167
<span v-if="node.slug" class="ml-2 text-sm text-gray-500">
167168
({{ node.slug }})
168169
</span>

src/Http/Controllers/NestedSetApiController.php

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,51 @@ public function tree(Request $request, string $model): JsonResponse
3737
}
3838

3939
$query = $model_class::query();
40+
$searchResultIds = collect();
4041

4142
// Поиск
4243
if ($search = $request->get('search')) {
43-
$query->where('name', 'like', "%{$search}%");
44+
// Поиск по имени без учета регистра
45+
$searchResults = $model_class::query()
46+
->whereRaw('LOWER(name) LIKE ?', ['%' . mb_strtolower($search) . '%'])
47+
->get();
48+
49+
if ($searchResults->isEmpty()) {
50+
return response()->json([
51+
'data' => []
52+
]);
53+
}
54+
55+
// Сохраняем ID найденных узлов для подсветки
56+
$searchResultIds = $searchResults->pluck('id');
57+
58+
// Получаем все ID найденных узлов и их предков
59+
$nodeIds = collect();
60+
foreach ($searchResults as $node) {
61+
// Добавляем сам узел
62+
$nodeIds->push($node->id);
63+
64+
// Добавляем всех предков
65+
$ancestors = $model_class::query()
66+
->where('lft', '<', $node->lft)
67+
->where('rgt', '>', $node->rgt)
68+
->pluck('id');
69+
70+
$nodeIds = $nodeIds->merge($ancestors);
71+
}
72+
73+
// Получаем только нужные узлы
74+
$items = $model_class::query()
75+
->whereIn('id', $nodeIds->unique())
76+
->orderBy('lft')
77+
->get();
78+
} else {
79+
// Без поиска - возвращаем всё дерево
80+
$items = $query->orderBy('lft')->get();
4481
}
4582

46-
$items = $query->orderBy('lft')->get();
47-
4883
// Построение дерева
49-
$tree = $this->buildTree($items);
84+
$tree = $this->buildTree($items, null, $searchResultIds);
5085

5186
return response()->json([
5287
'data' => $tree
@@ -331,7 +366,7 @@ protected function processReorderItems(array $items, ?int $parent_id, string $mo
331366
/**
332367
* Построить дерево из плоского списка
333368
*/
334-
protected function buildTree($items, $parent_id = null): array
369+
protected function buildTree($items, $parent_id = null, $searchResultIds = null): array
335370
{
336371
$tree = [];
337372

@@ -350,7 +385,12 @@ protected function buildTree($items, $parent_id = null): array
350385
'expanded' => true, // По умолчанию раскрываем все узлы
351386
];
352387

353-
$children = $this->buildTree($items, $item->id);
388+
// Помечаем найденные элементы
389+
if ($searchResultIds && $searchResultIds->contains($item->id)) {
390+
$node['highlighted'] = true;
391+
}
392+
393+
$children = $this->buildTree($items, $item->id, $searchResultIds);
354394
if (!empty($children)) {
355395
$node['children'] = $children;
356396
}

0 commit comments

Comments
 (0)