feat: synchronize friendly match double rows on input changes
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 54s

This commit is contained in:
Torsten Schulz (local)
2026-08-14 09:13:51 +02:00
parent 2c5a98e9da
commit 427c9dc35e

View File

@@ -135,7 +135,7 @@
</thead>
<tbody>
<tr v-for="match in matches" :key="match.id"
@click="friendlyOnly ? openFriendlyMatchDialog(match) : openPlayerSelectionDialog(match)"
@click="friendlyOnly ? (isFriendlyMatchReadOnly(match) ? openFriendlyResultDialog(match) : openFriendlyMatchDialog(match)) : openPlayerSelectionDialog(match)"
:class="getRowClass(match.date)"
style="cursor: pointer;">
<td class="location-info-cell">
@@ -395,7 +395,7 @@
<BaseDialog
v-model="friendlyResultDialog.isOpen"
:title="`Ergebniseingabe - ${friendlyResultDialog.match?.homeTeam?.name || ''} vs ${friendlyResultDialog.match?.guestTeam?.name || ''}`"
:title="`${friendlyResultReadonly ? 'Ergebnis' : 'Ergebniseingabe'} - ${friendlyResultDialog.match?.homeTeam?.name || ''} vs ${friendlyResultDialog.match?.guestTeam?.name || ''}`"
width="96vw"
max-width="1500px"
@close="closeFriendlyResultDialog"
@@ -431,18 +431,25 @@
<td class="friendly-result-player">{{ row.homeName || '-' }}</td>
<td class="friendly-result-player">{{ row.guestName || '-' }}</td>
<td v-for="setIndex in 5" :key="setIndex">
<span v-if="friendlyResultReadonly" class="friendly-result-set-value">
{{ row.sets[setIndex - 1] || '' }}
</span>
<input
v-else
v-model="row.sets[setIndex - 1]"
class="set-input"
placeholder="11:7"
:disabled="friendlyResultReadonly || isFriendlySetClosed(row, setIndex - 1)"
:disabled="isFriendlySetClosed(row, setIndex - 1)"
@blur="normalizeFriendlySet(row, setIndex - 1)"
/>
</td>
<td :class="['friendly-result-score-cell', friendlyScorePerspectiveClass(calculateFriendlyRowSets(row))]">{{ friendlyRowSetScore(row) }}</td>
<td :class="['friendly-result-score-cell', friendlyScorePerspectiveClass(friendlyRowPointScoreObject(row))]">{{ friendlyRowPointScore(row) }}</td>
<td>
<button type="button" class="btn-secondary" :disabled="friendlyResultReadonly" @click="row.completed = !row.completed">
<span v-if="friendlyResultReadonly" class="friendly-result-status">
{{ row.completed ? 'Abgeschlossen' : 'Offen' }}
</span>
<button v-else type="button" class="btn-secondary" @click="row.completed = !row.completed">
{{ row.completed ? 'Abgeschlossen' : 'Offen' }}
</button>
</td>
@@ -553,7 +560,7 @@
<label>Heimteam <input v-model="friendlyMatchDialog.form.homeTeamName" type="text" :disabled="friendlyMatchDialog.readonly" /></label>
<label>Gastteam <input v-model="friendlyMatchDialog.form.guestTeamName" type="text" :disabled="friendlyMatchDialog.readonly" /></label>
<label>Spielsystem
<select v-model="friendlyMatchDialog.form.matchSystem" :disabled="friendlyMatchDialog.readonly">
<select v-model="friendlyMatchDialog.form.matchSystem" :disabled="friendlyMatchDialog.readonly" @change="syncFriendlyEditDoubleRows">
<option>Braunschweiger System</option>
<option>Bundessystem</option>
<option>Werner-Scheffler-System</option>
@@ -1627,6 +1634,7 @@ export default {
resultDetails: [...this.parseFriendlyArray(match.resultDetails)]
}
: this.emptyFriendlyMatchForm();
this.syncFriendlyEditDoubleRows();
await this.loadFriendlyVenues(match);
const selectedVenue = this.findFriendlyVenueForForm();
this.friendlyMatchDialog.selectedVenueId = selectedVenue ? String(selectedVenue.id) : '';
@@ -1645,15 +1653,18 @@ export default {
const list = this.friendlyMatchDialog.form[field];
if (list.some(p => p.type === 'member' && Number(p.memberId) === Number(memberId))) return;
list.push({ type: 'member', memberId });
this.syncFriendlyEditDoubleRows();
},
addManualFriendlyParticipant(field, fullName) {
const parts = String(fullName).trim().split(/\s+/);
const firstName = parts.shift() || '';
const lastName = parts.join(' ');
this.friendlyMatchDialog.form[field].push({ type: 'manual', firstName, lastName });
this.syncFriendlyEditDoubleRows();
},
removeFriendlyParticipant(field, index) {
this.friendlyMatchDialog.form[field].splice(index, 1);
this.syncFriendlyEditDoubleRows();
},
friendlyParticipantLabel(participant, fallback = '') {
if (!participant) return fallback;
@@ -1717,7 +1728,7 @@ export default {
const current = doubleIndex == null ? row[field] : this.friendlyDoublePart(row[field], doubleIndex);
return labels.filter((label) => label === current || !used.has(label));
},
friendlyEditDoubleRows() {
syncFriendlyEditDoubleRows() {
const form = this.friendlyMatchDialog.form;
const template = this.friendlyResultTemplate({
...form,
@@ -1740,6 +1751,20 @@ export default {
form.resultDetails = [...doubles, ...singles];
return doubles;
},
friendlyEditDoubleRows() {
const form = this.friendlyMatchDialog.form;
const doubleIds = this.friendlyResultTemplate({
...form,
homeParticipants: form.homeParticipants,
guestParticipants: form.guestParticipants,
})
.filter((row) => row.type === 'double')
.map((row) => row.id);
const rowsById = new Map((Array.isArray(form.resultDetails) ? form.resultDetails : [])
.filter((row) => row?.type === 'double' && row.id)
.map((row) => [String(row.id), row]));
return doubleIds.map((id) => rowsById.get(id)).filter(Boolean);
},
friendlyEditDoubleLabels(field) {
return this.friendlyParticipantLabels(this.friendlyMatchDialog.form[field]);
},
@@ -2118,7 +2143,7 @@ export default {
},
async saveFriendlyMatch() {
if (this.friendlyMatchDialog.readonly) return;
this.friendlyEditDoubleRows();
this.syncFriendlyEditDoubleRows();
try {
const payload = {
...this.friendlyMatchDialog.form,
@@ -3101,6 +3126,18 @@ td {
text-align: center;
}
.friendly-result-set-value,
.friendly-result-status {
display: inline-block;
min-width: 4.5rem;
padding: 0.35rem 0.45rem;
text-align: center;
}
.friendly-result-status {
color: var(--text-muted, #667085);
}
.friendly-result-score-cell,
.score-value {
border-radius: 4px;