-
- {!automated && (
-
- )}
+
+
+ {!automated && reservation?.id && onDelete && (
+
+ )}
+
+
+
+ {!automated && (
+
+ )}
+
}
>
@@ -1245,6 +1258,20 @@ export function TransportModal({ isOpen, onClose, onSave, reservation, days, sel
)}
+
+
setShowDeleteConfirm(false)}
+ title={t('reservations.confirm.deleteTitle')}
+ message={t('reservations.confirm.deleteBody', { name: reservation?.title ?? '' })}
+ confirmLabel={t('common.delete')}
+ cancelLabel={t('common.cancel')}
+ onConfirm={async () => {
+ setShowDeleteConfirm(false)
+ await onDelete?.()
+ onClose()
+ }}
+ />
)
}
diff --git a/client/src/pages/TripPlannerPage.tsx b/client/src/pages/TripPlannerPage.tsx
index 59deb9195..a9455f057 100644
--- a/client/src/pages/TripPlannerPage.tsx
+++ b/client/src/pages/TripPlannerPage.tsx
@@ -1103,7 +1103,7 @@ function TripPlannerPageDesktop(): React.ReactElement | null {
{showTransportModal && (
- { if (importReviewActive) { advanceImportReview() } else { setShowTransportModal(false); setEditingTransport(null); setTransportModalDayId(null); setTransportModalAutomated(false); setTransitPrefill(null) } }} onSave={async (data) => { const r = await handleSaveTransport(data); if (importReviewActive && r) advanceImportReview(); return r }} reservation={editingTransport} prefill={transportPrefill} days={days} selectedDayId={transportModalDayId} files={files} onFileUpload={canUploadFiles ? (fd) => tripActions.addFile(tripId, fd) : undefined} onFileDelete={(id) => tripActions.deleteFile(tripId, id)} onOpenExpense={openBookingExpense} places={places} assignments={assignments} accommodations={tripAccommodations} initialAutomated={transportModalAutomated} transitPrefill={transitPrefill} tripHasDates={tripHasDates} tripMembers={tripMembers} />
+ { if (importReviewActive) { advanceImportReview() } else { setShowTransportModal(false); setEditingTransport(null); setTransportModalDayId(null); setTransportModalAutomated(false); setTransitPrefill(null) } }} onSave={async (data) => { const r = await handleSaveTransport(data); if (importReviewActive && r) advanceImportReview(); return r }} reservation={editingTransport} prefill={transportPrefill} days={days} selectedDayId={transportModalDayId} files={files} onFileUpload={canUploadFiles ? (fd) => tripActions.addFile(tripId, fd) : undefined} onFileDelete={(id) => tripActions.deleteFile(tripId, id)} onDelete={can('reservation_edit', trip) && editingTransport ? () => handleDeleteReservation(editingTransport.id) : undefined} onOpenExpense={openBookingExpense} places={places} assignments={assignments} accommodations={tripAccommodations} initialAutomated={transportModalAutomated} transitPrefill={transitPrefill} tripHasDates={tripHasDates} tripMembers={tripMembers} />
)}
diff --git a/client/src/pages/TripPlannerPage.wiring.test.tsx b/client/src/pages/TripPlannerPage.wiring.test.tsx
index e46add188..2b58563f9 100644
--- a/client/src/pages/TripPlannerPage.wiring.test.tsx
+++ b/client/src/pages/TripPlannerPage.wiring.test.tsx
@@ -1170,6 +1170,27 @@ describe('TripPlannerPage — modals', () => {
expect(tripActions.deleteFile).toHaveBeenCalledWith(42, 2)
})
+ it('FE-PAGE-TPW-053b: the transport edit window deletes the booking when the user may edit reservations', async () => {
+ const res = buildReservation({ id: 55, type: 'flight', title: 'LH 400' })
+ renderPage({ showTransportModal: true, editingTransport: res })
+
+ await act(async () => { await props('transportModal').onDelete() })
+ expect(hookState.handleDeleteReservation).toHaveBeenCalledWith(55)
+ })
+
+ it('FE-PAGE-TPW-053c: no transport delete without an edited booking or permission', () => {
+ renderPage({ showTransportModal: true })
+ expect(props('transportModal').onDelete).toBeUndefined()
+
+ cleanup()
+ renderPage({
+ showTransportModal: true,
+ editingTransport: buildReservation({ id: 55, type: 'flight' }),
+ can: vi.fn((action: string) => action !== 'reservation_edit'),
+ })
+ expect(props('transportModal').onDelete).toBeUndefined()
+ })
+
it('FE-PAGE-TPW-054: during a review the transport modal exits advance the queue too', async () => {
renderPage({ showTransportModal: true, importReviewActive: true })