Add nested group filter
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
58756b6094
commit
884ad31086
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Member\Data;
|
||||||
|
|
||||||
|
use App\Group;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
use Spatie\LaravelData\DataCollection;
|
||||||
|
|
||||||
|
class NestedGroup extends Data
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public int $id,
|
||||||
|
public string $name,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, array{name: string, id: int}>
|
||||||
|
*/
|
||||||
|
public static function forSelect(?int $parentId = null, int $level = 0): Collection
|
||||||
|
{
|
||||||
|
$groups = collect([]);
|
||||||
|
|
||||||
|
foreach (Group::where('parent_id', $parentId)->orderBy('name')->get()->toBase() as $group) {
|
||||||
|
$groups->push(['name' => str_repeat('- ', $level).$group->name, 'id' => $group->id]);
|
||||||
|
$groups = $groups->merge(static::forSelect($group->id, $level + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DataCollection<int, static>
|
||||||
|
*/
|
||||||
|
public static function cacheForSelect(): DataCollection
|
||||||
|
{
|
||||||
|
return static::collection(static::forSelect());
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ class FilterScope extends Filter
|
||||||
public ?int $activityId = null,
|
public ?int $activityId = null,
|
||||||
public ?int $subactivityId = null,
|
public ?int $subactivityId = null,
|
||||||
public string $search = '',
|
public string $search = '',
|
||||||
|
public ?int $groupId = null,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +48,11 @@ class FilterScope extends Filter
|
||||||
if ($this->billKind) {
|
if ($this->billKind) {
|
||||||
$query->where('bill_kind', BillKind::fromValue($this->billKind));
|
$query->where('bill_kind', BillKind::fromValue($this->billKind));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->groupId) {
|
||||||
|
$query->where('group_id', $this->groupId);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->subactivityId || $this->activityId) {
|
if ($this->subactivityId || $this->activityId) {
|
||||||
$query->whereHas('memberships', function ($q) {
|
$query->whereHas('memberships', function ($q) {
|
||||||
$q->active();
|
$q->active();
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
namespace App\Member;
|
namespace App\Member;
|
||||||
|
|
||||||
use App\Course\Resources\CourseMemberResource;
|
use App\Course\Resources\CourseMemberResource;
|
||||||
use App\Group;
|
|
||||||
use App\Lib\HasMeta;
|
use App\Lib\HasMeta;
|
||||||
|
use App\Member\Data\NestedGroup;
|
||||||
use App\Member\Resources\NationalityResource;
|
use App\Member\Resources\NationalityResource;
|
||||||
use App\Member\Resources\RegionResource;
|
use App\Member\Resources\RegionResource;
|
||||||
use App\Membership\MembershipResource;
|
use App\Membership\MembershipResource;
|
||||||
|
@ -104,7 +104,7 @@ class MemberResource extends JsonResource
|
||||||
public static function meta(): array
|
public static function meta(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'groups' => Group::select('name', 'id')->get(),
|
'groups' => NestedGroup::cacheForSelect(),
|
||||||
'filter' => FilterScope::fromRequest(request()->input('filter', '')),
|
'filter' => FilterScope::fromRequest(request()->input('filter', '')),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<div class="px-6 py-2 flex border-b border-gray-600 items-center space-x-3">
|
<div class="px-6 py-2 flex border-b border-gray-600 items-center space-x-3">
|
||||||
<f-text :value="getFilter('search')" @input="setFilter('search', $event)" id="search" name="search" label="Suchen …" size="sm"></f-text>
|
<f-text :value="getFilter('search')" @input="setFilter('search', $event)" id="search" name="search" label="Suchen …" size="sm"></f-text>
|
||||||
<f-switch v-show="hasModule('bill')" id="ausstand" @input="setFilter('ausstand', $event)" :items="getFilter('ausstand')" label="Nur Ausstände" size="sm"></f-switch>
|
<f-switch v-show="hasModule('bill')" id="ausstand" @input="setFilter('ausstand', $event)" :items="getFilter('ausstand')" label="Nur Ausstände" size="sm"></f-switch>
|
||||||
|
<f-select id="group_id" @input="setFilter('group_id', $event)" :options="data.meta.groups" :value="getFilter('group_id')" label="Gruppierung" size="sm" name="group_id"></f-select>
|
||||||
<f-select
|
<f-select
|
||||||
v-show="hasModule('bill')"
|
v-show="hasModule('bill')"
|
||||||
name="billKinds"
|
name="billKinds"
|
||||||
|
|
|
@ -184,6 +184,23 @@ class IndexTest extends TestCase
|
||||||
$this->assertInertiaHas('E-Mail', $emailResponse, 'data.meta.filter.bill_kind');
|
$this->assertInertiaHas('E-Mail', $emailResponse, 'data.meta.filter.bill_kind');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testItCanFilterForGroups(): void
|
||||||
|
{
|
||||||
|
$this->withoutExceptionHandling()->login()->loginNami();
|
||||||
|
$group1 = Group::factory()->create();
|
||||||
|
$group2 = Group::factory()->create();
|
||||||
|
Member::factory()->defaults()->for($group1)->create();
|
||||||
|
Member::factory()->defaults()->for($group1)->create();
|
||||||
|
Member::factory()->defaults()->for($group1)->create();
|
||||||
|
|
||||||
|
$oneResponse = $this->callFilter('member.index', ['group_id' => $group1->id]);
|
||||||
|
$twoResponse = $this->callFilter('member.index', ['group_id' => $group2->id]);
|
||||||
|
|
||||||
|
$this->assertCount(3, $this->inertia($oneResponse, 'data.data'));
|
||||||
|
$this->assertCount(0, $this->inertia($twoResponse, 'data.data'));
|
||||||
|
$this->assertInertiaHas($group1->id, $oneResponse, 'data.meta.filter.group_id');
|
||||||
|
}
|
||||||
|
|
||||||
public function testItFiltersForAusstand(): void
|
public function testItFiltersForAusstand(): void
|
||||||
{
|
{
|
||||||
$this->withoutExceptionHandling()->login()->loginNami();
|
$this->withoutExceptionHandling()->login()->loginNami();
|
||||||
|
@ -213,11 +230,17 @@ class IndexTest extends TestCase
|
||||||
|
|
||||||
public function testItLoadsGroups(): void
|
public function testItLoadsGroups(): void
|
||||||
{
|
{
|
||||||
$this->withoutExceptionHandling()->login()->loginNami();
|
$parent1 = Group::factory()->name('par1')->create();
|
||||||
Group::factory()->name('UUI')->create();
|
$child1 = Group::factory()->name('ch1')->for($parent1, 'parent')->create();
|
||||||
|
$child2 = Group::factory()->name('ch2')->for($parent1, 'parent')->create();
|
||||||
|
$parent2 = Group::factory()->name('par2')->create();
|
||||||
|
$this->withoutExceptionHandling()->login()->loginNami(12345, 'password', $parent1);
|
||||||
|
|
||||||
$response = $this->get('/member');
|
$response = $this->get('/member');
|
||||||
|
|
||||||
$this->assertInertiaHas('UUI', $response, 'data.meta.groups.1.name');
|
$this->assertInertiaHas('par1', $response, 'data.meta.groups.0.name');
|
||||||
|
$this->assertInertiaHas('- ch1', $response, 'data.meta.groups.1.name');
|
||||||
|
$this->assertInertiaHas('- ch2', $response, 'data.meta.groups.2.name');
|
||||||
|
$this->assertInertiaHas('par2', $response, 'data.meta.groups.3.name');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,14 @@ abstract class TestCase extends BaseTestCase
|
||||||
Auth::fake();
|
Auth::fake();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loginNami(int $mglnr = 12345, string $password = 'password', int $groupId = 55): self
|
public function loginNami(int $mglnr = 12345, string $password = 'password', int|Group $groupId = 55): self
|
||||||
{
|
{
|
||||||
Auth::success($mglnr, $password);
|
Auth::success($mglnr, $password);
|
||||||
$this->withNamiSettings($mglnr, $password, $groupId);
|
$group = is_int($groupId)
|
||||||
Group::factory()->create(['nami_id' => $groupId]);
|
? Group::factory()->create(['nami_id' => $groupId])
|
||||||
|
: $groupId;
|
||||||
|
|
||||||
|
$this->withNamiSettings($mglnr, $password, $group->id);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue