0

A custom ReactJS wrapper component should be used to wrap code and only render it, if the user has the required permission. Therefore, it needs to accept two parameters, the children that shall be rendered as well as the permission it needs to check for.

The idea is to use it like this:

const AdminTools = () => {
  return (
    <RequirePermission require_permission="ui:see_admin_menu">
      <>
        <h1>Sudo mode</h1>
        <Link href="/intern/users/">
          <a>
            <ActionCard link>User management</ActionCard>
          </a>
        </Link>
      </>
    </RequirePermission>
  );

};

What I came up with so far is the following code:

const RequirePermission = (children: React.FC<{}>, required_permission: string) => {
    const user = useContext(AuthContext);

    let hasPermission = false;
    if (user.state == AuthState.Authorized) {

        user.user?.realm_access?.roles.forEach(role => {
            if (permissions[role].includes(required_permission)) {
                hasPermission = true;
            }
        });
    }

    if (hasPermission) {
        return children;
    } else {
        return <div />;
    }

};

export default RequirePermission;

When using the code snippet as described above, the following error is thrown:

    Type '{ children: Element; require_permission: string; }' is not assignable to type 'IntrinsicAttributes & FC<{}>'.
  Property 'children' does not exist on type 'IntrinsicAttributes & FC<{}>'.ts(2322)
'RequirePermission' cannot be used as a JSX component.
  Its return type 'FC<{}> | Element' is not a valid JSX element.
    Type 'FunctionComponent<{}>' is missing the following properties from type 'Element': type, props, keyts(2786)

I don't really understand the error message to be frank. Any help would be much appreciated.

//Edit:

Error messages given by proposed code:

This JSX tag's 'children' prop expects a single child of type 'ReactChildren', but multiple children were provided.ts(2746)

and

'RequirePermission' cannot be used as a JSX component.
  Its return type 'Element | ReactChildren' is not a valid JSX element.
    Type 'ReactChildren' is missing the following properties from type 'Element': type, props, key
1
  • 1
    ReactNode instead of ReactChildren? Commented May 16, 2022 at 16:06

1 Answer 1

3

Try this, importing ReactChildren from react.

I wish i could explain this better, but i know typescript is expecting a JSX/TSX element, so we could use ReactElement for the return type.

For a better explanation on the children type

https://stackoverflow.com/a/58123882/7174241

import React, { ReactChildren, ReactElement, ReactNode } from "react";

interface RequireType {
  children: ReactChildren | ReactNode | ReactElement;
  required_permission: string;
}

const RequirePermission = ({ children, required_permission }: RequireType):ReactElement => {
  const user = useContext(AuthContext);

  let hasPermission = false;
  if (user.state == AuthState.Authorized) {
    user.user?.realm_access?.roles.forEach((role) => {
      if (permissions[role].includes(required_permission)) {
        hasPermission = true;
      }
    });
  }

 return <>{hasPermission ? children : null}</>

};

export default RequirePermission;
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your answer! This changed code still yields two errors, I've edited them in the original question for better readability
try the updated answer..
Thank you @BARNOWL, this works absolutely perfect! I'll try to understand the changes and their behaviour now to learn a bit more myself. Thanks for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.