feat: Add excludeFromBilling option for diary dates and update related functionality
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 44s

This commit is contained in:
Torsten Schulz (local)
2026-05-30 16:10:34 +02:00
parent 25f3802d66
commit 9d9481ac76
12 changed files with 208 additions and 25 deletions

View File

@@ -51,6 +51,17 @@
<label for="editTrainingEnd">{{ $t('diary.trainingEnd') }}:</label>
<input id="editTrainingEnd" :value="trainingEnd" type="time" step="300" @input="$emit('update:training-end', $event.target.value)" />
</div>
<div class="diary-billing-toggle-wrap">
<label class="diary-billing-toggle" for="editExcludeFromBilling">
<input
id="editExcludeFromBilling"
type="checkbox"
:checked="excludeFromBilling"
@change="$emit('update:exclude-from-billing', $event.target.checked)"
/>
<span>Nicht abrechnen</span>
</label>
</div>
<button type="submit">{{ $t('diary.updateTimes') }}</button>
</form>
</div>
@@ -120,11 +131,12 @@ export default {
activitiesCount: { type: Number, default: 0 },
trainingStart: { type: String, default: '' },
trainingEnd: { type: String, default: '' },
excludeFromBilling: { type: Boolean, default: false },
groups: { type: Array, required: true },
editingGroupId: { type: [Number, String, null], default: null },
newGroupCount: { type: Number, default: 2 }
},
emits: ['toggle-panel', 'update-training-times', 'update:training-start', 'update:training-end', 'edit-group', 'update-group-field', 'save-group', 'cancel-edit-group', 'delete-group', 'update:new-group-count', 'create-groups']
emits: ['toggle-panel', 'update-training-times', 'update:training-start', 'update:training-end', 'update:exclude-from-billing', 'edit-group', 'update-group-field', 'save-group', 'cancel-edit-group', 'delete-group', 'update:new-group-count', 'create-groups']
};
</script>
@@ -243,6 +255,20 @@ export default {
margin-bottom: 0.25rem;
}
.diary-billing-toggle-wrap {
display: flex;
align-items: center;
min-height: 2.5rem;
}
.diary-billing-toggle {
display: inline-flex;
align-items: center;
gap: 0.45rem;
font-weight: 600;
color: #173042;
}
.diary-groups-grid {
display: grid;
grid-template-columns: 1.4fr 1fr;

View File

@@ -68,6 +68,12 @@
<label for="trainingEnd">{{ $t('diary.trainingEnd') }}:</label>
<input type="time" step="300" id="trainingEnd" v-model="trainingEnd" />
</div>
<div>
<label for="excludeFromBilling" style="display: inline-flex; align-items: center; gap: 0.4rem;">
<input type="checkbox" id="excludeFromBilling" v-model="excludeFromBilling" />
<span>Nicht abrechnen</span>
</label>
</div>
<button type="submit">{{ $t('diary.createDate') }}</button>
</form>
</div>
@@ -83,6 +89,7 @@
:activities-count="activities.length"
:training-start="trainingStart"
:training-end="trainingEnd"
:exclude-from-billing="excludeFromBilling"
:groups="groups"
:editing-group-id="editingGroupId"
:new-group-count="newGroupCount"
@@ -90,6 +97,7 @@
@update-training-times="updateTrainingTimes"
@update:training-start="trainingStart = $event"
@update:training-end="trainingEnd = $event"
@update:exclude-from-billing="excludeFromBilling = $event"
@edit-group="editGroup"
@update-group-field="updateGroupField"
@save-group="saveGroup"
@@ -977,6 +985,7 @@ export default {
newDate: '',
trainingStart: '',
trainingEnd: '',
excludeFromBilling: false,
members: [],
participants: [],
showTrainingGroupDialog: false,
@@ -1780,6 +1789,7 @@ export default {
date: slot.date,
trainingStart: slot.startTime || null,
trainingEnd: slot.endTime || null,
excludeFromBilling: false,
});
await this.refreshDates(post.data.id);
await this.handleDateChange();
@@ -1799,6 +1809,7 @@ export default {
const dateData = response.data.find(entry => entry.id === dateId);
this.trainingStart = dateData.trainingStart;
this.trainingEnd = dateData.trainingEnd;
this.excludeFromBilling = Boolean(dateData.excludeFromBilling);
this.selectedActivityTags = dateData.diaryTags.map(tag => ({
id: tag.id,
name: tag.name
@@ -1816,6 +1827,7 @@ export default {
this.newDate = '';
this.trainingStart = '';
this.trainingEnd = '';
this.excludeFromBilling = false;
this.participants = [];
}
},
@@ -1836,6 +1848,7 @@ export default {
date: this.newDate,
trainingStart: this.trainingStart || null,
trainingEnd: this.trainingEnd || null,
excludeFromBilling: this.excludeFromBilling,
});
this.dates.push({ id: response.data.id, date: response.data.date });
// Liste nach Datum sortieren (neueste zuerst)
@@ -1844,6 +1857,7 @@ export default {
this.newDate = '';
this.trainingStart = response.data.trainingStart;
this.trainingEnd = response.data.trainingEnd;
this.excludeFromBilling = Boolean(response.data.excludeFromBilling);
// Direkt auf das leere Tagebuch des neuen Datums wechseln
await this.handleDateChange();
} catch (error) {
@@ -1858,6 +1872,7 @@ export default {
dateId,
trainingStart: this.trainingStart || null,
trainingEnd: this.trainingEnd || null,
excludeFromBilling: this.excludeFromBilling,
});
this.showInfo(this.$t('messages.success'), this.$t('diary.trainingTimesUpdated'), '', 'success');
} catch (error) {
@@ -4332,6 +4347,9 @@ export default {
if (data.updates.trainingEnd !== undefined) {
this.trainingEnd = data.updates.trainingEnd;
}
if (data.updates.excludeFromBilling !== undefined) {
this.excludeFromBilling = Boolean(data.updates.excludeFromBilling);
}
}
},