feat: verbessere die Auswahl von Spielplan-Team-IDs durch Checkboxen und aktualisiere die Logik zur Verarbeitung von Team-Kriterien
All checks were successful
Code Analysis and Production Deploy / analyze (push) Successful in 7m10s
Code Analysis and Production Deploy / deploy-production (push) Has been skipped
Code Analysis and Production Deploy / deploy-test (push) Successful in 2m43s

This commit is contained in:
Torsten Schulz (local)
2026-07-17 12:05:22 +02:00
parent 461f2de8dc
commit 1beb5c2eee
2 changed files with 41 additions and 19 deletions

View File

@@ -204,20 +204,27 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 mb-2">Spielplan-Team-IDs</label> <label class="block text-sm font-medium text-gray-700 mb-2">Spielplan-Team-IDs</label>
<select <div class="max-h-48 overflow-y-auto rounded-lg border border-gray-300 divide-y divide-gray-100">
:value="selectedSpielplanTeamIds" <label
multiple v-for="team in spielplanTeams"
size="4" :key="team.id"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500" class="flex items-start gap-3 px-4 py-3 cursor-pointer hover:bg-gray-50"
:disabled="isSaving"
@change="updateSpielplanTeamIds"
> >
<option v-for="team in spielplanTeams" :key="team.id" :value="team.id"> <input
{{ team.label }} :checked="selectedSpielplanTeamIds.includes(team.id)"
</option> type="checkbox"
</select> class="mt-0.5 h-4 w-4 rounded border-gray-300 text-primary-600 focus:ring-primary-500"
:disabled="isSaving"
@change="toggleSpielplanTeamId(team.id, $event.target.checked)"
>
<span class="text-sm text-gray-800">{{ team.label }}</span>
</label>
<p v-if="!spielplanTeams.length" class="px-4 py-3 text-sm text-gray-500">
Noch keine importierten Spielplan-Teams verfügbar.
</p>
</div>
<p class="mt-1 text-xs text-gray-500"> <p class="mt-1 text-xs text-gray-500">
Nach dem myTischtennis-Import alle passenden Einträge auswählen (z. B. Liga und Pokal). Mit Strg bzw. Cmd lassen sich mehrere Einträge markieren. Alle passenden Einträge auswählen (z. B. Liga und Pokal). Die Auswahl wird beim Speichern beibehalten.
</p> </p>
</div> </div>
<div> <div>
@@ -447,8 +454,11 @@ function parseSpielerString(s) { if (!s) return []; return String(s).split(';').
function serializeSpielerList(list) { return (list || []).map(s => (s?.name || '').trim()).filter(Boolean).join('; ') } function serializeSpielerList(list) { return (list || []).map(s => (s?.name || '').trim()).filter(Boolean).join('; ') }
function serializeSpielerNames(names) { return (names || []).map(s => String(s || '').trim()).filter(Boolean).join('; ') } function serializeSpielerNames(names) { return (names || []).map(s => String(s || '').trim()).filter(Boolean).join('; ') }
const selectedSpielplanTeamIds = computed(() => String(formData.value.spielplan_mannschaft_id || '').split(',').map(id => id.trim()).filter(Boolean)) const selectedSpielplanTeamIds = computed(() => String(formData.value.spielplan_mannschaft_id || '').split(',').map(id => id.trim()).filter(Boolean))
const updateSpielplanTeamIds = (event) => { const toggleSpielplanTeamId = (id, checked) => {
formData.value.spielplan_mannschaft_id = Array.from(event.target.selectedOptions, option => option.value).join(',') const ids = new Set(selectedSpielplanTeamIds.value)
if (checked) ids.add(id)
else ids.delete(id)
formData.value.spielplan_mannschaft_id = [...ids].join(',')
} }
async function fetchCsvText(url) { async function fetchCsvText(url) {

View File

@@ -54,8 +54,9 @@ function romanToNumber(value) {
return result || null return result || null
} }
function getCmsTeamCriteria(name) { function getCmsTeamCriteria(name, league) {
const youth = String(name || '').trim().match(/^jugend\s+j(\d{1,2})(?:\s+([ivx]+|\d+))?\b/i) const teamName = String(name || '').trim()
const youth = teamName.match(/^jugend\s+j(\d{1,2})(?:\s+([ivx]+|\d+))?\b/i)
if (youth) { if (youth) {
const rawNumber = youth[2] const rawNumber = youth[2]
return { return {
@@ -64,7 +65,18 @@ function getCmsTeamCriteria(name) {
} }
} }
const adult = String(name || '').trim().match(/^erwachsene\s+(\d+)\b/i) // In bestehenden CMS-Daten steht die Altersklasse häufig nur in der Liga,
// z. B. Mannschaft "Jugend I" mit Liga "Jugend 13 (J13)".
const ageMatch = `${teamName} ${String(league || '')}`.match(/\b(?:jugend\s*|j\s*\(?)(\d{1,2})\b/i)
if (ageMatch) {
const ordinal = teamName.match(/^jugend\s+([ivx]+|\d+)\b/i)?.[1]
return {
ageClass: `Jugend ${ageMatch[1]}`,
teamNumber: ordinal ? (Number(ordinal) || romanToNumber(ordinal)) : null
}
}
const adult = teamName.match(/^erwachsene\s+(\d+)\b/i)
if (adult) return { ageClass: 'Erwachsene', teamNumber: Number(adult[1]) } if (adult) return { ageClass: 'Erwachsene', teamNumber: Number(adult[1]) }
return null return null
} }
@@ -114,7 +126,7 @@ export async function synchronizeMannschaftenSpielplanIds(seasonSlug) {
let updatedTeams = 0 let updatedTeams = 0
for (const row of parsed.slice(1)) { for (const row of parsed.slice(1)) {
const criteria = getCmsTeamCriteria(row[0]) const criteria = getCmsTeamCriteria(row[0], row[1])
if (!criteria) continue if (!criteria) continue
const ids = importedTeams const ids = importedTeams
.filter(team => team.ageClass === criteria.ageClass && (!criteria.teamNumber || team.teamNumber === criteria.teamNumber)) .filter(team => team.ageClass === criteria.ageClass && (!criteria.teamNumber || team.teamNumber === criteria.teamNumber))