diff --git a/backend/src/database/migrations/045_add_permissions_batch.sql b/backend/src/database/migrations/045_add_permissions_batch.sql index bbabe6f..a2a5b20 100644 --- a/backend/src/database/migrations/045_add_permissions_batch.sql +++ b/backend/src/database/migrations/045_add_permissions_batch.sql @@ -36,12 +36,26 @@ INSERT INTO permissions (id, feature_group_id, label, description, sort_order) V ('admin:write', 'admin', 'Bearbeiten', 'Admin-Einstellungen ändern', 2) ON CONFLICT (id) DO NOTHING; --- Re-seed wissen grants for all groups (in case they were cascade-deleted) -INSERT INTO group_permissions (authentik_group, permission_id) -SELECT DISTINCT authentik_group, 'wissen:view' -FROM group_permissions -WHERE authentik_group LIKE 'dashboard_%' -ON CONFLICT DO NOTHING; +-- Re-seed wissen + vikunja + dashboard grants for all dashboard groups +-- (these may have been cascade-deleted when feature groups were missing) +DO $$ +DECLARE + grp TEXT; +BEGIN + FOR grp IN + SELECT DISTINCT authentik_group FROM group_permissions WHERE authentik_group LIKE 'dashboard_%' + LOOP + -- wissen permissions for everyone + INSERT INTO group_permissions (authentik_group, permission_id) + VALUES (grp, 'wissen:view'), (grp, 'wissen:widget_recent'), (grp, 'wissen:widget_search') + ON CONFLICT DO NOTHING; + + -- dashboard widget permissions for everyone + INSERT INTO group_permissions (authentik_group, permission_id) + VALUES (grp, 'dashboard:widget_links'), (grp, 'dashboard:widget_banner') + ON CONFLICT DO NOTHING; + END LOOP; +END $$; -- ═══════════════════════════════════════════════════════════════════════════ -- 1. New permissions diff --git a/frontend/src/components/dashboard/BookStackRecentWidget.tsx b/frontend/src/components/dashboard/BookStackRecentWidget.tsx index c84c297..cf6cb43 100644 --- a/frontend/src/components/dashboard/BookStackRecentWidget.tsx +++ b/frontend/src/components/dashboard/BookStackRecentWidget.tsx @@ -79,7 +79,9 @@ const BookStackRecentWidget: React.FC = () => { const configured = data?.configured ?? false; const pages = (data?.data ?? []).slice(0, 5); - if (!configured) { + // Only show "nicht eingerichtet" when we got a successful response with configured=false + // (not when the request errored out with 403 etc.) + if (data && !configured) { return ( diff --git a/frontend/src/components/dashboard/BookStackSearchWidget.tsx b/frontend/src/components/dashboard/BookStackSearchWidget.tsx index 69a768c..7253756 100644 --- a/frontend/src/components/dashboard/BookStackSearchWidget.tsx +++ b/frontend/src/components/dashboard/BookStackSearchWidget.tsx @@ -75,7 +75,7 @@ const BookStackSearchWidget: React.FC = () => { return () => { isMountedRef.current = false; }; }, []); - const { data, isLoading: configLoading } = useQuery({ + const { data, isLoading: configLoading, isError: configError } = useQuery({ queryKey: ['bookstack-recent'], queryFn: () => bookstackApi.getRecent(), refetchInterval: 5 * 60 * 1000, @@ -83,7 +83,8 @@ const BookStackSearchWidget: React.FC = () => { }); // undefined while loading, true/false once known - const configured = configLoading ? undefined : (data?.configured ?? false); + // On error (e.g. 403), treat as configured to avoid "nicht eingerichtet" message + const configured = configLoading ? undefined : configError ? true : (data?.configured ?? false); useEffect(() => { if (debounceRef.current) clearTimeout(debounceRef.current); diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index f05b402..6d5d958 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -187,7 +187,7 @@ function Dashboard() { {/* Dienste Group */} - {hasPermission('wissen:widget_recent') && widgetVisible('bookstackRecent') && ( + {hasPermission('wissen:view') && widgetVisible('bookstackRecent') && ( @@ -195,7 +195,7 @@ function Dashboard() { )} - {hasPermission('wissen:widget_search') && widgetVisible('bookstackSearch') && ( + {hasPermission('wissen:view') && widgetVisible('bookstackSearch') && (