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>
<label class="block text-sm font-medium text-gray-700 mb-2">Spielplan-Team-IDs</label>
<select
:value="selectedSpielplanTeamIds"
multiple
size="4"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500"
:disabled="isSaving"
@change="updateSpielplanTeamIds"
>
<option v-for="team in spielplanTeams" :key="team.id" :value="team.id">
{{ team.label }}
</option>
</select>
<div class="max-h-48 overflow-y-auto rounded-lg border border-gray-300 divide-y divide-gray-100">
<label
v-for="team in spielplanTeams"
:key="team.id"
class="flex items-start gap-3 px-4 py-3 cursor-pointer hover:bg-gray-50"
>
<input
:checked="selectedSpielplanTeamIds.includes(team.id)"
type="checkbox"
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">
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>
</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 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 updateSpielplanTeamIds = (event) => {
formData.value.spielplan_mannschaft_id = Array.from(event.target.selectedOptions, option => option.value).join(',')
const toggleSpielplanTeamId = (id, checked) => {
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) {

View File

@@ -54,8 +54,9 @@ function romanToNumber(value) {
return result || null
}
function getCmsTeamCriteria(name) {
const youth = String(name || '').trim().match(/^jugend\s+j(\d{1,2})(?:\s+([ivx]+|\d+))?\b/i)
function getCmsTeamCriteria(name, league) {
const teamName = String(name || '').trim()
const youth = teamName.match(/^jugend\s+j(\d{1,2})(?:\s+([ivx]+|\d+))?\b/i)
if (youth) {
const rawNumber = youth[2]
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]) }
return null
}
@@ -114,7 +126,7 @@ export async function synchronizeMannschaftenSpielplanIds(seasonSlug) {
let updatedTeams = 0
for (const row of parsed.slice(1)) {
const criteria = getCmsTeamCriteria(row[0])
const criteria = getCmsTeamCriteria(row[0], row[1])
if (!criteria) continue
const ids = importedTeams
.filter(team => team.ageClass === criteria.ageClass && (!criteria.teamNumber || team.teamNumber === criteria.teamNumber))