Add membership view
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
6da6453b5d
commit
6032b9c289
|
@ -54,6 +54,7 @@ class ActivityResource extends JsonResource
|
||||||
'index' => route('activity.index'),
|
'index' => route('activity.index'),
|
||||||
'create' => route('activity.create'),
|
'create' => route('activity.create'),
|
||||||
'membership_masslist' => route('membership.masslist.index'),
|
'membership_masslist' => route('membership.masslist.index'),
|
||||||
|
'membership_index' => route('membership.index'),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ namespace App\Invoice\Scopes;
|
||||||
|
|
||||||
use App\Invoice\Enums\InvoiceStatus;
|
use App\Invoice\Enums\InvoiceStatus;
|
||||||
use App\Invoice\Models\Invoice;
|
use App\Invoice\Models\Invoice;
|
||||||
use App\Lib\Filter;
|
|
||||||
use App\Lib\ScoutFilter;
|
use App\Lib\ScoutFilter;
|
||||||
use Laravel\Scout\Builder;
|
use Laravel\Scout\Builder;
|
||||||
use Spatie\LaravelData\Attributes\MapInputName;
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
|
|
|
@ -14,10 +14,12 @@ abstract class Filter extends Data
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Builder<T> $query
|
|
||||||
* @return Builder<T>
|
* @return Builder<T>
|
||||||
*/
|
*/
|
||||||
abstract public function apply(Builder $query): Builder;
|
abstract public function getQuery(): Builder;
|
||||||
|
|
||||||
|
/** @var Builder<T> */
|
||||||
|
protected Builder $query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed>|string|null $request
|
* @param array<string, mixed>|string|null $request
|
||||||
|
@ -36,14 +38,6 @@ abstract class Filter extends Data
|
||||||
*/
|
*/
|
||||||
public static function fromPost(?array $post = null): static
|
public static function fromPost(?array $post = null): static
|
||||||
{
|
{
|
||||||
return static::factory()->withoutMagicalCreation()->from($post ?: [])->toDefault();
|
return static::factory()->withoutMagicalCreation()->from($post ?: []);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return static
|
|
||||||
*/
|
|
||||||
public function toDefault(): self
|
|
||||||
{
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace App\Lib;
|
namespace App\Lib;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\PaginatedDataCollection;
|
||||||
|
|
||||||
/** @mixin \Illuminate\Http\Resources\Json\JsonResource */
|
/** @mixin \Illuminate\Http\Resources\Json\JsonResource */
|
||||||
trait HasMeta
|
trait HasMeta
|
||||||
{
|
{
|
||||||
|
@ -41,4 +43,12 @@ trait HasMeta
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function collectPages(mixed $items): array {
|
||||||
|
$source = parent::collect($items, PaginatedDataCollection::class)->toArray();
|
||||||
|
return [
|
||||||
|
...parent::collect($items, PaginatedDataCollection::class)->toArray(),
|
||||||
|
'meta' => [...$source['meta'], ...static::meta()]
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Member\Data;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\Data;
|
||||||
|
use App\Member\Member;
|
||||||
|
|
||||||
|
class MemberData extends Data
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
public string $fullname,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public static function fromModel(Member $member): static
|
||||||
|
{
|
||||||
|
return static::factory()->withoutMagicalCreation()->from([
|
||||||
|
'fullname' => $member->fullname
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,14 +2,21 @@
|
||||||
|
|
||||||
namespace App\Member\Data;
|
namespace App\Member\Data;
|
||||||
|
|
||||||
|
use App\Activity;
|
||||||
|
use App\Group;
|
||||||
use Spatie\LaravelData\Data;
|
use Spatie\LaravelData\Data;
|
||||||
use App\Lib\Data\DateData;
|
use App\Lib\Data\DateData;
|
||||||
use App\Lib\Data\RecordData;
|
use App\Lib\Data\RecordData;
|
||||||
|
use App\Lib\HasMeta;
|
||||||
use App\Member\Membership;
|
use App\Member\Membership;
|
||||||
|
use App\Membership\FilterScope;
|
||||||
|
use App\Subactivity;
|
||||||
|
|
||||||
class MembershipData extends Data
|
class MembershipData extends Data
|
||||||
{
|
{
|
||||||
|
|
||||||
|
use HasMeta;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public int $id,
|
public int $id,
|
||||||
public RecordData $activity,
|
public RecordData $activity,
|
||||||
|
@ -17,6 +24,8 @@ class MembershipData extends Data
|
||||||
public RecordData $group,
|
public RecordData $group,
|
||||||
public ?DateData $promisedAt,
|
public ?DateData $promisedAt,
|
||||||
public DateData $from,
|
public DateData $from,
|
||||||
|
public ?DateData $to,
|
||||||
|
public MemberData $member,
|
||||||
public bool $isActive,
|
public bool $isActive,
|
||||||
public array $links,
|
public array $links,
|
||||||
) {}
|
) {}
|
||||||
|
@ -29,8 +38,10 @@ class MembershipData extends Data
|
||||||
'subactivity' => $membership->subactivity,
|
'subactivity' => $membership->subactivity,
|
||||||
'isActive' => $membership->isActive(),
|
'isActive' => $membership->isActive(),
|
||||||
'from' => $membership->from,
|
'from' => $membership->from,
|
||||||
|
'to' => $membership->to,
|
||||||
'group' => $membership->group,
|
'group' => $membership->group,
|
||||||
'promisedAt' => $membership->promised_at,
|
'promisedAt' => $membership->promised_at,
|
||||||
|
'member' => $membership->member,
|
||||||
'links' => [
|
'links' => [
|
||||||
'update' => route('membership.update', $membership),
|
'update' => route('membership.update', $membership),
|
||||||
'destroy' => route('membership.destroy', $membership),
|
'destroy' => route('membership.destroy', $membership),
|
||||||
|
@ -38,4 +49,13 @@ class MembershipData extends Data
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function meta(): array {
|
||||||
|
return [
|
||||||
|
'activities' => RecordData::collect(Activity::get()),
|
||||||
|
'subactivities' => RecordData::collect(Subactivity::get()),
|
||||||
|
'groups' => RecordData::collect(Group::get()),
|
||||||
|
'filter' => FilterScope::fromRequest(request()->input('filter', '')),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,19 @@ class Membership extends Model
|
||||||
->where(fn ($query) => $query->whereNull('to')->orWhere('to', '>=', now()));
|
->where(fn ($query) => $query->whereNull('to')->orWhere('to', '>=', now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Builder<Membership> $query
|
||||||
|
*
|
||||||
|
* @return Builder<Membership>
|
||||||
|
*/
|
||||||
|
public function scopeInactive(Builder $query): Builder
|
||||||
|
{
|
||||||
|
return $query->where(fn ($q) => $q
|
||||||
|
->orWhere('from', '>=', now())
|
||||||
|
->orWhere('to', '<=', now())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Builder<Membership> $query
|
* @param Builder<Membership> $query
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,21 +3,21 @@
|
||||||
namespace App\Membership\Actions;
|
namespace App\Membership\Actions;
|
||||||
|
|
||||||
use App\Member\Data\MembershipData;
|
use App\Member\Data\MembershipData;
|
||||||
use App\Member\Membership;
|
use App\Membership\FilterScope;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
use Inertia\Response;
|
use Inertia\Response;
|
||||||
|
use Lorisleiva\Actions\ActionRequest;
|
||||||
use Lorisleiva\Actions\Concerns\AsAction;
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
use Spatie\LaravelData\PaginatedDataCollection;
|
|
||||||
|
|
||||||
class MembershipIndexAction
|
class MembershipIndexAction
|
||||||
{
|
{
|
||||||
use AsAction;
|
use AsAction;
|
||||||
|
|
||||||
public function asController(): Response
|
public function asController(ActionRequest $request): Response
|
||||||
{
|
{
|
||||||
return Inertia::render(
|
return Inertia::render(
|
||||||
'membership/Index',
|
'membership/Index',
|
||||||
MembershipData::collect(Membership::orderByRaw('member_id, activity_id, subactivity_id')->paginate(20), PaginatedDataCollection::class)->wrap('data')
|
['data' => MembershipData::collectPages(FilterScope::fromRequest($request->input('filter', ''))->getQuery()->paginate(20))]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Membership;
|
||||||
|
|
||||||
|
use App\Lib\Filter;
|
||||||
|
use App\Member\Membership;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Filter<Membership>
|
||||||
|
*/
|
||||||
|
class FilterScope extends Filter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<int, int> $activities
|
||||||
|
* @param array<int, int> $subactivities
|
||||||
|
* @param array<int, int> $groups
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public array $activities = [],
|
||||||
|
public array $subactivities = [],
|
||||||
|
public array $groups = [],
|
||||||
|
public ?bool $active = true,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function getQuery(): Builder
|
||||||
|
{
|
||||||
|
$query = (new Membership())->newQuery();
|
||||||
|
|
||||||
|
if ($this->active === true) {
|
||||||
|
$query = $query->active();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->active === false) {
|
||||||
|
$query = $query->inactive();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->groups)) {
|
||||||
|
$query = $query->whereIn('group_id', $this->groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->activities)) {
|
||||||
|
$query = $query->whereIn('activity_id', $this->activities);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($this->subactivities)) {
|
||||||
|
$query = $query->whereIn('subactivity_id', $this->subactivities);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ namespace Database\Factories\Member;
|
||||||
|
|
||||||
use App\Activity;
|
use App\Activity;
|
||||||
use App\Group;
|
use App\Group;
|
||||||
|
use App\Member\Member;
|
||||||
use App\Member\Membership;
|
use App\Member\Membership;
|
||||||
use App\Subactivity;
|
use App\Subactivity;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
@ -30,6 +31,10 @@ class MembershipFactory extends Factory
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function defaults(): self {
|
||||||
|
return $this->for(Member::factory()->defaults())->for(Group::factory())->for(Activity::factory())->for(Subactivity::factory());
|
||||||
|
}
|
||||||
|
|
||||||
public function inNami(int $namiId): self
|
public function inNami(int $namiId): self
|
||||||
{
|
{
|
||||||
return $this->state(['nami_id' => $namiId]);
|
return $this->state(['nami_id' => $namiId]);
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<label class="flex flex-col group" :for="id" :class="sizeClass(size)">
|
<label class="flex flex-col group" :for="id" :class="sizeClass(size)">
|
||||||
<f-label v-if="label" :required="false" :value="label"></f-label>
|
<f-label v-if="label" :required="false" :value="label" />
|
||||||
<div class="relative flex-none flex">
|
<div class="relative flex-none flex">
|
||||||
<div
|
<div :class="[fieldHeight, fieldAppearance, selectAppearance]"
|
||||||
:class="[fieldHeight, fieldAppearance, selectAppearance]"
|
|
||||||
class="form-select flex items-center w-full"
|
class="form-select flex items-center w-full"
|
||||||
@click="visible = !visible"
|
@click="visible = !visible"
|
||||||
v-text="`${modelValue.length} Einträge ausgewählt`"
|
v-text="`${modelValue.length} Einträge ausgewählt`"
|
||||||
></div>
|
/>
|
||||||
<div v-show="visible" class="absolute w-[max-content] z-30 max-h-[25rem] overflow-auto shadow-lg bg-gray-600 border border-gray-500 rounded-lg p-2 top-7 space-y-1">
|
<div v-show="visible" class="absolute w-[max-content] z-30 max-h-[25rem] overflow-auto shadow-lg bg-gray-600 border border-gray-500 rounded-lg p-2 top-7 space-y-1 mt-2">
|
||||||
<div v-for="(option, index) in parsedOptions" :key="index" class="flex items-center space-x-2">
|
<div v-for="(option, index) in parsedOptions" :key="index" class="flex items-center space-x-2">
|
||||||
<f-switch
|
<f-switch :id="`${id}-${index}`"
|
||||||
:id="`${id}-${index}`"
|
|
||||||
:name="`${id}-${index}`"
|
:name="`${id}-${index}`"
|
||||||
size="sm"
|
size="sm"
|
||||||
:model-value="modelValue.includes(option.id)"
|
:model-value="modelValue.includes(option.id)"
|
||||||
:value="option.id"
|
:value="option.id"
|
||||||
@update:modelValue="trigger(option, $event)"
|
@update:model-value="trigger(option, $event)"
|
||||||
></f-switch>
|
/>
|
||||||
<div class="text-sm text-gray-200" v-text="option.name"></div>
|
<div class="text-sm text-gray-200" v-text="option.name" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -66,7 +64,7 @@ const parsedOptions = computed(() =>
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
function trigger(option, v) {
|
function trigger(option, v) {
|
||||||
var value = JSON.parse(JSON.stringify(props.modelValue));
|
const value = JSON.parse(JSON.stringify(props.modelValue));
|
||||||
|
|
||||||
emit('update:modelValue', value.includes(option.id) ? value.filter((cv) => cv !== option.id) : [...value, option.id]);
|
emit('update:modelValue', value.includes(option.id) ? value.filter((cv) => cv !== option.id) : [...value, option.id]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<template #toolbar>
|
<template #toolbar>
|
||||||
<page-toolbar-button :href="meta.links.create" color="primary" icon="plus">Tätigkeit erstellen</page-toolbar-button>
|
<page-toolbar-button :href="meta.links.create" color="primary" icon="plus">Tätigkeit erstellen</page-toolbar-button>
|
||||||
<page-toolbar-button :href="meta.links.membership_masslist" color="primary" icon="pencil">Mitgliedschaften zuweisen</page-toolbar-button>
|
<page-toolbar-button :href="meta.links.membership_masslist" color="primary" icon="pencil">Mitgliedschaften zuweisen</page-toolbar-button>
|
||||||
|
<page-toolbar-button :href="meta.links.membership_index" color="primary" icon="eye">Mitgliedschaften anschauen</page-toolbar-button>
|
||||||
</template>
|
</template>
|
||||||
<ui-popup v-if="deleting !== null" heading="Bitte bestätigen" @close="deleting = null">
|
<ui-popup v-if="deleting !== null" heading="Bitte bestätigen" @close="deleting = null">
|
||||||
<div>
|
<div>
|
||||||
|
@ -16,22 +17,22 @@
|
||||||
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm table">
|
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm table">
|
||||||
<thead>
|
<thead>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th></th>
|
<th />
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tr v-for="(activity, index) in data" :key="index">
|
<tr v-for="(activity, index) in data" :key="index">
|
||||||
<td v-text="activity.name"></td>
|
<td v-text="activity.name" />
|
||||||
<td>
|
<td>
|
||||||
<div class="flex space-x-1">
|
<div class="flex space-x-1">
|
||||||
<i-link v-tooltip="`Bearbeiten`" :href="activity.links.edit" class="inline-flex btn btn-warning btn-sm"><ui-sprite src="pencil"></ui-sprite></i-link>
|
<i-link v-tooltip="`Bearbeiten`" :href="activity.links.edit" class="inline-flex btn btn-warning btn-sm"><ui-sprite src="pencil" /></i-link>
|
||||||
<a v-tooltip="`Entfernen`" href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="deleting = activity"><ui-sprite src="trash"></ui-sprite></a>
|
<a v-tooltip="`Entfernen`" href="#" class="inline-flex btn btn-danger btn-sm" @click.prevent="deleting = activity"><ui-sprite src="trash" /></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="px-6">
|
<div class="px-6">
|
||||||
<ui-pagination class="mt-4" :value="meta" :only="['data']"></ui-pagination>
|
<ui-pagination class="mt-4" :value="meta" :only="['data']" />
|
||||||
</div>
|
</div>
|
||||||
</page-layout>
|
</page-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<template>
|
||||||
|
<page-layout>
|
||||||
|
<page-filter>
|
||||||
|
<template #fields>
|
||||||
|
<f-multipleselect id="groups"
|
||||||
|
:model-value="getFilter('groups')"
|
||||||
|
:options="meta.groups"
|
||||||
|
label="Gruppen"
|
||||||
|
name="groups"
|
||||||
|
@update:model-value="setFilter('groups', $event)"
|
||||||
|
/>
|
||||||
|
<f-multipleselect id="activities"
|
||||||
|
:model-value="getFilter('activities')"
|
||||||
|
:options="meta.activities"
|
||||||
|
label="Tätigkeiten"
|
||||||
|
name="activities"
|
||||||
|
@update:model-value="setFilter('activities', $event)"
|
||||||
|
/>
|
||||||
|
<f-multipleselect id="subactivities"
|
||||||
|
:model-value="getFilter('subactivities')"
|
||||||
|
:options="meta.subactivities"
|
||||||
|
label="Untertätigkeiten"
|
||||||
|
name="subactivities"
|
||||||
|
@update:model-value="setFilter('subactivities', $event)"
|
||||||
|
/>
|
||||||
|
<f-select id="active"
|
||||||
|
:options="[{id: true, name: 'nur aktive'}, {id: false, name: 'nur inaktive'}]"
|
||||||
|
:model-value="getFilter('active')"
|
||||||
|
label="Aktiv"
|
||||||
|
name="active"
|
||||||
|
@update:model-value="setFilter('active', $event)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</page-filter>
|
||||||
|
<div class="flex space-x-3" />
|
||||||
|
<table cellspacing="0" cellpadding="0" border="0" class="custom-table custom-table-sm table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Gruppierung</th>
|
||||||
|
<th>Tätigkeit</th>
|
||||||
|
<th>Untertätigkeit</th>
|
||||||
|
<th>Beginn</th>
|
||||||
|
<th>Ende</th>
|
||||||
|
<th>Aktiv</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(membership, index) in data" :key="index">
|
||||||
|
<td v-text="membership.member.fullname" />
|
||||||
|
<td v-text="membership.group.name" />
|
||||||
|
<td v-text="membership.activity.name" />
|
||||||
|
<td v-text="membership.subactivity?.name" />
|
||||||
|
<td v-text="membership.from.human" />
|
||||||
|
<td v-text="membership.to?.human" />
|
||||||
|
<td><ui-bool :value="membership.isActive" /></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="px-6">
|
||||||
|
<ui-pagination class="mt-4" :value="meta" :only="['data', 'meta']" />
|
||||||
|
</div>
|
||||||
|
</page-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="js" setup>
|
||||||
|
import {useIndex, indexProps} from '@/composables/useIndex.js';
|
||||||
|
|
||||||
|
const props = defineProps(indexProps);
|
||||||
|
|
||||||
|
const {data, meta, getFilter, setFilter} = useIndex(props.data, 'memberships');
|
||||||
|
|
||||||
|
</script>
|
|
@ -32,14 +32,45 @@ it('lists memberships of users', function () {
|
||||||
$activity->subactivities()->first();
|
$activity->subactivities()->first();
|
||||||
$this->callFilter('membership.index', [])
|
$this->callFilter('membership.index', [])
|
||||||
->assertInertia(fn(Assert $page) => $page
|
->assertInertia(fn(Assert $page) => $page
|
||||||
|
->has('data', 1)
|
||||||
->has('data.0', fn(Assert $page) => $page
|
->has('data.0', fn(Assert $page) => $page
|
||||||
->where('activity.name', 'Act')
|
->where('activity.name', 'Act')
|
||||||
->where('subactivity.name', 'SubAct')
|
->where('subactivity.name', 'SubAct')
|
||||||
|
->where('member.fullname', 'Max Muster')
|
||||||
->where('group.name', 'GG')
|
->where('group.name', 'GG')
|
||||||
->where('promisedAt', null)
|
->where('promisedAt', null)
|
||||||
->where('links.update', route('membership.update', $member->memberships->first()))
|
->where('links.update', route('membership.update', $member->memberships->first()))
|
||||||
->where('links.destroy', route('membership.destroy', $member->memberships->first()))
|
->where('links.destroy', route('membership.destroy', $member->memberships->first()))
|
||||||
->etc()
|
->etc()
|
||||||
|
)->has('meta', fn (Assert $page) => $page
|
||||||
|
->where('current_page', 1)
|
||||||
|
->where('activities.0.name', 'Act')
|
||||||
|
->where('subactivities.0.name', 'SubAct')
|
||||||
|
->where('groups.1.name', 'GG')
|
||||||
|
->where('filter.active', true)
|
||||||
|
->where('filter.groups', [])
|
||||||
|
->where('filter.activities', [])
|
||||||
|
->where('filter.subactivities', [])
|
||||||
|
->etc()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lists end date', function () {
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
$member = Member::factory()->defaults()
|
||||||
|
->has(Membership::factory()->for(Activity::factory())->for(Subactivity::factory())->for(Group::factory())->ended())
|
||||||
|
->male()
|
||||||
|
->name('Max Muster')
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$this->callFilter('membership.index', ['active' => null])
|
||||||
|
->assertInertia(fn(Assert $page) => $page
|
||||||
|
->has('data.0', fn(Assert $page) => $page
|
||||||
|
->where('to.human', now()->subDays(2)->format('d.m.Y'))
|
||||||
|
->where('links.update', route('membership.update', $member->memberships->first()))
|
||||||
|
->where('links.destroy', route('membership.destroy', $member->memberships->first()))
|
||||||
|
->etc()
|
||||||
)->has('meta', fn (Assert $page) => $page
|
)->has('meta', fn (Assert $page) => $page
|
||||||
->where('current_page', 1)
|
->where('current_page', 1)
|
||||||
->etc()
|
->etc()
|
||||||
|
@ -47,3 +78,43 @@ it('lists memberships of users', function () {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('filters for active', function () {
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
Membership::factory()->defaults()->ended()->create();
|
||||||
|
Membership::factory()->defaults()->count(2)->create();
|
||||||
|
|
||||||
|
$this->callFilter('membership.index', [])->assertInertia(fn(Assert $page) => $page->has('data', 2));
|
||||||
|
$this->callFilter('membership.index', ['active' => null])->assertInertia(fn(Assert $page) => $page->has('data', 3));
|
||||||
|
$this->callFilter('membership.index', ['active' => false])->assertInertia(fn(Assert $page) => $page->has('data', 1));
|
||||||
|
$this->callFilter('membership.index', ['active' => true])->assertInertia(fn(Assert $page) => $page->has('data', 2));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters for group', function () {
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
$m1 = Membership::factory()->defaults()->count(2)->create();
|
||||||
|
$m2 = Membership::factory()->defaults()->create();
|
||||||
|
|
||||||
|
$this->callFilter('membership.index', [])->assertInertia(fn(Assert $page) => $page->has('data', 3));
|
||||||
|
$this->callFilter('membership.index', ['groups' => [$m1->first()->group_id]])->assertInertia(fn(Assert $page) => $page->has('data', 2)->where('meta.filter.groups', [$m1->first()->group_id]));
|
||||||
|
$this->callFilter('membership.index', ['groups' => [$m2->group_id]])->assertInertia(fn(Assert $page) => $page->has('data', 1)->where('meta.filter.groups', [$m2->group_id]));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters for activity', function () {
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
$m1 = Membership::factory()->defaults()->count(2)->create();
|
||||||
|
$m2 = Membership::factory()->defaults()->create();
|
||||||
|
|
||||||
|
$this->callFilter('membership.index', [])->assertInertia(fn(Assert $page) => $page->has('data', 3));
|
||||||
|
$this->callFilter('membership.index', ['activities' => [$m1->first()->activity_id]])->assertInertia(fn(Assert $page) => $page->has('data', 2)->where('meta.filter.activities', [$m1->first()->activity_id]));
|
||||||
|
$this->callFilter('membership.index', ['activities' => [$m2->activity_id]])->assertInertia(fn(Assert $page) => $page->has('data', 1)->where('meta.filter.activities', [$m2->activity_id]));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters for subactivity', function () {
|
||||||
|
$this->login()->loginNami()->withoutExceptionHandling();
|
||||||
|
$m1 = Membership::factory()->defaults()->count(2)->create();
|
||||||
|
$m2 = Membership::factory()->defaults()->create();
|
||||||
|
|
||||||
|
$this->callFilter('membership.index', [])->assertInertia(fn(Assert $page) => $page->has('data', 3));
|
||||||
|
$this->callFilter('membership.index', ['subactivities' => [$m1->first()->subactivity_id]])->assertInertia(fn(Assert $page) => $page->has('data', 2)->where('meta.filter.subactivities', [$m1->first()->subactivity_id]));
|
||||||
|
$this->callFilter('membership.index', ['subactivities' => [$m2->subactivity_id]])->assertInertia(fn(Assert $page) => $page->has('data', 1)->where('meta.filter.subactivities', [$m2->subactivity_id]));
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue