diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index 363e43c..d8fd46c 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -8,5 +8,3 @@ parameters:
tmpDir: build/phpstan
checkOctaneCompatibility: true
checkModelProperties: true
- checkMissingIterableValueType: false
-
diff --git a/resources/views/livewire/resource-picker.blade.php b/resources/views/livewire/resource-picker.blade.php
index e1287fb..ccb1500 100644
--- a/resources/views/livewire/resource-picker.blade.php
+++ b/resources/views/livewire/resource-picker.blade.php
@@ -45,6 +45,23 @@ class="block w-full transition text-sm py-1 !ps-8 !pe-3 duration-75 border-none
+ @if(!empty($relationFilters))
+ @foreach($relationFilters as $relation => $filters)
+
+
Filter by {{ $relation }}
+
+ @foreach($filters as $filter)
+
+ {{ $filter['name'] }}
+
+ @endforeach
+
+
+ @endforeach
+ @endif
@endif
diff --git a/src/Livewire/ResourcePicker.php b/src/Livewire/ResourcePicker.php
index 4795ddc..9475257 100644
--- a/src/Livewire/ResourcePicker.php
+++ b/src/Livewire/ResourcePicker.php
@@ -32,8 +32,12 @@ class ResourcePicker extends Component
public ?int $maxItems = null;
+ public ?array $relationFilters = null;
+
public string $search = '';
+ public array $selectedRelations = [];
+
public function mount(
string $resourceClass,
string $displayType,
@@ -46,6 +50,7 @@ public function mount(
int $gridColumns,
?int $minItems = null,
?int $maxItems = null,
+ ?array $relationFilters = null,
) {
$this->resourceClass = $resourceClass;
$this->displayType = $displayType;
@@ -58,6 +63,7 @@ public function mount(
$this->gridColumns = $gridColumns;
$this->minItems = $minItems;
$this->maxItems = $maxItems;
+ $this->relationFilters = $relationFilters;
$this->items = $this->getItems();
}
@@ -73,6 +79,7 @@ public function render()
public function getItems(int $offset = 0)
{
return ResourceQuery::get($this->resourceClass, $this->search)
+ ->tap(fn ($query) => $this->searchRelations($query))
->latest()
->offset($offset)
->limit(24)
@@ -82,6 +89,7 @@ public function getItems(int $offset = 0)
public function getItemCount()
{
return ResourceQuery::get($this->resourceClass, $this->search)
+ ->tap(fn ($query) => $this->searchRelations($query))
->count();
}
@@ -97,4 +105,49 @@ public function updatedSearch(): void
{
$this->items = $this->getItems();
}
+
+ public function toggleRelation($relation, $id): void
+ {
+ $this->setSelectedRelation($relation, $id);
+
+ $this->items = $this->getItems();
+ }
+
+ protected function searchRelations($query)
+ {
+ return collect($this->relationFilters)->each(function ($filters, $relation) use ($query) {
+ if (! empty($this->getSelectedRelations($relation))) {
+ $query->whereHas($relation, function ($q) use ($relation) {
+ $q->whereIn('id', $this->getSelectedRelations($relation));
+ });
+ }
+ });
+ }
+
+ protected function setSelectedRelation($relation, $id): void
+ {
+ if (! array_key_exists($relation, $this->selectedRelations)) {
+ $this->selectedRelations[$relation][] = $id;
+
+ return;
+ }
+
+ if (! in_array($id, $this->selectedRelations[$relation])) {
+ $this->selectedRelations[$relation][] = $id;
+
+ return;
+ }
+
+ $this->selectedRelations[$relation] = array_diff($this->selectedRelations[$relation], [$id]);
+ }
+
+ protected function getSelectedRelations($relation)
+ {
+ return $this->selectedRelations[$relation] ?? [];
+ }
+
+ public function isRelationFilterActive($relation, $id): bool
+ {
+ return in_array($id, $this->getSelectedRelations($relation));
+ }
}