Search code examples
reactjsreact-hookspermissionsroles

How to get permissions from other file js in react


I have fetched the following data from the server and stored it in Redux

[
    {
        "resourceId": 1,
        "resourceAction": "UserInsert",
        "resourceController": "Home",
        "resourceTitle": "ثبت کاربر"
    },
    {
        "resourceId": 4,
        "resourceAction": "ChangePassword",
        "resourceController": "Home",
        "resourceTitle": "تغییر کلمه عبور"
    },
    {
        "resourceId": 5,
        "resourceAction": "UserEdit",
        "resourceController": "Home",
        "resourceTitle": "ویرایش کاربر"
    },
    {
        "resourceId": 6,
        "resourceAction": "UserDelete",
        "resourceController": "Home",
        "resourceTitle": "حذف کاربر"
    },
    {
        "resourceId": 18,
        "resourceAction": "*",
        "resourceController": "*",
        "resourceTitle": "همه"
    }
]

I want write all conditions in a seprate js file and use each condition result in components.

my persmission.js file is

//REDUX IMPORT
import { useDispatch, useSelector } from "react-redux";

//redux data
const permissions = useSelector((state) => state.permissions.data);

export const canAll = permissions.resourceController == '*';
export const canInsertUser = (permissions.resourceAction == 'UserInsert' && permissions.resourceController == 'Home') || canAll;

How can i export each condition's result and use in other components?


Solution

  • You can create a custom hook which is called usePermission. This hook will get a permission as a enum and return a bool value as a result. Also there is a problem in this line of code which I've updated it:

    const permissions = useSelector((state) => state.permissions.data); //=> permssions is array and you can not use it like this : permissions.resourceController
    

    Here's the sample implementation of the functionality which you need:

    import { useDispatch, useSelector } from "react-redux";
    
    export const permissionEnum = Object.freeze({
            canAll: 'canAll',
            canInsertUser: 'canInsertUser',
            //... => other permissions
    });
    
    export const usePermission = () =>
    {
       const permissionArray = [];
       const permissions = useSelector((state) => state.permissions.data);
       if(permissions.some((permission) => permission.resourceController == '*'))
         permissionArray.push(permissionEnum.canAll);
       if(permissions.some((permission) => (permissions.resourceAction == 'UserInsert' && permissions.resourceController == 'Home'))
         permissionArray.push(permissionEnum.canInsertUser);
       //... => other conditions
      
      return permissionArray;
    }
    
    export const hasPermission = (permissionValue) =>
    { 
      const permissions = usePermission();
      return permissions.some((permission)=> permission == permissionValue);
    }
    

    So, you can use it in a sample component like this:

    import { usePermission, hasPermission, permissionEnum } from './permission.js';
    
    const SampleComponent = (props) =>
    {
       // if you just need all permissions in an array :
       const permissions = usePermission();
       // if you need check a specific permission : 
       const canAll = hasPermission(permissionEnum.canAll);
       //...
    }