Time Changes
Some checks failed
Build and Push Docker Images / verify-docs-sync (push) Failing after 9s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Has been skipped
Build and Push Docker Images / build-docs (push) Has been skipped

This commit is contained in:
2026-04-27 09:17:36 +02:00
parent bb61caed6d
commit a021d3d15c
7 changed files with 113 additions and 27 deletions

View File

@@ -12,7 +12,7 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue', 'saved'])
// 💡 createEntry importieren
const { update, createEntry } = useStaffTime()
const { list, update, createEntry } = useStaffTime()
const { $dayjs } = useNuxtApp()
const toast = useToast()
@@ -85,7 +85,7 @@ async function onSubmit(event: FormSubmitEvent<any>) {
if (state.end_date && state.end_time) {
endIso = $dayjs(`${state.end_date} ${state.end_time}`).toISOString()
if ($dayjs(endIso).isBefore($dayjs(startIso))) {
if (!$dayjs(endIso).isAfter($dayjs(startIso))) {
throw new Error("Endzeitpunkt muss nach dem Startzeitpunkt liegen.")
}
}
@@ -100,6 +100,33 @@ async function onSubmit(event: FormSubmitEvent<any>) {
})
toast.add({ title: 'Eintrag aktualisiert', color: 'green' })
} else {
if (endIso) {
const existingEntries = await list({
user_id: props.defaultUserId
})
const newStart = $dayjs(startIso).valueOf()
const newEnd = $dayjs(endIso).valueOf()
const blockingStates = new Set(['draft', 'factual', 'submitted', 'approved'])
const conflictingEntry = existingEntries.find(existingEntry => {
if (!blockingStates.has(existingEntry.state) || !existingEntry.stopped_at) return false
const existingStart = $dayjs(existingEntry.started_at).valueOf()
const existingEnd = $dayjs(existingEntry.stopped_at).valueOf()
if (!Number.isFinite(existingStart) || !Number.isFinite(existingEnd)) return false
return newStart < existingEnd && existingStart < newEnd
})
if (conflictingEntry) {
const conflictStart = $dayjs(conflictingEntry.started_at).format('DD.MM.YYYY HH:mm')
const conflictEnd = $dayjs(conflictingEntry.stopped_at).format('DD.MM.YYYY HH:mm')
throw new Error(`Überschneidung mit ${conflictStart} bis ${conflictEnd} (${conflictingEntry.state}).`)
}
}
// 🟢 CREATE (Neu Erstellen)
// 💡 HIER WAR DER FEHLER: Wir nutzen jetzt createEntry mit den Daten aus dem Formular
await createEntry({

View File

@@ -26,7 +26,7 @@ export const useStaffTime = () => {
duration_minutes: end.diff(start, 'minute'),
user_id: targetUserId,
type: span.type,
description: span.payload?.description || ''
description: span.description || span.payload?.description || ''
}
}).sort((a: any, b: any) => $dayjs(b.started_at).valueOf() - $dayjs(a.started_at).valueOf())
} catch (error) {
@@ -126,4 +126,4 @@ export const useStaffTime = () => {
}
return { list, start, stop, submit, approve, reject, update, createEntry }
}
}

View File

@@ -272,7 +272,7 @@ onMounted(async () => {
<UTooltip text="Genehmigen" v-if="row.original.state === 'submitted' && canViewAll">
<UButton size="xs" color="green" variant="ghost" icon="i-heroicons-check" @click="handleApprove(row.original)" :loading="loading" />
</UTooltip>
<UTooltip text="Ablehnen" v-if="(row.original.state === 'submitted' || row.original.state === 'approved') && canViewAll">
<UTooltip text="Ablehnen" v-if="['draft', 'factual', 'submitted', 'approved'].includes(row.original.state) && canViewAll">
<UButton size="xs" color="error" variant="ghost" icon="i-heroicons-x-mark" @click="openRejectModal(row.original)" :loading="loading" />
</UTooltip>
<UTooltip text="Bearbeiten" v-if="['draft', 'factual', 'submitted'].includes(row.original.state)">
@@ -366,7 +366,7 @@ onMounted(async () => {
/>
<UButton
v-if="(entry.state === 'submitted' || entry.state === 'approved') && canViewAll"
v-if="['draft', 'factual', 'submitted', 'approved'].includes(entry.state) && canViewAll"
size="xs" color="error" variant="ghost" icon="i-heroicons-x-mark" label="Ablehnen"
@click="openRejectModal(entry)" :loading="loading"
/>
@@ -434,6 +434,7 @@ onMounted(async () => {
<div class="flex gap-2 mt-3 justify-end">
<UButton v-if="(row.state === 'draft' || row.state === 'factual') && row.stopped_at" color="cyan" size="sm" icon="i-heroicons-paper-airplane" label="Einreichen" variant="soft" @click.stop="handleSubmit(row)" :loading="loading" />
<UButton v-if="row.state === 'submitted' && canViewAll" color="green" size="sm" icon="i-heroicons-check" label="Genehmigen" variant="soft" @click.stop="handleApprove(row)" :loading="loading" />
<UButton v-if="['draft', 'factual', 'submitted', 'approved'].includes(row.state) && canViewAll" color="error" size="sm" icon="i-heroicons-x-mark" label="Ablehnen" variant="soft" @click.stop="openRejectModal(row)" :loading="loading" />
</div>
</UCard>
</UDashboardPanelContent>