2020-09-02 05:49:53 +00:00
|
|
|
/**
|
|
|
|
* @author Martin Karkowski
|
|
|
|
* @email m.karkowski@zema.de
|
|
|
|
* @create date 2019-02-20 09:19:06
|
|
|
|
* @modify date 2020-07-22 22:06:39
|
|
|
|
* @desc [description]
|
|
|
|
*/
|
|
|
|
|
|
|
|
import React from 'react';
|
2020-09-07 11:05:40 +00:00
|
|
|
import { Col, Container, Nav, Row } from 'react-bootstrap';
|
2020-09-07 05:21:53 +00:00
|
|
|
import { FaTimesCircle } from 'react-icons/fa';
|
|
|
|
import DefaultNavbar from '../defaultNavbar';
|
2020-09-02 15:00:03 +00:00
|
|
|
import Selection, { SelecitonProps } from './selection';
|
2020-09-02 05:49:53 +00:00
|
|
|
|
|
|
|
const mainStyle = {
|
|
|
|
minHeight: '90vh',
|
|
|
|
}
|
|
|
|
|
|
|
|
const sidebarStyle = {
|
|
|
|
padding: '10px',
|
|
|
|
background: "primary"
|
|
|
|
}
|
|
|
|
|
|
|
|
const contentStyle = {
|
2020-09-02 15:00:03 +00:00
|
|
|
padding: '10px',
|
|
|
|
}
|
|
|
|
|
2020-09-07 05:21:53 +00:00
|
|
|
export interface ITab {
|
|
|
|
label: string,
|
|
|
|
id: string,
|
|
|
|
delteable: boolean
|
|
|
|
}
|
|
|
|
|
2020-09-02 15:00:03 +00:00
|
|
|
export interface LayoutProps<T> extends SelecitonProps<T> {
|
|
|
|
onResize?: () => void;
|
|
|
|
onMount?: (_ref: React.RefObject<any>) => void;
|
|
|
|
onUnmount?: () => void;
|
2020-09-07 11:05:40 +00:00
|
|
|
onNewTab?: () => Promise<ITab | false>;
|
2020-09-07 05:21:53 +00:00
|
|
|
onTabSelect?: (tabId: string) => void;
|
|
|
|
tabs?: {
|
2020-09-07 11:05:40 +00:00
|
|
|
allowNewTabs?: boolean;
|
2020-09-07 05:21:53 +00:00
|
|
|
active: string,
|
|
|
|
items: ITab[]
|
|
|
|
}
|
2020-09-02 15:00:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface LayoutState<T> {
|
2020-09-07 05:21:53 +00:00
|
|
|
update: null
|
2020-09-02 15:00:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class Layout<T> extends React.Component<LayoutProps<T>, LayoutState<T>> {
|
|
|
|
|
|
|
|
protected _ref: React.RefObject<any>;
|
|
|
|
protected _handleResize: () => void;
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
const _this = this;
|
|
|
|
|
|
|
|
function handleResize() {
|
|
|
|
if (typeof _this.props.onResize === 'function') {
|
|
|
|
_this.props.onResize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof this.props.onMount === 'function') {
|
|
|
|
this.props.onMount(this._ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._handleResize = handleResize;
|
|
|
|
window.addEventListener('resize', this._handleResize);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
window.removeEventListener('resize', this._handleResize);
|
|
|
|
|
|
|
|
// Call the unmount
|
|
|
|
if (typeof this.props.onUnmount === 'function') {
|
|
|
|
this.props.onUnmount();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this._ref = React.createRef();
|
|
|
|
}
|
|
|
|
|
2020-09-07 05:21:53 +00:00
|
|
|
public requestRerender() {
|
|
|
|
this.setState({
|
|
|
|
update: null
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-09-02 15:00:03 +00:00
|
|
|
public render() {
|
|
|
|
return (<>
|
2020-09-07 05:21:53 +00:00
|
|
|
<DefaultNavbar></DefaultNavbar>
|
2020-09-02 15:00:03 +00:00
|
|
|
<Container fluid style={mainStyle}>
|
|
|
|
<Row style={mainStyle}>
|
|
|
|
<Col className="col-md-2 d-none d-md-block bg-light sidebar-sticky" style={sidebarStyle}>
|
2020-09-07 11:05:40 +00:00
|
|
|
<Selection selection={this.props.selection} allowUserSelect={this.props.allowUserSelect} onItemSelected={this.props.onItemSelected}></Selection>
|
2020-09-02 15:00:03 +00:00
|
|
|
</Col>
|
|
|
|
<Col role="main" style={contentStyle}>
|
2020-09-07 05:21:53 +00:00
|
|
|
{this.props.tabs ?
|
2020-09-07 11:05:40 +00:00
|
|
|
<Nav variant="tabs" activeKey={this.props.tabs.active}>
|
2020-09-07 05:21:53 +00:00
|
|
|
{this.props.tabs.items.map((tab, idx) => {
|
2020-09-07 11:05:40 +00:00
|
|
|
if (tab.delteable && this.props.tabs.allowNewTabs) {
|
2020-09-07 05:21:53 +00:00
|
|
|
return (
|
|
|
|
<Nav.Item key={tab.id}>
|
|
|
|
<Nav.Link onSelect={_ => {
|
|
|
|
if (typeof this.props.onTabSelect === 'function') {
|
|
|
|
this.props.onTabSelect(tab.id);
|
|
|
|
}
|
2020-09-07 11:05:40 +00:00
|
|
|
// Assign the Tab ID
|
|
|
|
this.props.tabs.active = tab.id;
|
|
|
|
this.requestRerender();
|
2020-09-07 05:21:53 +00:00
|
|
|
}} eventKey={tab.id}>{tab.label}
|
|
|
|
<FaTimesCircle onClick={
|
|
|
|
e => {
|
|
|
|
// Remove the Items.
|
|
|
|
this.props.tabs.items.splice(idx, 1);
|
2020-09-07 11:05:40 +00:00
|
|
|
|
|
|
|
if (tab.id == this.props.tabs.active) {
|
|
|
|
// Assign the ID of the Element.
|
|
|
|
const _idx = this.props.tabs.items.length > idx ? idx : this.props.tabs.items.length - 1;
|
|
|
|
|
|
|
|
// Assign the First ID.
|
|
|
|
this.props.tabs.active = this.props.tabs.items.length > _idx ? this.props.tabs.items[_idx].id : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Redraw the Element.
|
2020-09-07 05:21:53 +00:00
|
|
|
this.requestRerender();
|
2020-09-07 11:05:40 +00:00
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2020-09-07 05:21:53 +00:00
|
|
|
}
|
|
|
|
} ></FaTimesCircle>
|
|
|
|
</Nav.Link>
|
|
|
|
</Nav.Item>
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return (
|
|
|
|
<Nav.Item key={tab.id}>
|
|
|
|
<Nav.Link onSelect={_ => {
|
|
|
|
if (typeof this.props.onTabSelect === 'function') {
|
|
|
|
this.props.onTabSelect(tab.id);
|
|
|
|
}
|
2020-09-07 11:05:40 +00:00
|
|
|
|
|
|
|
// Assign the Tab ID
|
|
|
|
this.props.tabs.active = tab.id;
|
|
|
|
this.requestRerender();
|
|
|
|
|
2020-09-07 05:21:53 +00:00
|
|
|
}} eventKey={tab.id}>{tab.label}</Nav.Link>
|
|
|
|
</Nav.Item>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
})}
|
2020-09-07 11:05:40 +00:00
|
|
|
|
|
|
|
{this.props.tabs.allowNewTabs ?
|
|
|
|
<Nav.Item>
|
|
|
|
<Nav.Link eventKey='_NEW_ITEM' onSelect={async () => {
|
|
|
|
if (typeof this.props.onNewTab === 'function') {
|
|
|
|
const tab = await this.props.onNewTab();
|
|
|
|
|
|
|
|
if (tab && typeof tab === 'object') {
|
|
|
|
this.props.tabs.items.push(tab);
|
|
|
|
this.props.tabs.active = tab.id;
|
|
|
|
this.requestRerender();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}}>
|
|
|
|
+
|
|
|
|
</Nav.Link>
|
|
|
|
</Nav.Item> : ''
|
|
|
|
}
|
|
|
|
|
2020-09-07 05:21:53 +00:00
|
|
|
</Nav>
|
|
|
|
: ''
|
|
|
|
}
|
|
|
|
|
2020-09-02 15:00:03 +00:00
|
|
|
{/* style={{height: '100%'}} */}
|
|
|
|
<div ref={this._ref}></div>
|
|
|
|
</Col>
|
|
|
|
</Row>
|
|
|
|
</Container>
|
|
|
|
</>);
|
|
|
|
}
|
2020-09-02 05:49:53 +00:00
|
|
|
}
|
|
|
|
|
2020-09-02 15:00:03 +00:00
|
|
|
export default Layout;
|