rights system
This commit is contained in:
@@ -10,7 +10,7 @@ import BannerManagementTab from '../components/admin/BannerManagementTab';
|
||||
import ServiceModeTab from '../components/admin/ServiceModeTab';
|
||||
import FdiskSyncTab from '../components/admin/FdiskSyncTab';
|
||||
import PermissionMatrixTab from '../components/admin/PermissionMatrixTab';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { usePermissionContext } from '../contexts/PermissionContext';
|
||||
|
||||
interface TabPanelProps {
|
||||
children: React.ReactNode;
|
||||
@@ -37,11 +37,9 @@ function AdminDashboard() {
|
||||
const t = Number(searchParams.get('tab'));
|
||||
if (t >= 0 && t < ADMIN_TAB_COUNT) setTab(t);
|
||||
}, [searchParams]);
|
||||
const { user } = useAuth();
|
||||
const { hasPermission } = usePermissionContext();
|
||||
|
||||
const isAdmin = user?.groups?.includes('dashboard_admin') ?? false;
|
||||
|
||||
if (!isAdmin) {
|
||||
if (!hasPermission('admin:view')) {
|
||||
return <Navigate to="/dashboard" replace />;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import { WidgetKey } from '../constants/widgets';
|
||||
|
||||
function Dashboard() {
|
||||
const { user } = useAuth();
|
||||
const { hasPermission, isAdmin } = usePermissionContext();
|
||||
const { hasPermission } = usePermissionContext();
|
||||
const [dataLoading, setDataLoading] = useState(true);
|
||||
|
||||
const { data: preferences } = useQuery({
|
||||
@@ -99,7 +99,7 @@ function Dashboard() {
|
||||
|
||||
{/* Status Group */}
|
||||
<WidgetGroup title="Status" gridColumn="1 / -1">
|
||||
{widgetVisible('vehicles') && (
|
||||
{hasPermission('fahrzeuge:widget') && widgetVisible('vehicles') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '300ms' }}>
|
||||
<Box>
|
||||
<VehicleDashboardCard />
|
||||
@@ -107,7 +107,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{widgetVisible('equipment') && (
|
||||
{hasPermission('ausruestung:widget') && widgetVisible('equipment') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '350ms' }}>
|
||||
<Box>
|
||||
<EquipmentDashboardCard />
|
||||
@@ -123,7 +123,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{isAdmin && widgetVisible('adminStatus') && (
|
||||
{hasPermission('admin:view') && widgetVisible('adminStatus') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '440ms' }}>
|
||||
<Box>
|
||||
<AdminStatusWidget />
|
||||
@@ -134,7 +134,7 @@ function Dashboard() {
|
||||
|
||||
{/* Kalender Group */}
|
||||
<WidgetGroup title="Kalender" gridColumn="1 / -1">
|
||||
{widgetVisible('events') && (
|
||||
{hasPermission('kalender:widget_events') && widgetVisible('events') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '480ms' }}>
|
||||
<Box>
|
||||
<UpcomingEventsWidget />
|
||||
@@ -142,7 +142,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{widgetVisible('vehicleBookingList') && (
|
||||
{hasPermission('kalender:widget_bookings') && widgetVisible('vehicleBookingList') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '520ms' }}>
|
||||
<Box>
|
||||
<VehicleBookingListWidget />
|
||||
@@ -150,7 +150,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{widgetVisible('vehicleBooking') && (
|
||||
{hasPermission('kalender:create_bookings') && widgetVisible('vehicleBooking') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '560ms' }}>
|
||||
<Box>
|
||||
<VehicleBookingQuickAddWidget />
|
||||
@@ -169,7 +169,7 @@ function Dashboard() {
|
||||
|
||||
{/* Dienste Group */}
|
||||
<WidgetGroup title="Dienste" gridColumn="1 / -1">
|
||||
{widgetVisible('bookstackRecent') && (
|
||||
{hasPermission('wissen:widget_recent') && widgetVisible('bookstackRecent') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '600ms' }}>
|
||||
<Box>
|
||||
<BookStackRecentWidget />
|
||||
@@ -177,7 +177,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{widgetVisible('bookstackSearch') && (
|
||||
{hasPermission('wissen:widget_search') && widgetVisible('bookstackSearch') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '640ms' }}>
|
||||
<Box>
|
||||
<BookStackSearchWidget />
|
||||
@@ -185,7 +185,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{widgetVisible('vikunjaTasks') && (
|
||||
{hasPermission('vikunja:widget_tasks') && widgetVisible('vikunjaTasks') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '680ms' }}>
|
||||
<Box>
|
||||
<VikunjaMyTasksWidget />
|
||||
@@ -193,7 +193,7 @@ function Dashboard() {
|
||||
</Fade>
|
||||
)}
|
||||
|
||||
{widgetVisible('vikunjaQuickAdd') && (
|
||||
{hasPermission('vikunja:widget_quick_add') && widgetVisible('vikunjaQuickAdd') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: '720ms' }}>
|
||||
<Box>
|
||||
<VikunjaQuickAddWidget />
|
||||
@@ -204,7 +204,7 @@ function Dashboard() {
|
||||
|
||||
{/* Information Group */}
|
||||
<WidgetGroup title="Information" gridColumn="1 / -1">
|
||||
{widgetVisible('links') && linkCollections.map((collection, idx) => (
|
||||
{hasPermission('dashboard:widget_links') && widgetVisible('links') && linkCollections.map((collection, idx) => (
|
||||
<Fade key={collection.id} in={!dataLoading} timeout={600} style={{ transitionDelay: `${760 + idx * 40}ms` }}>
|
||||
<Box>
|
||||
<LinksWidget collection={collection} />
|
||||
@@ -212,11 +212,13 @@ function Dashboard() {
|
||||
</Fade>
|
||||
))}
|
||||
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: `${760 + linkCollections.length * 40}ms` }}>
|
||||
<Box>
|
||||
<BannerWidget />
|
||||
</Box>
|
||||
</Fade>
|
||||
{hasPermission('dashboard:widget_banner') && (
|
||||
<Fade in={!dataLoading} timeout={600} style={{ transitionDelay: `${760 + linkCollections.length * 40}ms` }}>
|
||||
<Box>
|
||||
<BannerWidget />
|
||||
</Box>
|
||||
</Fade>
|
||||
)}
|
||||
</WidgetGroup>
|
||||
</Box>
|
||||
</Container>
|
||||
|
||||
@@ -96,6 +96,7 @@ function FahrzeugBuchungen() {
|
||||
const notification = useNotification();
|
||||
const canCreate = hasPermission('kalender:create_bookings');
|
||||
const canWrite = hasPermission('kalender:edit_bookings');
|
||||
const canCancelOwn = hasPermission('kalender:cancel_own_bookings');
|
||||
const canChangeBuchungsArt = hasPermission('kalender:manage_categories');
|
||||
|
||||
// ── Week navigation ────────────────────────────────────────────────────────
|
||||
@@ -691,7 +692,7 @@ function FahrzeugBuchungen() {
|
||||
Von: {detailBooking.gebucht_von_name}
|
||||
</Typography>
|
||||
)}
|
||||
{(canWrite || detailBooking.gebucht_von === user?.id) && (
|
||||
{(canWrite || (canCancelOwn && detailBooking.gebucht_von === user?.id)) && (
|
||||
<Box sx={{ mt: 1.5, display: 'flex', gap: 1 }}>
|
||||
{canWrite && (
|
||||
<Button
|
||||
|
||||
@@ -1707,7 +1707,7 @@ export default function Kalender() {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
|
||||
const canWriteEvents = hasPermission('kalender:create_events');
|
||||
const canWriteEvents = hasPermission('kalender:create');
|
||||
const canWriteBookings = hasPermission('kalender:edit_bookings');
|
||||
const canCreateBookings = hasPermission('kalender:create_bookings');
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ function Mitglieder() {
|
||||
// --- redirect non-privileged users to their own profile ---
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
if (!hasPermission('mitglieder:edit')) {
|
||||
if (!hasPermission('mitglieder:view_all')) {
|
||||
navigate(`/mitglieder/${(user as any).id}`, { replace: true });
|
||||
}
|
||||
}, [user, navigate, hasPermission]);
|
||||
|
||||
@@ -1074,7 +1074,7 @@ export default function Veranstaltungen() {
|
||||
const theme = useTheme();
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
|
||||
const canWrite = hasPermission('kalender:create_events');
|
||||
const canWrite = hasPermission('kalender:create');
|
||||
|
||||
const today = new Date();
|
||||
const [viewMonth, setViewMonth] = useState({ year: today.getFullYear(), month: today.getMonth() });
|
||||
|
||||
Reference in New Issue
Block a user