DocSpace-buildtools/web/ASC.Web.Components/src/components/layout/index.js

249 lines
6.5 KiB
JavaScript
Raw Normal View History

import React from 'react'
import PropTypes from 'prop-types'
import Backdrop from '../backdrop'
2019-07-10 09:49:14 +00:00
import Header from './sub-components/header'
import Nav from './sub-components/nav'
import Aside from './sub-components/aside'
import Main from './sub-components/main'
2019-07-10 09:59:00 +00:00
import HeaderNav from './sub-components/header-nav'
2019-07-05 15:10:16 +00:00
import NavLogoItem from './sub-components/nav-logo-item'
import NavItem from './sub-components/nav-item'
class Layout extends React.Component {
constructor(props) {
super(props);
this.timeout = null;
this.state = this.mapPropsToState(props);
}
/*shouldComponentUpdate() {
return false;
}*/
componentDidUpdate(prevProps, prevState) {
2019-07-24 14:24:40 +00:00
//console.log("Layout componentDidUpdate");
let currentHash = this.getPropsHash(this.props);
let prevHash = this.getPropsHash(prevProps);
if (currentHash !== prevHash) {
2019-07-24 14:24:40 +00:00
console.log("Layout componentDidUpdate hasChanges");
this.setState(this.mapPropsToState(this.props));
}
}
getPropsHash = (props) => {
let hash = "";
if (props.currentModuleId) {
hash+=props.currentModuleId;
}
if (props.currentUser) {
hash+=props.currentUser.id;
}
if (props.availableModules) {
for (let i=0, l=props.availableModules.length; i<l; i++)
{
let item = props.availableModules[i];
hash+=item.id + item.notifications;
}
}
return hash;
}
mapPropsToState = (props) => {
2019-07-09 10:16:50 +00:00
let currentModule = null,
2019-07-10 09:49:14 +00:00
isolateModules = [],
mainModules = [],
totalNotifications = 0,
item = null;
2019-07-05 12:15:58 +00:00
2019-07-09 10:16:50 +00:00
for (let i=0, l=props.availableModules.length; i<l; i++)
{
item = props.availableModules[i];
2019-07-09 10:16:50 +00:00
if (item.id == props.currentModuleId)
currentModule = item;
2019-07-09 10:16:50 +00:00
if (item.isolateMode) {
isolateModules.push(item);
} else {
mainModules.push(item);
if (item.seporator) continue;
totalNotifications+=item.notifications;
2019-07-09 10:16:50 +00:00
}
}
const newState = {
isBackdropAvailable: mainModules.length > 0 || !!props.asideContent,
isHeaderNavAvailable: isolateModules.length > 0 || !!props.currentUser,
isHeaderAvailable: mainModules.length > 0,
isNavAvailable: mainModules.length > 0,
isAsideAvailable: !!props.asideContent,
2019-07-12 10:12:22 +00:00
isBackdropVisible: props.isBackdropVisible,
isNavHoverEnabled: props.isNavHoverEnabled,
2019-07-11 14:59:06 +00:00
isNavOpened: props.isNavOpened,
isAsideVisible: props.isAsideVisible,
2019-07-10 09:49:14 +00:00
onLogoClick: props.onLogoClick,
asideContent: props.asideContent,
2019-07-12 10:12:22 +00:00
currentUser: props.currentUser,
currentUserActions: props.currentUserActions,
2019-07-10 09:49:14 +00:00
2019-07-12 10:12:22 +00:00
availableModules: props.availableModules,
2019-07-09 10:16:50 +00:00
isolateModules: isolateModules,
mainModules: mainModules,
2019-07-10 09:49:14 +00:00
currentModule: currentModule,
currentModuleId: props.currentModuleId,
2019-07-08 13:42:05 +00:00
totalNotifications: totalNotifications
};
return newState;
}
2019-07-10 09:49:14 +00:00
backdropClick = () => {
2019-07-08 13:42:05 +00:00
this.setState({
isBackdropVisible: false,
2019-07-11 14:59:06 +00:00
isNavOpened: false,
isAsideVisible: false,
isNavHoverEnabled: !this.state.isNavHoverEnabled
2019-07-08 13:42:05 +00:00
});
};
2019-07-10 09:49:14 +00:00
showNav = () => {
this.setState({
isBackdropVisible: true,
2019-07-11 14:59:06 +00:00
isNavOpened: true,
isAsideVisible: false,
isNavHoverEnabled: false
2019-07-10 09:49:14 +00:00
});
};
handleNavMouseEnter = () => {
if (!this.state.isNavHoverEnabled) return;
this.timeout = setTimeout(() => {
this.setState({
isBackdropVisible: false,
isNavOpened: true,
isAsideVisible: false
});
}, 300);
}
handleNavMouseLeave = () => {
if (!this.state.isNavHoverEnabled) return;
if (this.timeout != null) {
clearTimeout(this.timeout);
this.timeout = null;
}
2019-07-08 13:42:05 +00:00
this.setState({
isBackdropVisible: false,
isNavOpened: false,
2019-07-11 14:59:06 +00:00
isAsideVisible: false
2019-07-08 13:42:05 +00:00
});
}
2019-07-10 09:49:14 +00:00
toggleAside = () => {
2019-07-08 13:42:05 +00:00
this.setState({
isBackdropVisible: true,
2019-07-11 14:59:06 +00:00
isNavOpened: false,
isAsideVisible: true,
isNavHoverEnabled: false
2019-07-08 13:42:05 +00:00
});
};
render() {
//console.log("Layout render");
2019-07-24 14:24:40 +00:00
return (
2019-07-10 09:49:14 +00:00
<>
2019-07-12 10:12:22 +00:00
{
this.state.isBackdropAvailable &&
<Backdrop visible={this.state.isBackdropVisible} onClick={this.backdropClick}/>
}
{
this.state.isHeaderNavAvailable &&
<HeaderNav
modules={this.state.isolateModules}
user={this.state.currentUser}
userActions={this.state.currentUserActions}
2019-07-09 10:16:50 +00:00
/>
2019-07-12 10:12:22 +00:00
}
{
this.state.isHeaderAvailable &&
<Header
badgeNumber={this.state.totalNotifications}
onClick={this.showNav}
currentModule={this.state.currentModule}
/>
}
{
this.state.isNavAvailable &&
<Nav
opened={this.state.isNavOpened}
onMouseEnter={this.handleNavMouseEnter}
onMouseLeave={this.handleNavMouseLeave}
2019-07-12 10:12:22 +00:00
>
<NavLogoItem
opened={this.state.isNavOpened}
onClick={this.state.onLogoClick}
/>
{
this.state.mainModules.map(item =>
<NavItem
seporator={!!item.seporator}
key={item.id}
opened={this.state.isNavOpened}
active={item.id == this.state.currentModuleId}
iconName={item.iconName}
badgeNumber={item.notifications}
onClick={item.onClick}
onBadgeClick={(e)=>{item.onBadgeClick(e); this.toggleAside();}}
>
{item.title}
</NavItem>
)
}
</Nav>
}
{
this.state.isAsideAvailable &&
<Aside visible={this.state.isAsideVisible} onClick={this.backdropClick}>{this.state.asideContent}</Aside>
}
<Main fullscreen={!this.state.isNavAvailable}>{this.props.children}</Main>
2019-07-10 09:49:14 +00:00
</>
);
2019-07-05 12:15:58 +00:00
}
}
Layout.propTypes = {
isBackdropVisible: PropTypes.bool,
isNavHoverEnabled: PropTypes.bool,
2019-07-11 14:59:06 +00:00
isNavOpened: PropTypes.bool,
isAsideVisible: PropTypes.bool,
2019-07-10 09:49:14 +00:00
onLogoClick: PropTypes.func,
asideContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
2019-07-05 12:15:58 +00:00
currentUser: PropTypes.object,
2019-07-09 10:16:50 +00:00
currentUserActions: PropTypes.array,
2019-07-05 12:15:58 +00:00
availableModules: PropTypes.array,
2019-07-09 10:16:50 +00:00
currentModuleId: PropTypes.string
};
Layout.defaultProps = {
isBackdropVisible: false,
isNavHoverEnabled: true,
2019-07-11 14:59:06 +00:00
isNavOpened: false,
2019-07-12 10:12:22 +00:00
isAsideVisible: false,
currentUser: null,
currentUserActions: [],
availableModules: [],
};
export default Layout;