React Admin 根据权限渲染资源

React Admin render resources based on permissions

我正在 firestore 之上构建一个带有 React admin 的管理界面。

firestore dataProvider 一切正常,但现在我想处理权限,并根据权限显示专家列表。

为了实现这一点,我决定使用 AdminContextAdminUI 实现自定义 Admin

我当前实现的预期行为:如果我没有登录,我首先被重定向到登录页面,然后根据权限 (usePermission),我决定呈现什么。

真实行为:即使未登录,AsyncResources 也会获取渲染,并且它会在权限检查时崩溃,因为它是 null。

function App() {
  return (
    <AdminContext authProvider={authProvider} dataProvider={dataProvider}>
      <AsyncResources />
    </AdminContext>
  );
}

基于授权用户权限的资源

function AsyncResources() {
  const [emails, setEmails] = useState<string[]>([]);
  const { loading, permissions } = usePermissions();

  useEffect(() => {
    (async () => {
      const experts = await firebase.firestore().collection("experts").get();
      const docIds: string[] = experts.docs.map((doc) => doc.id);
      setEmails(docIds);
    })();
  }, []);

  if (loading) {
    return (
      <AdminUI layout={CustomLayout} theme={theme}>
        <Loading
          loadingPrimary="WePractice Admin UI"
          loadingSecondary="Loading..."
        />
      </AdminUI>
    );
  }

  if (permissions.admin) {
    return (
      <AdminUI layout={CustomLayout} theme={theme}>
        {emails.map((email) => (
          <Resource
            key={email}
            options={{ label: `${email}` }}
            name={`experts/${email}/requests`}
            list={RequestList}
            edit={RequestEdit}
          />
        ))}
        <Resource name={`experts`} list={ExpertList} />
      </AdminUI>
    );
  }

  return (
    <AdminUI layout={CustomLayout} theme={theme}>
      <Resource
        options={{ label: `${permissions.email}` }}
        name={`experts/${permissions.email}/requests`}
        list={RequestList}
        edit={RequestEdit}
      />
    </AdminUI>
  );
}

解决这个问题的方法可能是:

    <AdminContext authProvider={authProvider} dataProvider={dataProvider}>
        <AdminUI layout={CustomLayout} theme={theme}>
            <AsyncResources />
        </AdminUI>
    </AdminContext>

在这种情况下,似乎 AdminUI 进行身份验证检查并重定向到登录。

此解决方案的问题是 Resources 不能 divfragments 或其他组件包裹(我 return 一个数组),所以在这种情况下任何东西都会被渲染。

有人对此有解决方案吗?

谢谢

我通过将权限逻辑移到上层并使用 Admin 组件解决了我的问题。

新实现

function App() {
  const [emails, setEmails] = useState<string[]>([]);
  useEffect(() => {
    (async () => {
      const experts = await firebase.firestore().collection("experts").get();
      const docIds: string[] = experts.docs.map((doc) => doc.id);

      setEmails(docIds);
    })();
  }, []);

  return (
    <Admin
      catchAll={NotFound}
      authProvider={authProvider}
      dataProvider={dataProvider}
      layout={CustomLayout}
      theme={theme}
    >
      {(props) => {
        if (props.admin) {
          return [
            emails.map((email) => (
              <Resource
                key={email}
                options={{ label: `${email}` }}
                name={`experts/${email}/requests`}
                list={RequestList}
                edit={RequestEdit}
              />
            )),
            <Resource name={`experts`} list={ExpertList} />,
          ];
        }
        return [
          <Resource
            options={{ label: `${props.email}` }}
            name={`experts/${props.email}/requests`}
            list={RequestList}
            edit={RequestEdit}
          />,
        ];
      }}
    </Admin>
  );
}