|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace NovaEntitySelectField\Http\Controllers; |
|
4
|
|
|
|
|
5
|
|
|
use Illuminate\Database\Eloquent\Model; |
|
6
|
|
|
use Illuminate\Support\Facades\Response; |
|
7
|
|
|
use Laravel\Nova\Http\Requests\NovaRequest; |
|
8
|
|
|
use Laravel\Nova\Nova; |
|
9
|
|
|
use Laravel\Nova\Resource; |
|
10
|
|
|
|
|
11
|
|
|
class AutocompleteController extends Controller |
|
12
|
|
|
{ |
|
13
|
6 |
|
public function __invoke(NovaRequest $request) |
|
14
|
|
|
{ |
|
15
|
6 |
|
$searchKeyword = $request->input('search'); |
|
16
|
|
|
// TODO: currently limit we pass via requests as we have not field by attribute |
|
17
|
6 |
|
$limit = $request->integer('limit') ?: 20; |
|
18
|
6 |
|
$currentEntityId = $request->input('current'); |
|
19
|
6 |
|
$entityResourceKey = $request->input('entityResourceKey'); |
|
20
|
6 |
|
$withTrashed = $request->boolean('withTrashed'); |
|
21
|
|
|
|
|
22
|
6 |
|
throw_if(!$entityResourceKey, __('entityResourceKey is required.')); |
|
23
|
|
|
|
|
24
|
|
|
/** @var class-string<Resource>|Resource $resourceClass */ |
|
25
|
6 |
|
$resourceClass = Nova::authorizedResources($request) |
|
26
|
6 |
|
->filter(fn ($resource) => $resource::uriKey() == $entityResourceKey) |
|
27
|
6 |
|
->first(); |
|
28
|
6 |
|
throw_if(!$resourceClass, __("Resource for key [{$entityResourceKey}] not found")); |
|
29
|
|
|
|
|
30
|
|
|
/** @var Model $model */ |
|
31
|
6 |
|
$model = $resourceClass::newModel(); |
|
32
|
6 |
|
$idColumn = $model->getKeyName(); |
|
33
|
6 |
|
$titleColumn = $resourceClass::$title; |
|
34
|
|
|
|
|
35
|
6 |
|
$builder = $resourceClass::buildIndexQuery($request, $model::query(), $searchKeyword, withTrashed: $withTrashed); |
|
36
|
|
|
|
|
37
|
6 |
|
$currentEntities = null; |
|
38
|
6 |
|
if ($currentEntityId) { |
|
39
|
3 |
|
$currentEntities = $model::query()->whereKey($currentEntityId)->get(); |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
6 |
|
$builder->limit($limit); |
|
43
|
|
|
|
|
44
|
6 |
|
$items = $builder->get(); |
|
45
|
|
|
|
|
46
|
6 |
|
if ($currentEntities?->isNotEmpty()) { |
|
47
|
3 |
|
foreach ($currentEntities as $currentEntity) { |
|
48
|
3 |
|
$items->prepend($currentEntity); |
|
49
|
|
|
} |
|
50
|
3 |
|
$items = $items->unique($idColumn); |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
|
|
54
|
6 |
|
return Response::json([ |
|
55
|
6 |
|
'resources' => |
|
56
|
6 |
|
$items->map(function (Model $row) use ($resourceClass, $idColumn, $titleColumn) { |
|
57
|
5 |
|
$resource = new $resourceClass($row); |
|
58
|
5 |
|
$avatar = $resource->resolveAvatarField(app(NovaRequest::class)); |
|
59
|
|
|
|
|
60
|
5 |
|
if (!is_null($avatar)) { |
|
61
|
5 |
|
$avatar = $avatar->resolveThumbnailUrl(); |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
5 |
|
return [ |
|
65
|
5 |
|
'value' => $row->$idColumn, |
|
66
|
5 |
|
'display' => $row->$titleColumn, |
|
67
|
5 |
|
'avatar' => $avatar ?: null, |
|
68
|
5 |
|
'subtitle' => $resource->subtitle(), |
|
69
|
5 |
|
]; |
|
70
|
6 |
|
})->all(), |
|
71
|
6 |
|
'withTrashed' => $withTrashed, |
|
72
|
6 |
|
]); |
|
73
|
|
|
} |
|
74
|
|
|
} |
|
75
|
|
|
|