React Admin 根据权限渲染资源
React Admin render resources based on permissions
我正在 firestore 之上构建一个带有 React admin 的管理界面。
firestore dataProvider 一切正常,但现在我想处理权限,并根据权限显示专家列表。
为了实现这一点,我决定使用 AdminContext
和 AdminUI
实现自定义 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
不能 被 div
、fragments
或其他组件包裹(我 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>
);
}
我正在 firestore 之上构建一个带有 React admin 的管理界面。
firestore dataProvider 一切正常,但现在我想处理权限,并根据权限显示专家列表。
为了实现这一点,我决定使用 AdminContext
和 AdminUI
实现自定义 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
不能 被 div
、fragments
或其他组件包裹(我 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>
);
}