diff --git a/frontend/src/layout/TreeMenu/TreeMenu.js b/frontend/src/layout/TreeMenu/TreeMenu.js
index 9c6c03fa..4edc2f72 100644
--- a/frontend/src/layout/TreeMenu/TreeMenu.js
+++ b/frontend/src/layout/TreeMenu/TreeMenu.js
@@ -1,10 +1,11 @@
import React, { useState, useEffect, useMemo } from "react";
-import { useResourceDefinitions, Logout, Menu, useGetIdentity, MenuItemLink, useTranslate } from "react-admin";
+import { useResourceDefinitions, Logout, Menu, useGetIdentity, MenuItemLink, useTranslate, useAuthProvider } from "react-admin";
import { useLocation } from "react-router";
import { useMediaQuery, Divider } from "@mui/material";
import DefaultIcon from "@mui/icons-material/ViewList";
import LockOpenIcon from '@mui/icons-material/LockOpen';
import LoginIcon from '@mui/icons-material/Login';
+import { useCreateContainerUri } from "@semapps/semantic-data-provider";
import SubMenu from "./SubMenu";
import ResourceMenuLink from "./ResourceMenuLink";
@@ -17,6 +18,36 @@ const TreeMenu = () => {
[resourceDefinitions]
);
+ const [resourcesPermissions, setResourcesPermissions] = useState({});
+ const getCreateContainerUri = useCreateContainerUri();
+ const authProvider = useAuthProvider();
+
+ useEffect(() => {
+ const fetchPermissions = async () => {
+ const filteredResources = resources.filter(resource => resource.hasList);
+
+ const names = filteredResources.map(resource => resource.name);
+ const containersUri = filteredResources.map(resource => getCreateContainerUri(resource.name));
+
+ if (containersUri.every(uri => !uri)) {
+ return;
+ }
+
+ const permissions = await Promise.all(containersUri.map(containerUri => {
+ return authProvider.getPermissions(containerUri || {});
+ }));
+
+ const obj = names.reduce((acc, name, index) => {
+ acc[name] = permissions[index].some(p => p['acl:mode'] === 'acl:Read');
+ return acc;
+ }, {});
+
+ setResourcesPermissions(obj);
+ };
+
+ fetchPermissions();
+ }, [authProvider, resources, getCreateContainerUri]);
+
const location = useLocation();
const matches = location.pathname.match(/^\/([^/]+)/);
const currentResourceName = matches ? matches[1] : null;
@@ -40,13 +71,13 @@ const TreeMenu = () => {
// Calculate available categories
const categories = useMemo(() => {
const names = resources.reduce((categories, resource) => {
- if (resource.options?.parent) {
+ if (resource.options?.parent && resource.hasList && resourcesPermissions[resource.name]) {
categories.push(resource.options.parent);
}
return categories;
}, []);
return resources.filter((resource) => names.includes(resource.name));
- }, [resources]);
+ }, [resources, resourcesPermissions]);
// Open submenu of current page
useEffect(() => {
@@ -75,13 +106,13 @@ const TreeMenu = () => {
icon={menuRootItem.icon ? : }
>
{resources
- .filter(resource => resource.hasList && resource.options.parent === menuRootItem.name)
+ .filter(resource => resource.hasList && resourcesPermissions[resource.name] && resource.options.parent === menuRootItem.name)
.map(resource => (
))}
) : (
- menuRootItem.hasList && (
+ menuRootItem.hasList && resourcesPermissions[menuRootItem.name] && (
)
);
diff --git a/frontend/src/layout/list/ListView.js b/frontend/src/layout/list/ListView.js
index 3742ea09..7bce75ec 100644
--- a/frontend/src/layout/list/ListView.js
+++ b/frontend/src/layout/list/ListView.js
@@ -1,10 +1,18 @@
import React from 'react';
-import { useListContext, Pagination } from 'react-admin';
+import { useListContext, Pagination, useResourceContext } from 'react-admin';
import { Box } from '@mui/material';
+import { useCheckPermissions } from '@semapps/auth-provider';
+import { useCreateContainer } from '@semapps/semantic-data-provider';
import BaseView from "../BaseView";
const ListView = ({ title, children, aside, actions, pagination }) => {
const listContext = useListContext();
+
+ const resource = useResourceContext();
+ const containerUri = useCreateContainer(resource);
+
+ useCheckPermissions(containerUri, 'list');
+
return(