calendar and vehicle booking rework
This commit is contained in:
@@ -226,8 +226,8 @@ class BookingController {
|
||||
const isOwner = booking.gebucht_von === req.user!.id;
|
||||
const groups: string[] = req.user?.groups ?? [];
|
||||
const isAdmin = groups.includes('dashboard_admin');
|
||||
const canCancelOwn = isAdmin || permissionService.hasPermission(groups, 'kalender:manage_bookings');
|
||||
const canCancelAny = isAdmin || permissionService.hasPermission(groups, 'kalender:manage_bookings');
|
||||
const canCancelOwn = isAdmin || permissionService.hasPermission(groups, 'fahrzeugbuchungen:manage');
|
||||
const canCancelAny = isAdmin || permissionService.hasPermission(groups, 'fahrzeugbuchungen:manage');
|
||||
|
||||
if (!(isOwner && canCancelOwn) && !canCancelAny) {
|
||||
res.status(403).json({ success: false, message: 'Keine Berechtigung' });
|
||||
|
||||
@@ -18,15 +18,15 @@ router.get('/calendar-token', authenticate, bookingController.getCalendarToken.b
|
||||
|
||||
// ── Write operations ──────────────────────────────────────────────────────────
|
||||
|
||||
router.post('/', authenticate, requirePermission('kalender:manage_bookings'), bookingController.create.bind(bookingController));
|
||||
router.patch('/:id', authenticate, requirePermission('kalender:manage_bookings'), bookingController.update.bind(bookingController));
|
||||
router.post('/', authenticate, requirePermission('fahrzeugbuchungen:create'), bookingController.create.bind(bookingController));
|
||||
router.patch('/:id', authenticate, requirePermission('fahrzeugbuchungen:manage'), bookingController.update.bind(bookingController));
|
||||
|
||||
// Soft-cancel (sets abgesagt=TRUE) — creator or bookings:write
|
||||
router.delete('/:id', authenticate, bookingController.cancel.bind(bookingController));
|
||||
router.patch('/:id/cancel', authenticate, bookingController.cancel.bind(bookingController));
|
||||
|
||||
// Hard-delete (admin only)
|
||||
router.delete('/:id/force', authenticate, requirePermission('kalender:manage_bookings'), bookingController.hardDelete.bind(bookingController));
|
||||
router.delete('/:id/force', authenticate, requirePermission('fahrzeugbuchungen:manage'), bookingController.hardDelete.bind(bookingController));
|
||||
|
||||
// ── Single booking read — after specific routes to avoid path conflicts ───────
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const router = Router();
|
||||
router.get(
|
||||
'/',
|
||||
authenticate,
|
||||
requirePermission('kalender:view_bookings'),
|
||||
requirePermission('fahrzeugbuchungen:view'),
|
||||
buchungskategorieController.list.bind(buchungskategorieController)
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@ router.get(
|
||||
router.get(
|
||||
'/active',
|
||||
authenticate,
|
||||
requirePermission('kalender:view_bookings'),
|
||||
requirePermission('fahrzeugbuchungen:view'),
|
||||
buchungskategorieController.listActive.bind(buchungskategorieController)
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ router.get(
|
||||
router.post(
|
||||
'/',
|
||||
authenticate,
|
||||
requirePermission('kalender:manage_bookings'),
|
||||
requirePermission('fahrzeugbuchungen:manage'),
|
||||
buchungskategorieController.create.bind(buchungskategorieController)
|
||||
);
|
||||
|
||||
@@ -33,7 +33,7 @@ router.post(
|
||||
router.patch(
|
||||
'/:id',
|
||||
authenticate,
|
||||
requirePermission('kalender:manage_bookings'),
|
||||
requirePermission('fahrzeugbuchungen:manage'),
|
||||
buchungskategorieController.update.bind(buchungskategorieController)
|
||||
);
|
||||
|
||||
@@ -41,7 +41,7 @@ router.patch(
|
||||
router.delete(
|
||||
'/:id',
|
||||
authenticate,
|
||||
requirePermission('kalender:manage_bookings'),
|
||||
requirePermission('fahrzeugbuchungen:manage'),
|
||||
buchungskategorieController.deactivate.bind(buchungskategorieController)
|
||||
);
|
||||
|
||||
@@ -49,7 +49,7 @@ router.delete(
|
||||
router.delete(
|
||||
'/:id/permanent',
|
||||
authenticate,
|
||||
requirePermission('kalender:manage_bookings'),
|
||||
requirePermission('fahrzeugbuchungen:manage'),
|
||||
buchungskategorieController.remove.bind(buchungskategorieController)
|
||||
);
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@ const DEFAULT_GROUP_HIERARCHY: Record<string, string[]> = {
|
||||
|
||||
const DEFAULT_PERMISSION_DEPS: Record<string, string[]> = {
|
||||
'kalender:create': ['kalender:view'],
|
||||
'kalender:view_bookings': ['kalender:view'],
|
||||
'kalender:manage_bookings': ['kalender:view', 'kalender:view_bookings'],
|
||||
'kalender:widget_events': ['kalender:view'],
|
||||
'kalender:widget_bookings': ['kalender:view'],
|
||||
'kalender:widget_quick_add': ['kalender:view', 'kalender:create'],
|
||||
'fahrzeugbuchungen:create': ['fahrzeugbuchungen:view'],
|
||||
'fahrzeugbuchungen:manage': ['fahrzeugbuchungen:view', 'fahrzeugbuchungen:create'],
|
||||
'fahrzeugbuchungen:widget': ['fahrzeugbuchungen:view'],
|
||||
'fahrzeuge:create': ['fahrzeuge:view'],
|
||||
'fahrzeuge:change_status': ['fahrzeuge:view'],
|
||||
'fahrzeuge:manage_maintenance': ['fahrzeuge:view'],
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
ExpandLess,
|
||||
LocalShipping,
|
||||
BugReport,
|
||||
BookOnline,
|
||||
} from '@mui/icons-material';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
@@ -49,11 +50,6 @@ interface NavigationItem {
|
||||
permission?: string;
|
||||
}
|
||||
|
||||
const kalenderSubItems: SubItem[] = [
|
||||
{ text: 'Veranstaltungen', path: '/kalender' },
|
||||
{ text: 'Fahrzeugbuchungen', path: '/fahrzeugbuchungen' },
|
||||
];
|
||||
|
||||
const adminSubItems: SubItem[] = [
|
||||
{ text: 'Services', path: '/admin?tab=0' },
|
||||
{ text: 'System', path: '/admin?tab=1' },
|
||||
@@ -77,9 +73,14 @@ const baseNavigationItems: NavigationItem[] = [
|
||||
text: 'Kalender',
|
||||
icon: <CalendarMonth />,
|
||||
path: '/kalender',
|
||||
subItems: kalenderSubItems,
|
||||
permission: 'kalender:view',
|
||||
},
|
||||
{
|
||||
text: 'Fahrzeugbuchungen',
|
||||
icon: <BookOnline />,
|
||||
path: '/fahrzeugbuchungen',
|
||||
permission: 'fahrzeugbuchungen:view',
|
||||
},
|
||||
{
|
||||
text: 'Fahrzeuge',
|
||||
icon: <DirectionsCar />,
|
||||
|
||||
@@ -170,7 +170,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{hasPermission('kalender:view_bookings') && widgetVisible('vehicleBookingList') && (
|
||||
{hasPermission('fahrzeugbuchungen:view') && widgetVisible('vehicleBookingList') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '520ms' }}>
|
||||
<Box>
|
||||
<VehicleBookingListWidget />
|
||||
@@ -178,7 +178,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{hasPermission('kalender:manage_bookings') && widgetVisible('vehicleBooking') && (
|
||||
{hasPermission('fahrzeugbuchungen:manage') && widgetVisible('vehicleBooking') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '560ms' }}>
|
||||
<Box>
|
||||
<VehicleBookingQuickAddWidget />
|
||||
|
||||
@@ -98,8 +98,8 @@ function FahrzeugBuchungen() {
|
||||
const navigate = useNavigate();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const canCreate = hasPermission('kalender:create');
|
||||
const canManage = hasPermission('kalender:manage_bookings');
|
||||
const canCreate = hasPermission('fahrzeugbuchungen:create');
|
||||
const canManage = hasPermission('fahrzeugbuchungen:manage');
|
||||
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user