feat(buchung): Buchungen kopieren
Duplizieren-Button im Bearbeiten-Dialog und Kopier-Icon je Buchung in Liste und Wochenansicht. Die Kopie oeffnet den Dialog als neue Buchung fuer heute mit Projekt, Task, Notiz und Zeit der Vorlage. Inaktive Projekte oder Tasks fallen auf die Standardauswahl zurueck. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b6ba7860bf
commit
2b9b7a6ae3
@@ -53,7 +53,7 @@ export const Booking: React.FC = () => {
|
||||
const [mode, setMode] = usePersistentState<BookingMode>('pulse_booking_mode', 'week');
|
||||
const [layout, setLayout] = usePersistentState<BookingLayout>('pulse_booking_layout', 'calendar');
|
||||
const [anchor, setAnchor] = useState(todayIso());
|
||||
const [modal, setModal] = useState<{ date: string; entry?: TimeEntry | null } | null>(null);
|
||||
const [modal, setModal] = useState<{ date: string; entry?: TimeEntry | null; template?: TimeEntry | null } | null>(null);
|
||||
const [exportOpen, setExportOpen] = useState(false);
|
||||
const [viewUserId, setViewUserId] = useState<number>(user!.id);
|
||||
const isLead = atLeast(user, 'lead');
|
||||
@@ -100,6 +100,12 @@ export const Booking: React.FC = () => {
|
||||
setModal({ date: date ?? (today >= range.from && today <= range.to ? today : range.from) });
|
||||
};
|
||||
|
||||
/** Kopie einer Buchung als neue Buchung fuer heute; Datum ist im Dialog aenderbar. */
|
||||
const copy = (entry: TimeEntry) => {
|
||||
if (readOnly) return;
|
||||
setModal({ date: today, template: entry });
|
||||
};
|
||||
|
||||
/*
|
||||
* Im Export stehen nur die eigenen Projekte zur Wahl - auch fuer
|
||||
* Vorgesetzte. Wer einen Nachweis fuer einen Kunden erstellt, filtert nach
|
||||
@@ -228,12 +234,13 @@ export const Booking: React.FC = () => {
|
||||
<EntryList
|
||||
entries={list}
|
||||
onEdit={readOnly ? undefined : (entry) => setModal({ date: entry.entry_date, entry })}
|
||||
onCopy={readOnly ? undefined : copy}
|
||||
emptyText={`Keine Buchungen ${mode === 'week' ? 'in dieser Woche' : mode === 'month' ? 'in diesem Monat' : 'in diesem Jahr'}.`}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
{layout === 'calendar' && mode === 'week' && (
|
||||
<WeekView from={range.from} entries={list} readOnly={readOnly} dailyTarget={(weekly / 5) * 60} onAdd={openNew} onEdit={(entry) => !readOnly && setModal({ date: entry.entry_date, entry })} />
|
||||
<WeekView from={range.from} entries={list} readOnly={readOnly} dailyTarget={(weekly / 5) * 60} onAdd={openNew} onEdit={(entry) => !readOnly && setModal({ date: entry.entry_date, entry })} onCopy={copy} />
|
||||
)}
|
||||
{layout === 'calendar' && mode === 'month' && (
|
||||
<MonthView
|
||||
@@ -273,7 +280,16 @@ export const Booking: React.FC = () => {
|
||||
)}
|
||||
|
||||
{modal && projects.data && (
|
||||
<EntryModal projects={projects.data} date={modal.date} entry={modal.entry} onClose={() => setModal(null)} onSaved={() => { entries.reload(); projects.reload(); }} />
|
||||
<EntryModal
|
||||
key={modal.entry?.id ?? `new-${modal.template?.id ?? ''}`}
|
||||
projects={projects.data}
|
||||
date={modal.date}
|
||||
entry={modal.entry}
|
||||
template={modal.template}
|
||||
onClose={() => setModal(null)}
|
||||
onSaved={() => { entries.reload(); projects.reload(); }}
|
||||
onDuplicate={copy}
|
||||
/>
|
||||
)}
|
||||
{exportOpen && (
|
||||
<ExportDialog
|
||||
|
||||
Reference in New Issue
Block a user