Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maximize option to card #1688

Closed
wants to merge 17 commits into from
2 changes: 1 addition & 1 deletion panel/template/react/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def _update_render_items(self, event):
if x1 is None: x1 = 12
if y0 is None: y0 = 0
if y1 is None: y1 = self.main.nrows
layouts.append({'x': x0, 'y': y0, 'w': x1-x0, 'h': y1-y0, 'i': str(i+1)})
layouts.append({'x': x0, 'y': y0, 'w': x1-x0, 'h': y1-y0, 'i': str(i+1), 'minH':4})
self._render_variables['layouts'] = {'lg': layouts, 'md': layouts}

@depends('cols', 'breakpoints', 'row_height', 'compact', watch=True)
Expand Down
6 changes: 5 additions & 1 deletion panel/template/react/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ body {
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij48cGF0aCBmaWxsPSJub25lIiBkPSJNMCAwaDI0djI0SDB6Ii8+PHBhdGggZmlsbD0id2hpdGUiIGQ9Ik0xNiAxM2w2Ljk2NCA0LjA2Mi0yLjk3My44NSAyLjEyNSAzLjY4MS0xLjczMiAxLTIuMTI1LTMuNjgtMi4yMjMgMi4xNUwxNiAxM3ptLTItN2gydjJoNWExIDEgMCAwIDEgMSAxdjRoLTJ2LTNIMTB2MTBoNHYySDlhMSAxIDAgMCAxLTEtMXYtNUg2di0yaDJWOWExIDEgMCAwIDEgMS0xaDVWNnpNNCAxNHYySDJ2LTJoMnptMC00djJIMnYtMmgyem0wLTR2MkgyVjZoMnptMC00djJIMlYyaDJ6bTQgMHYySDZWMmgyem00IDB2MmgtMlYyaDJ6bTQgMHYyaC0yVjJoMnoiLz48L3N2Zz4=');
}

.maximize{
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij4NCg0KPGcNCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgxLjQ2MzgyMSwtMTc5LjQ1MDU0KSINCiAgICAgaWQ9ImxheWVyMSI+DQogICAgPGcNCiAgICAgICBzdHlsZT0iZmlsbDp3aGl0ZTtzdHJva2U6bm9uZSINCiAgICAgICB0cmFuc2Zvcm09Im1hdHJpeCgwLjAwOTQ1MzU4LDAsMCwtMC4wMDk0NTE1NSw4MC44MDIwNywyMDcuNjA5MjEpIg0KICAgICAgIGlkPSJnMTE5ODkiPg0KICAgICAgPHBhdGgNCiAgICAgICAgIGQ9Im0gODU1LDI5NjYgYyAtMzcsLTE2IC05MiwtNzcgLTEwMiwtMTE0IC01LC0xNSAtOCwtMzAwIC04LC02MzMgMCwtNTgzIDEsLTYwOCAxOSwtNjI4IDIzLC0yNSA0NCwtMjcgNzQsLTUgbCAyMiwxNSB2IDYwMyBjIDAsNTk1IDAsNjA0IDIxLDYzMCBsIDIwLDI2IGggNzc1IGMgNzYxLDAgNzc0LDAgNzk0LC0yMCAyMCwtMjAgMjAsLTMzIDIwLC03OTQgdiAtNzc1IGwgLTI2LC0yMCBjIC0yNiwtMjEgLTM1LC0yMSAtNjMwLC0yMSBoIC02MDMgbCAtMTUsLTIyIGMgLTIwLC0yOSAtMjAsLTQxIDIsLTY4IGwgMTgsLTIyIDYyNCwyIGMgNjA1LDEgNjI1LDEgNjYwLDIxIDE5LDExIDQ3LDM2IDYwLDU2IGwgMjUsMzcgMyw3OTAgYyAyLDUzMSAwLDgwMyAtOCw4MjcgLTE0LDUxIC00Nyw4OCAtOTQsMTEwIC0zOSwxOCAtODMsMTkgLTgzMSwxOCAtNjMxLDAgLTc5NiwtMiAtODIwLC0xMyB6Ig0KICAgICAgICAgaWQ9InBhdGgxMTk4MyIgLz4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJtIDE2NzcsMjY4MiBjIC0yNCwtMjYgLTIxLC02OCA1LC04NiAxOSwtMTMgNTksLTE2IDIzMywtMTYgaCAyMTAgTCAxMjM3LDE2OTIgQyA1MTksOTc0IDM1MCw4MDAgMzUwLDc3OSBjIDAsLTMyIDI4LC01OSA2MSwtNTkgMTgsMCAyMjYsMjAyIDkxMSw4ODcgbCA4ODgsODg4IHYgLTIxMCBjIDAsLTIzMyA1LC0yNTUgNTksLTI1NSA2MCwwIDYxLDYgNjEsMzM3IDAsMjc4IC0xLDMwMSAtMTgsMzE2IC0xNiwxNSAtNTMsMTcgLTMxOSwxNyAtMjc4LDAgLTMwMSwtMSAtMzE2LC0xOCB6Ig0KICAgICAgICAgaWQ9InBhdGgxMTk4NSIgLz4NCiAgICAgIDxwYXRoDQogICAgICAgICBkPSJtIDE1NiwxNDg3IGMgLTI1LC0xNCAtNDgsLTM5IC02MywtNjYgLTIzLC00NCAtMjMsLTQ1IC0yMywtNDQyIDAsLTI1NyA0LC00MDggMTEsLTQyNiAxNCwtMzggNTcsLTgzIDk2LC05OSAyNiwtMTEgMTE1LC0xNCA0MzEsLTE0IDM5OCwwIDM5OSwwIDQ0MywyMyAyNywxNSA1MiwzOCA2Niw2MyAyMiwzNyAyMyw1MCAyMywyNjAgMCwxNjEgLTMsMjI0IC0xMiwyMzYgLTIyLDI3IC01MywzMCAtODEsNyBsIC0yNywtMjAgViA3OTUgYyAwLC0yMDIgLTEsLTIxNSAtMTksLTIyNSAtMTMsLTYgLTE1NywtMTAgLTM5OSwtMTAgLTM1NCwwIC0zODAsMSAtMzk1LDE4IC0xNSwxNyAtMTcsNTkgLTE3LDM5NiAwLDI0MSA0LDM4NCAxMCwzOTcgMTAsMTggMjMsMTkgMjI1LDE5IGggMjE0IGwgMjAsMjcgYyAyMywyOCAyMCw1OSAtNyw4MSAtMTIsOSAtNzUsMTIgLTIzNiwxMiAtMjEwLDAgLTIyMywtMSAtMjYwLC0yMyB6Ig0KICAgICAgICAgaWQ9InBhdGgxMTk4NyIgLz4NCiAgICA8L2c+DQogIDwvZz4NCjwvc3ZnPg==');
}

html {
scrollbar-face-color: #646464;
scrollbar-base-color: #646464;
Expand All @@ -64,4 +68,4 @@ html {
::-webkit-scrollbar-track-piece { background-color: #000;}
::-webkit-scrollbar-thumb { height: 50px; background-color: #666; border-radius: 3px;}
::-webkit-scrollbar-corner { background-color: #646464;}}
::-webkit-resizer { background-color: #666;}
::-webkit-resizer { background-color: #666;}
23 changes: 22 additions & 1 deletion panel/template/react/react.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ a.navbar-brand {

p.bk.card-button {
display: none;
}
}

.sidenav {
overflow-x: hidden;
Expand Down Expand Up @@ -198,6 +198,27 @@ p.bk.card-button {
opacity: 1;
}

.maximize{
position: absolute;
top: 2px;
right: 2px;
width: 24px;
height: 24px;
z-index: 10000;
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij4NCg0KPGcNCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgxLjQ2MzgyMSwtMTc5LjQ1MDU0KSINCiAgICAgaWQ9ImxheWVyMSI+DQogICAgPGcNCiAgICAgICBzdHlsZT0iZmlsbDojMDAwMDAwO3N0cm9rZTpub25lIg0KICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuMDA5NDUzNTgsMCwwLC0wLjAwOTQ1MTU1LDgwLjgwMjA3LDIwNy42MDkyMSkiDQogICAgICAgaWQ9ImcxMTk4OSI+DQogICAgICA8cGF0aA0KICAgICAgICAgZD0ibSA4NTUsMjk2NiBjIC0zNywtMTYgLTkyLC03NyAtMTAyLC0xMTQgLTUsLTE1IC04LC0zMDAgLTgsLTYzMyAwLC01ODMgMSwtNjA4IDE5LC02MjggMjMsLTI1IDQ0LC0yNyA3NCwtNSBsIDIyLDE1IHYgNjAzIGMgMCw1OTUgMCw2MDQgMjEsNjMwIGwgMjAsMjYgaCA3NzUgYyA3NjEsMCA3NzQsMCA3OTQsLTIwIDIwLC0yMCAyMCwtMzMgMjAsLTc5NCB2IC03NzUgbCAtMjYsLTIwIGMgLTI2LC0yMSAtMzUsLTIxIC02MzAsLTIxIGggLTYwMyBsIC0xNSwtMjIgYyAtMjAsLTI5IC0yMCwtNDEgMiwtNjggbCAxOCwtMjIgNjI0LDIgYyA2MDUsMSA2MjUsMSA2NjAsMjEgMTksMTEgNDcsMzYgNjAsNTYgbCAyNSwzNyAzLDc5MCBjIDIsNTMxIDAsODAzIC04LDgyNyAtMTQsNTEgLTQ3LDg4IC05NCwxMTAgLTM5LDE4IC04MywxOSAtODMxLDE4IC02MzEsMCAtNzk2LC0yIC04MjAsLTEzIHoiDQogICAgICAgICBpZD0icGF0aDExOTgzIiAvPg0KICAgICAgPHBhdGgNCiAgICAgICAgIGQ9Im0gMTY3NywyNjgyIGMgLTI0LC0yNiAtMjEsLTY4IDUsLTg2IDE5LC0xMyA1OSwtMTYgMjMzLC0xNiBoIDIxMCBMIDEyMzcsMTY5MiBDIDUxOSw5NzQgMzUwLDgwMCAzNTAsNzc5IGMgMCwtMzIgMjgsLTU5IDYxLC01OSAxOCwwIDIyNiwyMDIgOTExLDg4NyBsIDg4OCw4ODggdiAtMjEwIGMgMCwtMjMzIDUsLTI1NSA1OSwtMjU1IDYwLDAgNjEsNiA2MSwzMzcgMCwyNzggLTEsMzAxIC0xOCwzMTYgLTE2LDE1IC01MywxNyAtMzE5LDE3IC0yNzgsMCAtMzAxLC0xIC0zMTYsLTE4IHoiDQogICAgICAgICBpZD0icGF0aDExOTg1IiAvPg0KICAgICAgPHBhdGgNCiAgICAgICAgIGQ9Im0gMTU2LDE0ODcgYyAtMjUsLTE0IC00OCwtMzkgLTYzLC02NiAtMjMsLTQ0IC0yMywtNDUgLTIzLC00NDIgMCwtMjU3IDQsLTQwOCAxMSwtNDI2IDE0LC0zOCA1NywtODMgOTYsLTk5IDI2LC0xMSAxMTUsLTE0IDQzMSwtMTQgMzk4LDAgMzk5LDAgNDQzLDIzIDI3LDE1IDUyLDM4IDY2LDYzIDIyLDM3IDIzLDUwIDIzLDI2MCAwLDE2MSAtMywyMjQgLTEyLDIzNiAtMjIsMjcgLTUzLDMwIC04MSw3IGwgLTI3LC0yMCBWIDc5NSBjIDAsLTIwMiAtMSwtMjE1IC0xOSwtMjI1IC0xMywtNiAtMTU3LC0xMCAtMzk5LC0xMCAtMzU0LDAgLTM4MCwxIC0zOTUsMTggLTE1LDE3IC0xNyw1OSAtMTcsMzk2IDAsMjQxIDQsMzg0IDEwLDM5NyAxMCwxOCAyMywxOSAyMjUsMTkgaCAyMTQgbCAyMCwyNyBjIDIzLDI4IDIwLDU5IC03LDgxIC0xMiw5IC03NSwxMiAtMjM2LDEyIC0yMTAsMCAtMjIzLC0xIC0yNjAsLTIzIHoiDQogICAgICAgICBpZD0icGF0aDExOTg3IiAvPg0KICAgIDwvZz4NCiAgPC9nPg0KPC9zdmc+');
opacity: 0;
transition-delay: 0.5s;
transition: 0.5s;
}

.maximize:hover {
transition: 0.5s;
opacity: 1;
}

.maximize:focus{opacity: 1;
}

.react-resizable {
position: relative;
}
Expand Down
194 changes: 149 additions & 45 deletions panel/template/react/react.html
Original file line number Diff line number Diff line change
Expand Up @@ -126,56 +126,160 @@

<script type="text/babel">
const divStyle = {borderRadius: '5px'};
const ResponsiveGridLayout = ReactGridLayout.WidthProvider(ReactGridLayout.Responsive);

const ResponsiveGridLayout = ReactGridLayout.WidthProvider(ReactGridLayout.Responsive)

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);
}

function ResponsiveGrid(props) {
const layouts = {{layouts}};
return (
<ResponsiveGridLayout
className={"layout"}
cols={ {{cols}} }
breakpoints={ {{breakpoints}} }
draggableHandle={".drag-handle"}
onResize={resize_layout}
onResizeStop={resize_layout_stop}
draggableCancel={".bk-root"}
rowHeight={ {{rowHeight}} }
layouts={layouts}
{% if compact == "both" %}
compactType={"horizontal"}
{% elif compact == "horizontal" %}
verticalCompact={false}
compactType={"horizontal"}
{% elif compact is none %}
verticalCompact={false}
{% 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") }}
</div>
{% set __ = count.append(1) %}
{% endif %}{% endfor %}{% endfor %}
</ResponsiveGridLayout>
);
}

class ResponsiveGrid extends React.Component {
constructor(props) {
super(props);
this.state= {
layouts: {{layouts}},
resizedWidgets: {},
};
}


resize_layout(resized_layouts) {
const { layouts, resizedWidgets } = this.state;

const newLayout = layouts;
newLayout['lg']=resized_layouts;
newLayout['md']=resized_layouts
// reinitilize all widgets maximized state to false if there is some kind of manual resizing event
Object.keys(resizedWidgets).map(function(key, index) {
resizedWidgets[key] = false; });

this.setState({layouts:newLayout, });
window.dispatchEvent(new Event("resize"));
}


resize_layout_stop(resized_layouts) {
console.log(resized_layouts, window.innerWidth);
const { layouts, resizedWidgets } = this.state;

const newLayout = layouts;
newLayout['lg']=resized_layouts;
newLayout['md']=resized_layouts

var myObject = resizedWidgets;
Object.keys(myObject).map(function(key, index) {
myObject[key] = false;
});
console.log(myObject);

this.setState({layouts:newLayout, });
setTimeout(function(){
window.dispatchEvent(new Event("resize"));
}, 100);
}


toggleWidget(id){
const newState = {...this.state.resizedWidgets};
const maximized = typeof newState[id] === 'boolean' ? newState[id] : false;
newState[id] = !maximized;

this.setState({resizedWidgets: newState,}, () => {
window.dispatchEvent(new Event("resize"));
});
}


getModifiedLayouts() {
const N_COLS = {{cols}}
const ROW_HEIGHT = {{rowHeight}}
const { layouts, resizedWidgets } = this.state;

const layout_LG = layouts.lg
const layout_MD = layouts.md

const height_header = 70
const margin_rgl = 10
const N_viewport_rows = parseInt((window.innerHeight-height_header)/(ROW_HEIGHT+margin_rgl))
const N_trues = Object.values(resizedWidgets).reduce((a, item) => a + item, 0)

const newLayouts_LG = layout_LG.map(layout => {
const newLayout = { ...layout };

if (N_trues > 0) {
if (resizedWidgets[newLayout.i]) {
console.log('int', parseInt(window.innerHeight/ROW_HEIGHT));
newLayout.h = N_viewport_rows ;
newLayout.w = N_COLS['lg'];
newLayout.y= 0;
}
else {
newLayout.y= 100
};
};
return newLayout;
});

const newLayouts_MD = layout_MD.map(layout => {
const newLayout = { ...layout };
console.log('modified',newLayout);
if (N_trues > 0) {
if (resizedWidgets[newLayout.i]) {
console.log('int', parseInt(window.innerHeight/ROW_HEIGHT));
newLayout.h = N_viewport_rows ;
newLayout.w = N_COLS['md'];
newLayout.y= 0;
}
else {
newLayout.y= 100
};
};
return newLayout;
});

const newLayouts = {};
newLayouts['lg'] = newLayouts_LG
newLayouts['md'] = newLayouts_MD
return newLayouts

}


render() {
const modifiedLayouts = this.getModifiedLayouts();
return (
<ResponsiveGridLayout
className = {"layout"}
{...this.props}
cols = { {{cols}} }
breakpoints = { {{breakpoints}} }
draggableHandle = {".drag-handle"}
onResize = {this.resize_layout.bind(this)}
onResizeStop = {this.resize_layout_stop.bind(this)}
draggableCancel = {".bk-root"}
rowHeight = { {{rowHeight}} }
layouts = {modifiedLayouts}
verticalCompact = {true}
compactType = {"horizontal"}
>

{% set count = [] %}
{% for doc in docs %}{% for root in doc.roots %}{% if "main" in root.tags %}
<div key="{{count|length + 1 }}" id = {'reactcard' + "{{ count|length + 1}}"} style={divStyle} >
<span className="drag-handle"></span>
<span className="maximize" onClick={() =>
this.toggleWidget("{{count|length + 1 }}")}></span>
{{ embed(root) | indent(4) | replace("class", "className") }}
</div>
{% set __ = count.append(1) %}
{% endif %}{% endfor %}{% endfor %}

</ResponsiveGridLayout>
);
};
}

ReactDOM.render(<ResponsiveGrid />, document.getElementById('responsive-grid'))

</script>


{{ embed(roots.js_area) }}
{{ embed(roots.location) }}

Expand Down