Update worshipController.js to enhance worship data parsing and conflict resolution. Introduce unparsedText for better tracking of source data. Modify date handling functions for improved accuracy in event filtering. Update .gitignore to exclude generated frontend artifacts, including index.html and assets directory, to streamline deployment.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s

This commit is contained in:
Torsten Schulz (local)
2026-04-29 18:47:15 +02:00
parent 05a8229b83
commit 7d5e2526d3
600 changed files with 183 additions and 4253 deletions

View File

@@ -112,6 +112,27 @@
@update:modelValue="(value) => { if (value) worship.eventPlaceId = value.id; }"
></multiselect>
</div>
<div v-if="worship._sourceText" class="field-group source-field">
<label>Original aus Excel:</label>
<textarea :value="worship._sourceText" readonly rows="2"></textarea>
<small v-if="worship._unparsedText">Nicht automatisch übernommen: {{ worship._unparsedText }}</small>
</div>
<div v-if="worship._hasDayPlaceConflict" class="field-group conflict-field">
<label>Es gibt bereits Gottesdienst(e) an diesem Tag und Ort:</label>
<ul>
<li v-for="existing in worship._conflictingWorships" :key="existing.id">
{{ formatConflictWorship(existing) }}
</li>
</ul>
<label class="radio-label">
<input type="radio" value="keepExisting" v-model="worship._importChoice" />
Bestehenden Eintrag behalten, importierten Eintrag nicht speichern
</label>
<label class="radio-label">
<input type="radio" value="replaceExisting" v-model="worship._importChoice" />
Importierten Eintrag speichern und bestehende(n) ersetzen
</label>
</div>
<div class="field-group" :class="{ 'field-changed': isFieldChanged(worship, 'title') }">
<label>
Titel:
@@ -194,7 +215,7 @@
<input type="time" id="time" v-model="worshipData.time" required>
<label for="title">Titel:</label>
<input type="text" id="title" v-model="worshipData.title" required>
<input type="text" id="title" v-model="worshipData.title">
<label for="organizer">Gestalter:</label>
<multiselect v-model="selectedOrganizers" :options="organizerOptions" :multiple="true" :taggable="true"
@@ -459,6 +480,12 @@ export default {
}
return '';
},
formatConflictWorship(worship) {
const time = worship.time ? `${worship.time} Uhr` : 'ohne Uhrzeit';
const title = worship.title || 'Gottesdienst';
const organizer = worship.organizer ? `, ${worship.organizer}` : '';
return `${time} ${title}${organizer}`;
},
formatTime,
formatDate,
async fetchWorships() {
@@ -593,9 +620,15 @@ export default {
},
async saveWorship() {
try {
if (!this.worshipData.date || !this.worshipData.time || !this.selectedEventPlace) {
alert('Bitte Datum, Uhrzeit und Veranstaltungsort ausfüllen.');
return;
}
const payload = {
...this.worshipData,
eventPlaceId: this.selectedEventPlace ? this.selectedEventPlace.id : null,
title: this.worshipData.title && this.worshipData.title.trim() ? this.worshipData.title.trim() : 'Gottesdienst',
organizer: this.selectedOrganizers.map(org => org.name).join(', '),
sacristanService: this.selectedSacristans.map(sac => sac.name).join(', '),
dayName: this.selectedDayName ? this.selectedDayName.dayName : '',
@@ -792,7 +825,13 @@ export default {
_oldValues: w._oldValues || {},
_isUpdate: w._isUpdate || false,
_isNew: w._isNew || false,
_existingId: w._existingId || null
_existingId: w._existingId || null,
_sourceText: w._sourceText || '',
_unparsedText: w._unparsedText || '',
_hasDayPlaceConflict: w._hasDayPlaceConflict || false,
_conflictingWorships: w._conflictingWorships || [],
_replaceExistingIds: w._replaceExistingIds || [],
_importChoice: w._importChoice || (w._hasDayPlaceConflict ? 'keepExisting' : 'import')
};
});
this.importErrors = response.data.errors || [];
@@ -826,6 +865,18 @@ export default {
return;
}
const invalidWorship = this.importedWorships.find(w => {
if (w._hasDayPlaceConflict && w._importChoice === 'keepExisting') {
return false;
}
const eventPlaceId = w.eventPlace ? w.eventPlace.id : (w.eventPlaceId || null);
return !w.date || !w.time || !eventPlaceId;
});
if (invalidWorship) {
alert('Bitte bei allen zu speichernden Gottesdiensten Datum, Uhrzeit und Ort ausfüllen.');
return;
}
this.isImporting = true;
// Daten für das Backend vorbereiten
@@ -855,13 +906,15 @@ export default {
date: dateStr,
dayName: w.dayName,
time: timeValue,
title: w.title,
title: w.title && w.title.trim() ? w.title.trim() : 'Gottesdienst',
organizer: w.organizer,
collection: w.collection,
sacristanService: w.sacristanService,
organPlaying: w.organPlaying,
approved: w.approved || false,
eventPlaceId: w.eventPlace ? w.eventPlace.id : (w.eventPlaceId || null),
_importChoice: w._importChoice || 'import',
_replaceExistingIds: w._replaceExistingIds || [],
};
return worshipData;
});
@@ -1513,13 +1566,49 @@ li>span {
.field-group input[type="text"],
.field-group input[type="date"],
.field-group input[type="time"] {
.field-group input[type="time"],
.field-group textarea {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.source-field {
grid-column: 1 / -1;
}
.source-field textarea {
background: #f8f9fa;
resize: vertical;
}
.source-field small {
margin-top: 4px;
color: #666;
}
.conflict-field {
grid-column: 1 / -1;
padding: 10px;
border: 1px solid #f0ad4e;
border-radius: 4px;
background: #fff8e5;
}
.conflict-field ul {
margin: 0 0 8px 18px;
padding: 0;
}
.conflict-field .radio-label {
display: flex;
gap: 8px;
align-items: center;
margin-top: 6px;
font-weight: normal;
}
.field-group.field-changed {
background-color: #fff3cd;
padding: 8px;