feat(TournamentStats): enhance internal tournament statistics with member profile integration
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 37s
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 37s
- Integrated member profile data (birth date and gender) into the internal tournament statistics calculations for more accurate age class filtering. - Removed deprecated age class filtering functions and streamlined the statistics computation process. - Updated the InternalTournamentStats component to reflect changes in age class options and improved sorting logic. - Enhanced localization strings across multiple languages to support new terminology related to age classes and gender, improving user accessibility and understanding.
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
</p>
|
||||
<p class="stats-explain">{{ $t('tournaments.internalStatsPointsExplain') }}</p>
|
||||
|
||||
<fieldset v-if="sortedAgeOptions.length > 1" class="age-filter">
|
||||
<fieldset v-if="sortedAgeOptions.length" class="age-filter">
|
||||
<legend class="age-filter-legend">{{ $t('tournaments.internalStatsAgeFilter') }}</legend>
|
||||
<div class="age-filter-actions">
|
||||
<button type="button" class="age-filter-link" @click="selectAllAgeKeys" :disabled="loading">
|
||||
@@ -154,13 +154,10 @@ export default {
|
||||
sortedAgeOptions() {
|
||||
const list = [...(this.stats.ageClassOptions || [])];
|
||||
list.sort((a, b) => {
|
||||
const va = this.ageClassSortValue(a);
|
||||
const vb = this.ageClassSortValue(b);
|
||||
const va = this.ttOptionSortKey(a);
|
||||
const vb = this.ttOptionSortKey(b);
|
||||
if (va !== vb) return va - vb;
|
||||
const ga = this.tournamentGenderSortOrder(a.gender);
|
||||
const gb = this.tournamentGenderSortOrder(b.gender);
|
||||
if (ga !== gb) return ga - gb;
|
||||
return (a.name || '').localeCompare(b.name || '', 'de', { sensitivity: 'base' });
|
||||
return (a.key || '').localeCompare(b.key || '', 'de');
|
||||
});
|
||||
return list;
|
||||
},
|
||||
@@ -232,48 +229,35 @@ export default {
|
||||
this.selectedAgeKeys = [];
|
||||
this.load();
|
||||
},
|
||||
/** TT: nur Weiblich vs. Alle (offen); kein „Männlich“ mehr in Turnierklassen */
|
||||
tournamentClassGenderLabel(gender) {
|
||||
if (gender === 'female') return this.$t('tournaments.tournamentClassGenderFemale');
|
||||
/** TT: nur Weiblich vs. Alle (offen) */
|
||||
tournamentClassGenderLabelFromMode(genderMode) {
|
||||
if (genderMode === 'female') return this.$t('tournaments.tournamentClassGenderFemale');
|
||||
return this.$t('tournaments.tournamentClassGenderOpen');
|
||||
},
|
||||
tournamentGenderSortOrder(gender) {
|
||||
return gender === 'female' ? 0 : 1;
|
||||
},
|
||||
/**
|
||||
* Reihenfolge: J9 … J19 (bzw. U…), dann Erwachsene/Senioren, Sonstiges, ohne Klasse zuletzt.
|
||||
*/
|
||||
ageClassSortValue(opt) {
|
||||
if (opt.isNoClass) return 99999;
|
||||
const name = (opt.name || '').trim();
|
||||
const ju = name.match(/\bJ\s*(\d+)\b/i) || name.match(/\bU\s*(\d+)\b/i);
|
||||
if (ju) {
|
||||
const num = parseInt(ju[1], 10);
|
||||
return 100 + num;
|
||||
/** Sortierung: J9w, J9o, J11w … Erwachsene, zuletzt ohne Zuordnung */
|
||||
ttOptionSortKey(opt) {
|
||||
if (!opt) return 0;
|
||||
if (opt.isNoClass) return 1e6;
|
||||
if (opt.band === 'adult') return 5000 + (opt.genderMode === 'female' ? 0 : 1);
|
||||
if (opt.band === 'youth' && opt.bandNum != null) {
|
||||
return opt.bandNum * 10 + (opt.genderMode === 'female' ? 0 : 1);
|
||||
}
|
||||
if (/erwachsen|senioren/i.test(name)) return 9000;
|
||||
if (/damen|herren|aktive|mixed|offen|frei/i.test(name)) return 9100;
|
||||
return 5000;
|
||||
return 9999;
|
||||
},
|
||||
formatAgeOption(opt) {
|
||||
if (!opt) return '';
|
||||
if (opt.isNoClass) return this.$t('tournaments.internalStatsAgeNoClass');
|
||||
const bits = [];
|
||||
const nameTrim = (opt.name || '').trim();
|
||||
if (nameTrim) bits.push(nameTrim);
|
||||
const min = opt.minBirthYear;
|
||||
const max = opt.maxBirthYear;
|
||||
if (!nameTrim) {
|
||||
if (min != null && max != null) bits.push(`${min}–${max}`);
|
||||
else if (max != null) bits.push(`≤ ${max}`);
|
||||
else if (min != null) bits.push(`≥ ${min}`);
|
||||
if (opt.band === 'youth' && opt.bandNum != null) {
|
||||
return `J${opt.bandNum} · ${this.tournamentClassGenderLabelFromMode(opt.genderMode)}`;
|
||||
}
|
||||
bits.push(this.tournamentClassGenderLabel(opt.gender));
|
||||
return bits.join(' · ');
|
||||
if (opt.band === 'adult') {
|
||||
return `${this.$t('tournaments.internalStatsTtAdult')} · ${this.tournamentClassGenderLabelFromMode(opt.genderMode)}`;
|
||||
}
|
||||
return opt.key || '';
|
||||
},
|
||||
ageFilterPdfLine() {
|
||||
const opts = this.stats.ageClassOptions || [];
|
||||
if (opts.length <= 1) return '';
|
||||
if (opts.length === 0) return '';
|
||||
const allKeys = opts.map((o) => o.key);
|
||||
if (this.selectedAgeKeys.length === allKeys.length) {
|
||||
return this.$t('tournaments.internalStatsAgeFilterAll');
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
"internalStatsAgeFilter": "Altersklassä & Gschlächt (Einzel)",
|
||||
"tournamentClassGenderFemale": "Weiblich",
|
||||
"tournamentClassGenderOpen": "Alli",
|
||||
"internalStatsTtAdult": "Erwachsene",
|
||||
"internalStatsAgeNoClass": "Ohni Klassäzuordnig",
|
||||
"internalStatsAgeSelectAll": "Alli",
|
||||
"internalStatsAgeSelectNone": "Keini",
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
"internalStatsAgeFilter": "Altersklassen & Geschlecht (Einzel)",
|
||||
"tournamentClassGenderFemale": "Weiblich",
|
||||
"tournamentClassGenderOpen": "Alle",
|
||||
"internalStatsTtAdult": "Erwachsene",
|
||||
"internalStatsAgeNoClass": "Ohne Klassenzuordnung",
|
||||
"internalStatsAgeSelectAll": "Alle",
|
||||
"internalStatsAgeSelectNone": "Keine",
|
||||
|
||||
@@ -704,6 +704,7 @@
|
||||
"internalStatsAgeFilter": "Altersklassen & Geschlecht (Einzel)",
|
||||
"tournamentClassGenderFemale": "Weiblich",
|
||||
"tournamentClassGenderOpen": "Alle",
|
||||
"internalStatsTtAdult": "Erwachsene",
|
||||
"internalStatsAgeNoClass": "Ohne Klassenzuordnung",
|
||||
"internalStatsAgeSelectAll": "Alle",
|
||||
"internalStatsAgeSelectNone": "Keine",
|
||||
@@ -714,7 +715,7 @@
|
||||
"internalStatsLast6Months": "Letzte 6 Monate",
|
||||
"internalStatsLast3Months": "Letzte 3 Monate",
|
||||
"internalStatsTournamentsInPeriod": "{count} Turnier(e) im Zeitraum (ohne Minimeisterschaften).",
|
||||
"internalStatsPointsExplain": "Wertung: Pro Gruppe wird die Platzierung als Prozentzahl ausgedrückt (bei N Teilnehmern mit Platzierung: 1. = 100 %, Letzter = 0 %, dazwischen linear; gleiche Platzierung = gleicher Wert). N umfasst alle Platzierten in der Gruppe (inkl. Gäste). Bei nur einem Teilnehmer: 100 %. Wer die K.-o.-Runde erreicht, erhält den höchsten Gruppenwert der Klasse plus 1, danach je gewonnenes K.-o.-Spiel einen weiteren Punkt. Nur Vereinsmitglieder (Einzel).",
|
||||
"internalStatsPointsExplain": "Wertung: Pro Gruppe wird die Platzierung als Prozentzahl ausgedrückt (bei N Teilnehmern mit Platzierung: 1. = 100 %, Letzter = 0 %, dazwischen linear; gleiche Platzierung = gleicher Wert). N umfasst alle Platzierten in der Gruppe (inkl. Gäste). Bei nur einem Teilnehmer: 100 %. Wer die K.-o.-Runde erreicht, erhält den höchsten Gruppenwert der Klasse plus 1, danach je gewonnenes K.-o.-Spiel einen weiteren Punkt. Nur Vereinsmitglieder (Einzel). Die Filter J9–J19 / Erwachsene und Weiblich/Alle beziehen sich auf das jeweilige Mitglied (Geburtsdatum und Geschlecht laut Vereinsdaten), nicht auf die Bezeichnung der Turnierklasse.",
|
||||
"internalStatsAbsoluteRank": "Rangliste Gesamtwertung",
|
||||
"internalStatsAverageRank": "Rangliste Durchschnitt (pro Turnier)",
|
||||
"internalStatsPoints": "Summe",
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
"internalStatsAgeFilter": "Age group & gender (singles)",
|
||||
"tournamentClassGenderFemale": "Female",
|
||||
"tournamentClassGenderOpen": "Open (all)",
|
||||
"internalStatsTtAdult": "Adults",
|
||||
"internalStatsAgeNoClass": "No class assigned",
|
||||
"internalStatsAgeSelectAll": "All",
|
||||
"internalStatsAgeSelectNone": "None",
|
||||
|
||||
@@ -362,6 +362,7 @@
|
||||
"internalStatsAgeFilter": "Age group & gender (singles)",
|
||||
"tournamentClassGenderFemale": "Female",
|
||||
"tournamentClassGenderOpen": "Open (all)",
|
||||
"internalStatsTtAdult": "Adults",
|
||||
"internalStatsAgeNoClass": "No class assigned",
|
||||
"internalStatsAgeSelectAll": "All",
|
||||
"internalStatsAgeSelectNone": "None",
|
||||
@@ -372,7 +373,7 @@
|
||||
"internalStatsLast6Months": "Last 6 months",
|
||||
"internalStatsLast3Months": "Last 3 months",
|
||||
"internalStatsTournamentsInPeriod": "{count} tournament(s) in this period (excluding mini championships).",
|
||||
"internalStatsPointsExplain": "Scoring: In each group, placement is expressed as a percentage (with N ranked players: 1st = 100%, last = 0%, linear in between; tied ranks share the same value). N counts everyone ranked in that group (including guests). With only one player: 100%. Players who reach the knockout get the highest group score in that class plus 1, then one extra point per knockout match won. Club members in singles classes only.",
|
||||
"internalStatsPointsExplain": "Scoring: In each group, placement is expressed as a percentage (with N ranked players: 1st = 100%, last = 0%, linear in between; tied ranks share the same value). N counts everyone ranked in that group (including guests). With only one player: 100%. Players who reach the knockout get the highest group score in that class plus 1, then one extra point per knockout match won. Club members in singles classes only. The J9–J19 / adults and female/open filters use each member’s birth date and gender from club records, not the tournament class name.",
|
||||
"internalStatsAbsoluteRank": "Total score ranking",
|
||||
"internalStatsAverageRank": "Average per tournament",
|
||||
"internalStatsPoints": "Total",
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
"internalStatsAgeFilter": "Age group & gender (singles)",
|
||||
"tournamentClassGenderFemale": "Female",
|
||||
"tournamentClassGenderOpen": "Open (all)",
|
||||
"internalStatsTtAdult": "Adults",
|
||||
"internalStatsAgeNoClass": "No class assigned",
|
||||
"internalStatsAgeSelectAll": "All",
|
||||
"internalStatsAgeSelectNone": "None",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "Edad y género (individual)",
|
||||
"tournamentClassGenderFemale": "Femenino",
|
||||
"tournamentClassGenderOpen": "Abierta (todos)",
|
||||
"internalStatsTtAdult": "Adultos",
|
||||
"internalStatsAgeNoClass": "Sin clase asignada",
|
||||
"internalStatsAgeSelectAll": "Todas",
|
||||
"internalStatsAgeSelectNone": "Ninguna",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "Edad at kasarian (singles)",
|
||||
"tournamentClassGenderFemale": "Babae",
|
||||
"tournamentClassGenderOpen": "Bukas (lahat)",
|
||||
"internalStatsTtAdult": "Adults",
|
||||
"internalStatsAgeNoClass": "Walang klase",
|
||||
"internalStatsAgeSelectAll": "Lahat",
|
||||
"internalStatsAgeSelectNone": "Wala",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "Âge et genre (simple)",
|
||||
"tournamentClassGenderFemale": "Féminin",
|
||||
"tournamentClassGenderOpen": "Tous",
|
||||
"internalStatsTtAdult": "Adultes",
|
||||
"internalStatsAgeNoClass": "Sans classe assignée",
|
||||
"internalStatsAgeSelectAll": "Tout",
|
||||
"internalStatsAgeSelectNone": "Aucune",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "Età e genere (singolo)",
|
||||
"tournamentClassGenderFemale": "Femminile",
|
||||
"tournamentClassGenderOpen": "Aperta (tutti)",
|
||||
"internalStatsTtAdult": "Adulti",
|
||||
"internalStatsAgeNoClass": "Senza classe assegnata",
|
||||
"internalStatsAgeSelectAll": "Tutte",
|
||||
"internalStatsAgeSelectNone": "Nessuna",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "年齢・性別(シングルス)",
|
||||
"tournamentClassGenderFemale": "女子",
|
||||
"tournamentClassGenderOpen": "オープン(全員)",
|
||||
"internalStatsTtAdult": "一般・シニア",
|
||||
"internalStatsAgeNoClass": "クラス未設定",
|
||||
"internalStatsAgeSelectAll": "すべて",
|
||||
"internalStatsAgeSelectNone": "なし",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "Grupa wiekowa i płeć (singel)",
|
||||
"tournamentClassGenderFemale": "Kobiety",
|
||||
"tournamentClassGenderOpen": "Otwarta (wszyscy)",
|
||||
"internalStatsTtAdult": "Dorośli",
|
||||
"internalStatsAgeNoClass": "Bez przypisania do klasy",
|
||||
"internalStatsAgeSelectAll": "Wszystkie",
|
||||
"internalStatsAgeSelectNone": "Żadna",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "รุ่นอายุและเพศ (เดี่ยว)",
|
||||
"tournamentClassGenderFemale": "หญิง",
|
||||
"tournamentClassGenderOpen": "เปิด (ทุกคน)",
|
||||
"internalStatsTtAdult": "ประเภทใหญ่",
|
||||
"internalStatsAgeNoClass": "ไม่มีคลาส",
|
||||
"internalStatsAgeSelectAll": "ทั้งหมด",
|
||||
"internalStatsAgeSelectNone": "ไม่มี",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "Edad at kasarian (singles)",
|
||||
"tournamentClassGenderFemale": "Babae",
|
||||
"tournamentClassGenderOpen": "Bukas (lahat)",
|
||||
"internalStatsTtAdult": "Adults",
|
||||
"internalStatsAgeNoClass": "Walang klase",
|
||||
"internalStatsAgeSelectAll": "Lahat",
|
||||
"internalStatsAgeSelectNone": "Wala",
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
"internalStatsAgeFilter": "年龄与性别(单打)",
|
||||
"tournamentClassGenderFemale": "女子",
|
||||
"tournamentClassGenderOpen": "公开组(全体)",
|
||||
"internalStatsTtAdult": "成人组",
|
||||
"internalStatsAgeNoClass": "未分配级别",
|
||||
"internalStatsAgeSelectAll": "全选",
|
||||
"internalStatsAgeSelectNone": "全不选",
|
||||
|
||||
Reference in New Issue
Block a user