Render Admin NavBlock based on authorization
Require location prop as propType in SideNav to prevent silent fail. Add guard clause on isUsingAuth to prevent DOM break in Authorized. Consolidate return on Authorized render. Clean up Authorized. Signed-off-by: Alex Paxton <thealexpaxton@gmail.com>pull/10616/head
parent
c8163b68aa
commit
95917837e3
|
@ -33,19 +33,28 @@ export const isUserAuthorized = (meRole, requiredRole) => {
|
|||
|
||||
const getRoleName = ({roles: [{name}, ..._]}) => name
|
||||
|
||||
const Authorized = ({children, me, isUsingAuth, requiredRole, replaceWith}) => {
|
||||
if (!isUsingAuth) {
|
||||
return React.isValidElement(children) ? children : children[0]
|
||||
const Authorized = ({
|
||||
children,
|
||||
me,
|
||||
isUsingAuth,
|
||||
requiredRole,
|
||||
replaceWith,
|
||||
...additionalProps
|
||||
}) => {
|
||||
// if me response has not been received yet, render nothing
|
||||
if (typeof isUsingAuth !== 'boolean') {
|
||||
return null
|
||||
}
|
||||
|
||||
const meRole = getRoleName(me)
|
||||
if (isUserAuthorized(meRole, requiredRole)) {
|
||||
if (!isUsingAuth || isUserAuthorized(meRole, requiredRole)) {
|
||||
return React.cloneElement(
|
||||
React.isValidElement(children) ? children : children[0]
|
||||
)
|
||||
React.isValidElement(children) ? children : children[0],
|
||||
{...additionalProps}
|
||||
) // guards against multiple children wrapped by Authorized
|
||||
}
|
||||
|
||||
return replaceWith ? React.cloneElement(replaceWith) : null
|
||||
return replaceWith ? replaceWith : null
|
||||
|
||||
// if you want elements to be disabled instead of hidden:
|
||||
// return React.cloneElement(clonedElement, {disabled: !isAuthorized})
|
||||
|
@ -54,7 +63,7 @@ const Authorized = ({children, me, isUsingAuth, requiredRole, replaceWith}) => {
|
|||
const {arrayOf, bool, node, shape, string} = PropTypes
|
||||
|
||||
Authorized.propTypes = {
|
||||
isUsingAuth: bool.isRequired,
|
||||
isUsingAuth: bool,
|
||||
replaceWith: node,
|
||||
children: node.isRequired,
|
||||
me: shape({
|
||||
|
|
|
@ -2,13 +2,15 @@ import React, {PropTypes} from 'react'
|
|||
import {Link} from 'react-router'
|
||||
import classnames from 'classnames'
|
||||
|
||||
import Authorized from 'src/auth/Authorized'
|
||||
|
||||
const {bool, node, string} = PropTypes
|
||||
|
||||
const NavListItem = React.createClass({
|
||||
propTypes: {
|
||||
link: string.isRequired,
|
||||
children: node,
|
||||
location: string,
|
||||
location: string.isRequired,
|
||||
useAnchor: bool,
|
||||
isExternal: bool,
|
||||
},
|
||||
|
@ -60,15 +62,14 @@ const NavBlock = React.createClass({
|
|||
children: node,
|
||||
link: string,
|
||||
icon: string.isRequired,
|
||||
location: string,
|
||||
location: string.isRequired,
|
||||
className: string,
|
||||
},
|
||||
|
||||
render() {
|
||||
const {location, className} = this.props
|
||||
|
||||
const isActive = React.Children.toArray(this.props.children).find(child => {
|
||||
return location.startsWith(child.props.link)
|
||||
return location.startsWith(child.props.link) // if location is undefined, this will fail silently
|
||||
})
|
||||
|
||||
const children = React.Children.map(this.props.children, child => {
|
||||
|
@ -119,7 +120,7 @@ const NavBar = React.createClass({
|
|||
|
||||
render() {
|
||||
const children = React.Children.map(this.props.children, child => {
|
||||
if (child && child.type === NavBlock) {
|
||||
if (child && (child.type === NavBlock || child.type === Authorized)) {
|
||||
return React.cloneElement(child, {
|
||||
location: this.props.location,
|
||||
})
|
||||
|
|
|
@ -2,6 +2,8 @@ import React, {PropTypes} from 'react'
|
|||
import {withRouter, Link} from 'react-router'
|
||||
import {connect} from 'react-redux'
|
||||
|
||||
import Authorized, {ADMIN_ROLE} from 'src/auth/Authorized'
|
||||
|
||||
import {
|
||||
NavBar,
|
||||
NavBlock,
|
||||
|
@ -108,9 +110,11 @@ const SideNav = React.createClass({
|
|||
Create
|
||||
</NavListItem>
|
||||
</NavBlock>
|
||||
<Authorized requiredRole={ADMIN_ROLE}>
|
||||
<NavBlock icon="crown2" link={`${sourcePrefix}/admin`}>
|
||||
<NavHeader link={`${sourcePrefix}/admin`} title="Admin" />
|
||||
</NavBlock>
|
||||
</Authorized>
|
||||
<NavBlock icon="cog-thick" link={`${sourcePrefix}/manage-sources`}>
|
||||
<NavHeader
|
||||
link={`${sourcePrefix}/manage-sources`}
|
||||
|
|
Loading…
Reference in New Issue