Move member filter to separate component

This commit is contained in:
philipp lang 2025-05-29 22:17:50 +02:00
parent f33a23ecc3
commit 27f805700e
5 changed files with 137 additions and 87 deletions

View File

@ -48,8 +48,7 @@ class FilterScope extends ScoutFilter
public ?bool $hasBirthday = null,
public ?bool $hasSvk = null,
public ?bool $hasVk = null,
) {
}
) {}
/**
* @param array<string, mixed> $options

View File

@ -136,8 +136,8 @@ class MemberResource extends JsonResource
$createActivities = Activity::remote()->with(['subactivities' => fn($q) => $q->remote()])->get();
return [
'filterActivities' => Activity::where('is_filterable', true)->pluck('name', 'id'),
'filterSubactivities' => Subactivity::where('is_filterable', true)->pluck('name', 'id'),
'filterActivities' => Activity::where('is_filterable', true)->get()->map(fn($a) => ['id' => $a->id, 'name' => $a->name]),
'filterSubactivities' => Subactivity::where('is_filterable', true)->get()->map(fn($a) => ['id' => $a->id, 'name' => $a->name]),
'formActivities' => $activities->pluck('name', 'id'),
'formSubactivities' => $activities->map(function (Activity $activity) {
return ['subactivities' => $activity->subactivities->pluck('name', 'id'), 'id' => $activity->id];

View File

@ -56,6 +56,11 @@ export function useIndex(props, siteName) {
reload(true);
}
function setFilterObject(o) {
inner.filter.value = o;
reload(true);
}
startListener();
onBeforeUnmount(() => stopListener());
@ -70,6 +75,8 @@ export function useIndex(props, siteName) {
toFilterString,
reloadPage,
axios,
filter: inner.filter,
setFilterObject,
};
}

View File

@ -0,0 +1,112 @@
<template>
<f-switch
v-show="hasModule('bill')"
id="ausstand"
name="ausstand"
:model-value="getFilter('ausstand')"
label="Nur Ausstände"
size="sm"
@update:model-value="setFilter('ausstand', $event)"
></f-switch>
<f-select
id="has_vk"
name="has_vk"
:model-value="getFilter('has_vk')"
label="Verhaltenskodex unterschrieben"
size="sm"
:options="meta.boolean_filter"
@update:model-value="setFilter('has_vk', $event)"
></f-select>
<f-select
id="has_svk"
name="has_svk"
:model-value="getFilter('has_svk')"
label="SVK unterschrieben"
size="sm"
:options="meta.boolean_filter"
@update:model-value="setFilter('has_svk', $event)"
></f-select>
<f-multipleselect
id="group_ids"
:options="meta.groups"
:model-value="getFilter('group_ids')"
label="Gruppierungen"
size="sm"
@update:model-value="setFilter('group_ids', $event)"
></f-multipleselect>
<f-select
v-show="hasModule('bill')"
id="billKinds"
name="billKinds"
:options="meta.billKinds"
:model-value="getFilter('bill_kind')"
label="Rechnung"
size="sm"
@update:model-value="setFilter('bill_kind', $event)"
></f-select>
<div>
<div>nach mitgitedschaftren</div>
<button class="btn btn-primary label mt-2" @click.prevent="memberships = [...memberships, {...meta.default_membership_filter}]">
<ui-sprite class="w-3 h-3 xl:mr-2" src="plus"></ui-sprite>
<span class="hidden xl:inline">Hinzufügen</span>
</button>
<div v-for="(filter, index) in memberships" :key="index" class="flex space-x-2 mt-2">
<f-multipleselect :id="`group_ids-multiple-${index}`" v-model="filter.group_ids" :options="meta.groups" label="Gruppierung" size="sm"></f-multipleselect>
<f-multipleselect :id="`activity_ids-multiple-${index}`" v-model="filter.activity_ids" :options="meta.filterActivities" label="Tätigkeiten" size="sm"></f-multipleselect>
<f-multipleselect :id="`subactivity_ids-multiple-${index}`" v-model="filter.subactivity_ids" :options="meta.filterSubactivities" label="Untertätigkeiten" size="sm"></f-multipleselect>
</div>
<button
class="btn btn-primary label mt-3"
@click.prevent="
setFilterObject({...filter, memberships: membershipFilters});
membershipFilters = null;
"
>
<span class="hidden xl:inline">Anwenden</span>
</button>
</div>
</template>
<script setup>
import {onMounted, ref, watch} from 'vue';
const emit = defineEmits(['update:modelValue']);
const props = defineProps({
modelValue: {
type: Object,
required: true,
},
meta: {
type: Object,
required: true,
},
});
function getFilter(key) {
return props.modelValue[key];
}
function setFilter(key, value) {
emit('update:modelValue', {
...props.modelValue,
[key]: value,
});
}
const memberships = ref([]);
onMounted(() => {
memberships.value = props.modelValue.memberships;
});
watch(
memberships,
function (newValue) {
console.log('II');
setFilter('meberships', newValue);
},
{deep: true}
);
</script>

View File

@ -17,80 +17,12 @@
</div>
</div>
</ui-popup>
<ui-popup v-if="membershipFilters !== null" heading="Nach Mitgliedschaften filtern" full @close="membershipFilters = null">
<button class="btn btn-primary label mt-2" @click.prevent="membershipFilters.push({...meta.default_membership_filter})">
<ui-sprite class="w-3 h-3 xl:mr-2" src="plus"></ui-sprite>
<span class="hidden xl:inline">Hinzufügen</span>
</button>
<div v-for="(filter, index) in membershipFilters" :key="index" class="flex space-x-2 mt-2">
<f-multipleselect :id="`group_ids-multiple-${index}`" v-model="filter.group_ids" :options="meta.groups" label="Gruppierung" size="sm"></f-multipleselect>
<f-multipleselect :id="`activity_ids-multiple-${index}`" v-model="filter.activity_ids" :options="meta.filterActivities" label="Tätigkeiten" size="sm"></f-multipleselect>
<f-multipleselect :id="`subactivity_ids-multiple-${index}`" v-model="filter.subactivity_ids" :options="meta.filterSubactivities" label="Untertätigkeiten" size="sm"></f-multipleselect>
</div>
<button
class="btn btn-primary label mt-3"
@click.prevent="
setFilter('memberships', membershipFilters);
membershipFilters = null;
"
>
<span class="hidden xl:inline">Anwenden</span>
</button>
</ui-popup>
<page-filter>
<template #fields>
<f-switch
v-show="hasModule('bill')"
id="ausstand"
name="ausstand"
:model-value="getFilter('ausstand')"
label="Nur Ausstände"
size="sm"
@update:model-value="setFilter('ausstand', $event)"
></f-switch>
<f-select
id="has_vk"
name="has_vk"
:model-value="getFilter('has_vk')"
label="Verhaltenskodex unterschrieben"
size="sm"
:options="meta.boolean_filter"
@update:model-value="setFilter('has_vk', $event)"
></f-select>
<f-select
id="has_svk"
name="has_svk"
:model-value="getFilter('has_svk')"
label="SVK unterschrieben"
size="sm"
:options="meta.boolean_filter"
@update:model-value="setFilter('has_svk', $event)"
></f-select>
<f-multipleselect
id="group_ids"
:options="meta.groups"
:model-value="getFilter('group_ids')"
label="Gruppierungen"
size="sm"
@update:model-value="setFilter('group_ids', $event)"
></f-multipleselect>
<f-select
v-show="hasModule('bill')"
id="billKinds"
name="billKinds"
:options="meta.billKinds"
:model-value="getFilter('bill_kind')"
label="Rechnung"
size="sm"
@update:model-value="setFilter('bill_kind', $event)"
></f-select>
<button class="btn btn-primary label mr-2" @click.prevent="membershipFilters = getFilter('memberships')">
<ui-sprite class="w-3 h-3 xl:mr-2" src="filter"></ui-sprite>
<span class="hidden xl:inline">Mitgliedschaften</span>
</button>
<member-filter :meta="meta" :model-value="filter" @update:model-value="setFilterObject($event)" />
</template>
<template #buttons>
<f-text id="search" :model-value="getFilter('search')" label="Suchen …" size="sm" @update:model-value="setFilter('search', $event)"></f-text>
<f-text id="search" :model-value="filter.search" label="Suchen …" size="sm" @update:model-value="setFilterObject({...filter, search: $event})"></f-text>
<button class="btn btn-primary label mr-2" @click.prevent="exportMembers">
<ui-sprite class="w-3 h-3 xl:mr-2" src="save"></ui-sprite>
<span class="hidden xl:inline">Exportieren</span>
@ -161,7 +93,7 @@
</page-layout>
</template>
<script lang="js" setup>
<script setup>
import MemberInvoicePositions from './MemberInvoicePositions.vue';
import MemberMemberships from './MemberMemberships.vue';
import MemberCourses from './MemberCourses.vue';
@ -169,13 +101,13 @@ import Tags from './Tags.vue';
import Actions from './index/Actions.vue';
import {indexProps, useIndex} from '../../composables/useIndex.js';
import {ref, defineProps} from 'vue';
import MemberFilter from './MemberFilter.vue';
const single = ref(null);
const deleting = ref(null);
const membershipFilters = ref(null);
const props = defineProps(indexProps);
var { router, data, meta, getFilter, setFilter, filterString, reloadPage } = useIndex(props.data, 'member');
var {router, data, meta, filter, setFilterObject, filterString, reloadPage} = useIndex(props.data, 'member');
function exportMembers() {
window.open(`/member-export?filter=${filterString.value}`);