266 lines
7.7 KiB
HTML
266 lines
7.7 KiB
HTML
|
|
{% extends "base/base.html" %}
|
||
|
|
|
||
|
|
{% block preamble %}
|
||
|
|
{% block metadata %}
|
||
|
|
{{ super() }}
|
||
|
|
{% endblock %}
|
||
|
|
|
||
|
|
<!-- Template JS -->
|
||
|
|
{% for src in template_resources['js'].values() %}
|
||
|
|
<script src="{{ src }}"></script>
|
||
|
|
{% endfor %}
|
||
|
|
{% for src in template_resources['js_modules'].values() %}
|
||
|
|
<script src="{{ src }}" type="module"></script>
|
||
|
|
{% endfor %}
|
||
|
|
{% endblock %}
|
||
|
|
|
||
|
|
{% block postamble %}
|
||
|
|
<!-- Template CSS -->
|
||
|
|
{% for css in template_resources['css'].values() %}
|
||
|
|
<link rel="stylesheet" href="{{ css }}">
|
||
|
|
{% endfor %}
|
||
|
|
{% for raw_css in template_resources['raw_css'] %}
|
||
|
|
<style type="text/css">
|
||
|
|
{{ raw_css }}
|
||
|
|
</style>
|
||
|
|
{% endfor %}
|
||
|
|
|
||
|
|
<style>
|
||
|
|
:root {
|
||
|
|
--header-background: {{ header_background or "var(--design-primary-color, var(--panel-primary-color))" }};
|
||
|
|
--header-color: {{ header_color or "var(--design-primary-text-color, var(--panel-on-primary-color))" }};
|
||
|
|
--sidebar-width: {{ sidebar_width }}px;
|
||
|
|
}
|
||
|
|
#header {
|
||
|
|
--design-background-text-color: var(--header-color);
|
||
|
|
--design-background-color: var(--header-background);
|
||
|
|
background-color: var(--header-background);
|
||
|
|
color: var(--header-color);
|
||
|
|
}
|
||
|
|
#sidebar {
|
||
|
|
min-width: var(--sidebar-width);
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
{% endblock %}
|
||
|
|
|
||
|
|
<!-- goes in body -->
|
||
|
|
{% block contents %}
|
||
|
|
<div id="container">
|
||
|
|
<nav id="header">
|
||
|
|
{% if nav %}
|
||
|
|
<span style="font-size:30px; cursor:pointer" onclick="{{ 'openNav()' if collapsed_sidebar else 'closeNav()' }}" id="sidebar-button">
|
||
|
|
<div class="pn-bar"></div>
|
||
|
|
<div class="pn-bar"></div>
|
||
|
|
<div class="pn-bar"></div>
|
||
|
|
</span>
|
||
|
|
{% endif %}
|
||
|
|
<div class="app-header">
|
||
|
|
{% if app_logo %}<a class="navbar-brand app-logo" href="{{ site_url }}"><img src="{{ app_logo }}" class="app-logo"></a>{% endif %}
|
||
|
|
{% if site_title %}<a class="title" href="{{ site_url }}" > {{ site_title }}</a>{% endif %}
|
||
|
|
{% if site_title and app_title%}<span class="title">-</span>{% endif %}
|
||
|
|
{% if app_title %}<a class="title" href="" > {{ app_title }}</a>{% endif %}
|
||
|
|
</div>
|
||
|
|
<div id="header-items">
|
||
|
|
{% for doc in docs %}
|
||
|
|
{% for root in doc.roots %}
|
||
|
|
{% if "header" in root.tags %}
|
||
|
|
{{ embed(root) | indent(8) }}
|
||
|
|
{% endif %}
|
||
|
|
{% endfor %}
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
{% if saveLayout %}
|
||
|
|
<button id="layout-reset">Reset Layout</button>
|
||
|
|
{% endif %}
|
||
|
|
{% if busy %}
|
||
|
|
<div class="pn-busy-container">
|
||
|
|
{{ embed(roots.busy_indicator) | indent(6) }}
|
||
|
|
</div>
|
||
|
|
{% endif %}
|
||
|
|
</nav>
|
||
|
|
|
||
|
|
<div class="row" id="content">
|
||
|
|
{% if nav %}
|
||
|
|
<div class="sidenav {{'hidden' if collapsed_sidebar else ''}}" id="sidebar">
|
||
|
|
<ul class="nav flex-column">
|
||
|
|
{% for doc in docs %}
|
||
|
|
{% for root in doc.roots %}
|
||
|
|
{% if "nav" in root.tags %}
|
||
|
|
{{ embed(root) | indent(8) }}
|
||
|
|
{% endif %}
|
||
|
|
{% endfor %}
|
||
|
|
{% endfor %}
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
{% endif %}
|
||
|
|
|
||
|
|
<div class="main" id="main">
|
||
|
|
{% if main_max_width %}
|
||
|
|
<div style="margin-left: auto; margin-right: auto; max-width: {{main_max_width}}">
|
||
|
|
{% endif %}
|
||
|
|
<div id="responsive-grid"></div>
|
||
|
|
<div id="pn-Modal" class="pn-modal header-adjust">
|
||
|
|
<div class="pn-modal-content">
|
||
|
|
<span class="pn-modalclose" id="pn-closeModal">×</span>
|
||
|
|
{% for doc in docs %}
|
||
|
|
{% for root in doc.roots %}
|
||
|
|
{% if "modal" in root.tags %}
|
||
|
|
{{ embed(root) | indent(10) }}
|
||
|
|
{% endif %}
|
||
|
|
{% endfor %}
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
{% if main_max_width %}
|
||
|
|
</div>
|
||
|
|
{% endif %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
function openNav() {
|
||
|
|
document.getElementById("sidebar").classList.remove("hidden");
|
||
|
|
window.dispatchEvent(new Event("resize"))
|
||
|
|
document.getElementById("sidebar-button").onclick = closeNav;
|
||
|
|
var interval = setInterval(function () { window.dispatchEvent(new Event('resize')); }, 10);
|
||
|
|
setTimeout(function () { clearInterval(interval) }, 210)
|
||
|
|
}
|
||
|
|
|
||
|
|
function closeNav() {
|
||
|
|
document.getElementById("sidebar").classList.add("hidden");
|
||
|
|
document.getElementById("sidebar-button").onclick = openNav;
|
||
|
|
var interval = setInterval(function () { window.dispatchEvent(new Event('resize')); }, 10);
|
||
|
|
setTimeout(function () { clearInterval(interval) }, 210)
|
||
|
|
}
|
||
|
|
|
||
|
|
var modal = document.getElementById("pn-Modal");
|
||
|
|
var span = document.getElementById("pn-closeModal");
|
||
|
|
|
||
|
|
span.onclick = function() {
|
||
|
|
modal.style.display = "none";
|
||
|
|
}
|
||
|
|
|
||
|
|
window.onclick = function(event) {
|
||
|
|
if (event.target == modal) {
|
||
|
|
modal.style.display = "none";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<script type="text/babel">
|
||
|
|
const divStyle = {borderRadius: '5px'};
|
||
|
|
const ResponsiveGridLayout = ReactGridLayout.WidthProvider(ReactGridLayout.Responsive);
|
||
|
|
{% if saveLayout %}
|
||
|
|
const originalLayout = getFromLS("layouts") || {{ layouts }};
|
||
|
|
{% else %}
|
||
|
|
const originalLayout = {{ layouts }};
|
||
|
|
{% endif %}
|
||
|
|
|
||
|
|
function getFromLS(key) {
|
||
|
|
let ls = {};
|
||
|
|
if (window.localStorage) {
|
||
|
|
try {
|
||
|
|
ls = JSON.parse(window.localStorage.getItem(window.location.origin + window.location.pathname)) || {};
|
||
|
|
} catch (e) {
|
||
|
|
/*Ignore*/
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return ls[key];
|
||
|
|
}
|
||
|
|
|
||
|
|
function saveToLS(key, value) {
|
||
|
|
if (window.localStorage) {
|
||
|
|
window.localStorage.setItem(
|
||
|
|
window.location.origin + window.location.pathname,
|
||
|
|
JSON.stringify({
|
||
|
|
[key]: value
|
||
|
|
})
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function resize_layout(obj, old_, new_, p, e, element) {
|
||
|
|
window.dispatchEvent(new Event("resize"))
|
||
|
|
}
|
||
|
|
|
||
|
|
function resize_layout_stop(obj, old_, new_, p, e, element) {
|
||
|
|
setTimeout(function(){
|
||
|
|
window.dispatchEvent(new Event("resize"))
|
||
|
|
}, 50);
|
||
|
|
}
|
||
|
|
|
||
|
|
class ResponsiveGrid extends React.PureComponent {
|
||
|
|
|
||
|
|
static defaultProps = {
|
||
|
|
onLayoutChange: function() {}
|
||
|
|
}
|
||
|
|
|
||
|
|
constructor(props) {
|
||
|
|
super(props);
|
||
|
|
this.state = {
|
||
|
|
layouts: JSON.parse(JSON.stringify(originalLayout))
|
||
|
|
};
|
||
|
|
{% if saveLayout %}
|
||
|
|
this.resetLayout = this.resetLayout.bind(this)
|
||
|
|
document.getElementById('layout-reset').onclick = this.resetLayout
|
||
|
|
{% endif %}
|
||
|
|
}
|
||
|
|
|
||
|
|
resetLayout() {
|
||
|
|
this.setState({
|
||
|
|
layouts: {{ layouts }}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
onLayoutChange(layout, layouts) {
|
||
|
|
saveToLS("layouts", layouts);
|
||
|
|
this.setState({ layouts });
|
||
|
|
}
|
||
|
|
|
||
|
|
render() {
|
||
|
|
return (
|
||
|
|
<ResponsiveGridLayout
|
||
|
|
className={"layout"}
|
||
|
|
cols={ {{cols}} }
|
||
|
|
breakpoints={ {{breakpoints}} }
|
||
|
|
draggableHandle={".drag-handle"}
|
||
|
|
draggableCancel={".bk-root"}
|
||
|
|
onResize={resize_layout}
|
||
|
|
onResizeStop={resize_layout_stop}
|
||
|
|
rowHeight={ {{rowHeight}} }
|
||
|
|
layouts={this.state.layouts}
|
||
|
|
{% if compact == "both" %}
|
||
|
|
compactType={"horizontal"}
|
||
|
|
{% elif compact == "horizontal" %}
|
||
|
|
verticalCompact={false}
|
||
|
|
compactType={"horizontal"}
|
||
|
|
{% elif compact is none %}
|
||
|
|
verticalCompact={false}
|
||
|
|
{% endif %}
|
||
|
|
preventCollision={ {{preventCollision and 'true' or 'false'}} }
|
||
|
|
{% if saveLayout %}
|
||
|
|
onLayoutChange={(layout, layouts) => this.onLayoutChange(layout, layouts)}
|
||
|
|
{% endif %}
|
||
|
|
>
|
||
|
|
{% set count = [] %}
|
||
|
|
{% for doc in docs %}{% for root in doc.roots %}{% if "main" in root.tags %}
|
||
|
|
<div key="{{count|length + 1 }}" style={divStyle} >
|
||
|
|
<span className="drag-handle"></span>
|
||
|
|
{{ embed(root) | indent(4) | replace("class", "className") | replace('style="display: contents;"', 'style={{display: "contents"}}') }}
|
||
|
|
</div>
|
||
|
|
{% set __ = count.append(1) %}
|
||
|
|
{% endif %}{% endfor %}{% endfor %}
|
||
|
|
</ResponsiveGridLayout>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ReactDOM.render(<ResponsiveGrid />, document.getElementById('responsive-grid'));
|
||
|
|
</script>
|
||
|
|
|
||
|
|
{% block state_roots %}
|
||
|
|
{{ super() }}
|
||
|
|
{% endblock %}
|
||
|
|
|
||
|
|
{% endblock %}
|