navidrome/ui/src/layout/AppBar.js

141 lines
3.7 KiB
JavaScript

import React, { createElement, forwardRef, Fragment } from 'react'
import {
AppBar as RAAppBar,
MenuItemLink,
useTranslate,
usePermissions,
getResources,
} from 'react-admin'
import { useSelector } from 'react-redux'
import { makeStyles, MenuItem, ListItemIcon, Divider } from '@material-ui/core'
import ViewListIcon from '@material-ui/icons/ViewList'
import InfoIcon from '@material-ui/icons/Info'
import PersonIcon from '@material-ui/icons/Person'
import SupervisorAccountIcon from '@material-ui/icons/SupervisorAccount'
import { Dialogs } from '../dialogs/Dialogs'
import { AboutDialog } from '../dialogs'
import PersonalMenu from './PersonalMenu'
import ActivityPanel from './ActivityPanel'
import UserMenu from './UserMenu'
import config from '../config'
const useStyles = makeStyles(
(theme) => ({
root: {
color: theme.palette.text.secondary,
},
active: {
color: theme.palette.text.primary,
},
icon: { minWidth: theme.spacing(5) },
}),
{
name: 'NDAppBar',
}
)
const AboutMenuItem = forwardRef(({ onClick, ...rest }, ref) => {
const classes = useStyles(rest)
const translate = useTranslate()
const [open, setOpen] = React.useState(false)
const handleOpen = () => {
setOpen(true)
}
const handleClose = () => {
onClick && onClick()
setOpen(false)
}
const label = translate('menu.about')
return (
<>
<MenuItem ref={ref} onClick={handleOpen} className={classes.root}>
<ListItemIcon className={classes.icon}>
<InfoIcon titleAccess={label} />
</ListItemIcon>
{label}
</MenuItem>
<AboutDialog onClose={handleClose} open={open} />
</>
)
})
const settingsResources = (resource) =>
resource.name !== 'user' &&
resource.hasList &&
resource.options &&
resource.options.subMenu === 'settings'
const CustomUserMenu = ({ onClick, ...rest }) => {
const translate = useTranslate()
const resources = useSelector(getResources)
const classes = useStyles(rest)
const { permissions } = usePermissions()
const resourceDefinition = (resourceName) =>
resources.find((r) => r?.name === resourceName)
const renderUserMenuItemLink = () => {
const userResource = resourceDefinition('user')
if (!userResource) {
return null
}
if (permissions !== 'admin') {
if (!config.enableUserEditing) {
return null
}
userResource.icon = PersonIcon
} else {
userResource.icon = SupervisorAccountIcon
}
return renderSettingsMenuItemLink(
userResource,
permissions !== 'admin' ? localStorage.getItem('userId') : null
)
}
const renderSettingsMenuItemLink = (resource, id) => {
const label = translate(`resources.${resource.name}.name`, {
smart_count: id ? 1 : 2,
})
const link = id ? `/${resource.name}/${id}` : `/${resource.name}`
return (
<MenuItemLink
className={classes.root}
activeClassName={classes.active}
key={resource.name}
to={link}
primaryText={label}
leftIcon={
(resource.icon && createElement(resource.icon)) || <ViewListIcon />
}
onClick={onClick}
sidebarIsOpen={true}
/>
)
}
return (
<>
{config.devActivityPanel && permissions === 'admin' && <ActivityPanel />}
<UserMenu {...rest}>
<PersonalMenu sidebarIsOpen={true} onClick={onClick} />
<Divider />
{renderUserMenuItemLink()}
{resources
.filter(settingsResources)
.map((r) => renderSettingsMenuItemLink(r))}
<Divider />
<AboutMenuItem />
</UserMenu>
<Dialogs />
</>
)
}
const AppBar = (props) => (
<RAAppBar {...props} container={Fragment} userMenu={<CustomUserMenu />} />
)
export default AppBar