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

261 lines
6.8 KiB
JavaScript
Raw Normal View History

import React from "react";
import PropTypes from "prop-types";
import Backdrop from "../backdrop";
import HeaderComponent from "./sub-components/header";
import Nav from "./sub-components/nav";
import Aside from "./sub-components/aside";
import Main from "./sub-components/main";
import HeaderNav from "./sub-components/header-nav";
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) {
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) {
const { id, displayName, email, avatarSmall } = props.currentUser;
hash += id + displayName + email + avatarSmall;
}
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,
isolateModules = [],
mainModules = [],
totalNotifications = 0,
item = null;
2019-07-05 12:15:58 +00:00
for (let i = 0, l = props.availableModules.length; i < l; i++) {
2019-07-09 10:16:50 +00:00
item = props.availableModules[i];
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);
2019-09-12 08:38:04 +00:00
if (item.separator) 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-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");
return (
2019-07-10 09:49:14 +00:00
<>
{this.state.isBackdropAvailable && (
<Backdrop
visible={this.state.isBackdropVisible}
onClick={this.backdropClick}
/>
)}
{this.state.isHeaderNavAvailable && (
2019-07-12 10:12:22 +00:00
<HeaderNav
modules={this.state.isolateModules}
user={this.state.currentUser}
userActions={this.state.currentUserActions}
2019-07-09 10:16:50 +00:00
/>
)}
{this.state.isHeaderAvailable && (
<HeaderComponent
2019-07-12 10:12:22 +00:00
badgeNumber={this.state.totalNotifications}
onClick={this.showNav}
currentModule={this.state.currentModule}
/>
)}
{this.state.isNavAvailable && (
2019-07-12 10:12:22 +00:00
<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
separator={!!item.separator}
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>
))}
2019-07-12 10:12:22 +00:00
</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
]),
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]),
2019-07-10 09:49:14 +00:00
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;