feat(MembersOverview, MembersView): add training group filtering and display enhancements
- Introduced a new training group filter in MembersOverviewSection for improved member management. - Updated MembersView to support the new training group selection and display last training date for members. - Enhanced computed properties to dynamically generate training group options based on member data. - Improved filtering logic to include selected training group, refining member search capabilities.
This commit is contained in:
@@ -106,6 +106,15 @@
|
||||
<option value="unknown">{{ $t('members.genderUnknown') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>{{ $t('members.trainingGroups') }}:</label>
|
||||
<select :value="selectedTrainingGroup" class="filter-select" @change="$emit('update:selected-training-group', $event.target.value)">
|
||||
<option value="">{{ $t('common.all') }}</option>
|
||||
<option v-for="group in trainingGroupOptions" :key="group.id" :value="group.id">
|
||||
{{ group.name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<button @click="$emit('clear-filters')" class="btn-clear-filters">{{ $t('members.clearFilters') }}</button>
|
||||
</div>
|
||||
</details>
|
||||
@@ -193,6 +202,8 @@ export default {
|
||||
selectedAgeFrom: { type: [String, Number], required: true },
|
||||
selectedAgeTo: { type: [String, Number], required: true },
|
||||
selectedGender: { type: String, required: true },
|
||||
selectedTrainingGroup: { type: String, required: true },
|
||||
trainingGroupOptions: { type: Array, required: true },
|
||||
selectedSort: { type: String, required: true },
|
||||
sortDirection: { type: String, required: true },
|
||||
filteredMembersWithoutFormCount: { type: Number, required: true },
|
||||
@@ -213,6 +224,7 @@ export default {
|
||||
'update:selected-age-from',
|
||||
'update:selected-age-to',
|
||||
'update:selected-gender',
|
||||
'update:selected-training-group',
|
||||
'clear-filters',
|
||||
'update:selected-sort',
|
||||
'toggle-sort-direction',
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
:selected-age-from="selectedAgeFrom"
|
||||
:selected-age-to="selectedAgeTo"
|
||||
:selected-gender="selectedGender"
|
||||
:selected-training-group="selectedTrainingGroup"
|
||||
:training-group-options="trainingGroupFilterOptions"
|
||||
:selected-sort="selectedSort"
|
||||
:sort-direction="sortDirection"
|
||||
:filtered-members-without-form-count="filteredMembersWithoutForm.length"
|
||||
@@ -33,6 +35,7 @@
|
||||
@update:selected-age-from="selectedAgeFrom = $event"
|
||||
@update:selected-age-to="selectedAgeTo = $event"
|
||||
@update:selected-gender="selectedGender = $event"
|
||||
@update:selected-training-group="selectedTrainingGroup = $event"
|
||||
@clear-filters="clearFilters"
|
||||
@update:selected-sort="selectedSort = $event"
|
||||
@toggle-sort-direction="toggleSortDirection"
|
||||
@@ -326,6 +329,7 @@
|
||||
<th>{{ $t('members.contact') }}</th>
|
||||
<th>{{ $t('members.birthdate') }}</th>
|
||||
<th>{{ $t('members.age') }}</th>
|
||||
<th>{{ $t('members.lastTraining') }}</th>
|
||||
<th v-if="hasTestMembers">{{ $t('members.trainingParticipations') }}</th>
|
||||
<th>{{ $t('members.actions') }}</th>
|
||||
</tr>
|
||||
@@ -398,6 +402,7 @@
|
||||
</td>
|
||||
<td>{{ getFormattedBirthdate(member.birthDate) }}</td>
|
||||
<td>{{ getAgeLabel(member.birthDate) }}</td>
|
||||
<td>{{ getOptionalFormattedDate(member.lastTraining, 'members.previewNoLastTraining') }}</td>
|
||||
<td v-if="hasTestMembers">
|
||||
<span v-if="member.testMembership">{{ member.trainingParticipations || 0 }}</span>
|
||||
<span v-else>-</span>
|
||||
@@ -578,6 +583,22 @@ export default {
|
||||
inactiveMembersCount() {
|
||||
return this.members.filter(member => !member.active).length;
|
||||
},
|
||||
|
||||
trainingGroupFilterOptions() {
|
||||
const groups = new Map();
|
||||
this.members.forEach((member) => {
|
||||
this.getMemberTrainingGroups(member).forEach((group) => {
|
||||
if (!group || group.id == null) {
|
||||
return;
|
||||
}
|
||||
groups.set(String(group.id), group.name || `#${group.id}`);
|
||||
});
|
||||
});
|
||||
|
||||
return Array.from(groups.entries())
|
||||
.map(([id, name]) => ({ id, name }))
|
||||
.sort((a, b) => a.name.localeCompare(b.name, 'de-DE'));
|
||||
},
|
||||
|
||||
filteredMembers() {
|
||||
return this.members.filter(member => {
|
||||
@@ -648,6 +669,13 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.selectedTrainingGroup) {
|
||||
const memberGroupIds = this.getMemberTrainingGroups(member).map(group => String(group.id));
|
||||
if (!memberGroupIds.includes(String(this.selectedTrainingGroup))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (search) {
|
||||
const haystack = [
|
||||
member.firstName,
|
||||
@@ -885,6 +913,7 @@ export default {
|
||||
selectedAgeFrom: '',
|
||||
selectedAgeTo: '',
|
||||
selectedGender: '',
|
||||
selectedTrainingGroup: '',
|
||||
clickTtPendingMemberIds: [],
|
||||
searchQuery: '',
|
||||
selectedMemberScope: 'active',
|
||||
@@ -2323,6 +2352,7 @@ export default {
|
||||
this.selectedAgeFrom = '';
|
||||
this.selectedAgeTo = '';
|
||||
this.selectedGender = '';
|
||||
this.selectedTrainingGroup = '';
|
||||
this.showInactiveMembers = false;
|
||||
this.searchQuery = '';
|
||||
this.selectedMemberScope = 'active';
|
||||
|
||||
Reference in New Issue
Block a user