plugins.SideBar.SideBar.jsx Maven / Gradle / Ivy
The newest version!
import React, { useRef } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
import isEqual from 'lodash/isEqual'
import map from 'lodash/map'
import {
compose,
withState,
lifecycle,
withHandlers,
setDisplayName,
} from 'recompose'
import { withTranslation } from 'react-i18next'
import mapProps from 'recompose/mapProps'
import { connect } from 'react-redux'
import { Logo } from '../Header/SimpleHeader/Logo'
import { withItemsResolver } from '../withItemsResolver/withItemResolver'
import { withTitlesResolver } from '../withTitlesResolver/withTitlesResolver'
import { WithDataSource } from '../../core/datasource/WithDataSource'
import { WithContextDataSource } from '../WithContextDataSource/WithContextDataSource'
import { dataSourceModelByPrefixSelector } from '../../ducks/datasource/selectors'
import { ModelPrefix } from '../../core/datasource/const'
import { NavItemContainer } from './NavItemContainer'
/**
* Sidebar
* @param activeId - id активного элемента
* @param brand - текст бренда
* @param brandImage - картинка бренда
* @param userBox - настройка userBox
* @param items - массив итемов
* @param visible - видимость
* @param sidebarOpen - видимость если controlled
* @param width - длина сайдбара
* @param controlled - флаг контроллед режима
* @param onToggle - переключение compressed
* @param extra - екстра итемы
* @param className - class
* @param logo - настройки лого
* @param t - функция перевода
* @returns {*}
* @constructor
*/
export const sidebarView = {
none: 'none',
micro: 'micro',
mini: 'mini',
maxi: 'maxi',
}
const toggleIconClassNames = (visible, side) => {
const isLeftIcon = (visible && side === 'left') || (!visible && (side === 'right'))
return isLeftIcon ? 'fa fa-angle-double-left' : 'fa fa-angle-double-right'
}
const sideBarClasses = (isStaticView, defaultState, toggledState, currentVisible, side, className) => {
const viewMode = isStaticView || !currentVisible ? sidebarView[defaultState] : sidebarView[toggledState]
return classNames(
'n2o-sidebar',
side,
className,
viewMode,
)
}
const LogoSection = ({
isMiniView,
logo,
subtitle,
showContent,
}) => (
{logo && }
)
export function SideBar({
activeId,
visible,
sidebarOpen,
controlled,
onToggle,
className,
logo,
subtitle,
menu,
extraMenu = {},
defaultState = sidebarView.mini,
toggledState = sidebarView.maxi,
onMouseEnter,
onMouseLeave,
side = 'left',
isStaticView,
datasources,
datasource,
models = {},
}) {
const sidebarRef = useRef()
const currentVisible = controlled ? sidebarOpen : visible
const { items = [] } = menu
const { items: extraItems = [] } = extraMenu
const needShowContent = () => {
if (isStaticView && defaultState !== 'micro') {
return true
}
if (currentVisible) {
return (toggledState === sidebarView.mini) || (toggledState === sidebarView.maxi)
}
return defaultState !== 'micro'
}
const showContent = needShowContent()
const isMiniView = (defaultState === sidebarView.mini && !currentVisible) ||
(toggledState === sidebarView.mini && currentVisible)
const renderItems = items => map(items, (item, key) => (
))
return (
)
}
SideBar.propTypes = {
/**
* ID активного элемента
*/
activeId: PropTypes.string,
/**
* Настройки лого и брэнда
*/
logo: PropTypes.object,
/**
* Флаг сжатия
*/
visible: PropTypes.bool,
/**
* Флаг сжатия если controlled
*/
sidebarOpen: PropTypes.bool,
/**
* Флаг включения режима controlled
*/
controlled: PropTypes.bool,
/**
* Callback на переключение сжатия
*/
onToggle: PropTypes.func,
/**
* Адрес ссылка бренда
*/
subtitle: PropTypes.string,
side: PropTypes.string,
className: PropTypes.string,
menu: PropTypes.object,
extraMenu: PropTypes.array,
datasources: PropTypes.object,
datasource: PropTypes.string,
defaultState: PropTypes.string,
toggledState: PropTypes.string,
onMouseEnter: PropTypes.func,
onMouseLeave: PropTypes.func,
isStaticView: PropTypes.bool,
}
SideBar.defaultProps = {
controlled: false,
menu: {},
}
LogoSection.propTypes = {
isMiniView: PropTypes.bool,
logo: PropTypes.object,
subtitle: PropTypes.string,
showContent: PropTypes.bool,
}
const mapStateToProps = (state, { datasource }) => ({
datasourceModel:
dataSourceModelByPrefixSelector(datasource, ModelPrefix.source)(state)?.[0] || {},
})
export default compose(
withTranslation(),
setDisplayName('Sidebar'),
withState('visible', 'setVisible', ({ visible }) => visible),
withHandlers({
onToggle: ({ visible, setVisible }) => () => setVisible(!visible),
}),
lifecycle({
componentDidUpdate(prevProps) {
if (!isEqual(prevProps.visible, this.props.visible)) {
this.setState({ visible: this.props.visible })
}
},
}),
mapProps(props => ({
...props,
force: true,
fetch: 'lazy',
})),
WithDataSource,
WithContextDataSource,
withItemsResolver,
connect(mapStateToProps),
withTitlesResolver,
)(SideBar)