Skip to content

Commit 8403f59

Browse files
author
rodriguez-facundo
committed
#139 Enforce tab render order in flexlayout
1 parent 00c0905 commit 8403f59

3 files changed

Lines changed: 141 additions & 96 deletions

File tree

webapp/components/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
destroyWidget,
88
minimizeWidget,
99
maximizeWidget,
10+
updateWidget,
1011
newWidget
1112
} from "../redux/actions/flexlayout";
1213
import { openBackendErrorDialog, closeBackendErrorDialog } from '../redux/actions/errors';
@@ -93,6 +94,7 @@ import _LayoutManager from "./layout/LayoutManager";
9394
export const LayoutManager = connect(
9495
state => ({ ...state.flexlayout, editMode: state.general.editMode }),
9596
dispatch => ({
97+
updateWidget: widget => dispatch(updateWidget(widget)),
9698
minimizeWidget: id => dispatch(minimizeWidget(id)),
9799
destroyWidget: id => dispatch(destroyWidget(id)),
98100
maximizeWidget: id => dispatch(maximizeWidget(id)),

webapp/components/layout/LayoutManager.js

Lines changed: 4 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import defaultLayoutConfiguration from './layoutConf.json';
1111
import Icon from '@material-ui/core/Icon';
1212

1313
import { withStyles } from '@material-ui/core/styles'
14-
14+
import onAction from './OnLayoutAction';
1515

1616
/**
1717
* Transforms a widget configutation into a flexlayout node descriptor
@@ -219,102 +219,11 @@ class LayoutManager extends Component {
219219
findDeletedWidgets (widgets, oldWidgets) {
220220
return oldWidgets ? Object.values(oldWidgets).filter(widget => widget && !widgets[widget.id]) : Object.values(widgets);
221221
}
222-
223-
224-
onAction (action) {
225-
const model = this.getModel()
226-
switch (action.type){
227-
case Actions.SET_ACTIVE_TABSET:
228-
break;
229-
case Actions.SELECT_TAB:
230-
this.activateWidget(action.data.tabNode);
231-
window.dispatchEvent(new Event('resize'));
232-
break;
233-
case Actions.DELETE_TAB:
234-
this.onActionDeleteWidget(action);
235-
window.dispatchEvent(new Event('resize'));
236-
break;
237-
case Actions.MAXIMIZE_TOGGLE:
238-
this.onActionMaximizeWidget(action);
239-
window.dispatchEvent(new Event('resize'));
240-
break;
241-
case Actions.ADJUST_SPLIT:
242-
case Actions.MOVE_NODE :
243-
window.dispatchEvent(new Event('resize'));
244-
break;
245-
case Actions.ADD_NODE:{
246-
if (this.props.editMode && action.data.toNode === 'hlsPanel') {
247-
action.data.index = this.findWidgetInsertionIndex(action.data.json.config.pos)
248-
}
249-
break
250-
}
251-
}
252-
model.doAction(action);
253-
}
254-
255-
findWidgetInsertionIndex (position) {
256-
const model = this.getModel()
257-
const tabset = model.getNodeById('hlsPanel')
258-
259-
const positions = tabset.getChildren().map(node => node.getConfig().pos)
260-
var index = -1
261-
for (let i = 0; i < positions.length; i++) {
262-
if (position < positions[i]) {
263-
index = i
264-
break
265-
}
266-
}
267-
return index
268-
}
269-
270-
onActionMaximizeWidget (action) {
271-
const model = this.getModel()
272-
const { widgets } = this.props;
273-
const { maximizeWidget, activateWidget } = this;
274-
const panel2maximize = model.getNodeById(action.data.node);
275-
276-
if (panel2maximize.getChildren().length > 0) {
277-
const widgetId2maximize = panel2maximize.getSelectedNode().getId();
278-
const maximizedWidget = this.findMaximizedWidget(widgets);
279-
if (maximizedWidget) {
280-
if (maximizedWidget.id !== widgetId2maximize) {
281-
maximizeWidget(widgetId2maximize);
282-
}
283-
activateWidget(maximizedWidget.id);
284-
285-
} else {
286-
maximizeWidget(widgetId2maximize);
287-
}
288-
}
289-
290-
}
291222

292223
findMaximizedWidget (widgets) {
293224
return Object.values(widgets).find(widget => widget && widget.status == WidgetStatus.MAXIMIZED);
294225
}
295-
296-
onActionDeleteWidget (action) {
297-
const model = this.getModel()
298-
const { widgets } = this.props;
299-
const maximizedWidget = this.findMaximizedWidget(widgets);
300-
// change widget status
301-
this.destroyWidget(action.data.node);
302-
// check if the current maximized widget is the same than in the action dispatched
303-
if (maximizedWidget && maximizedWidget.id == action.data.node) {
304-
// find if there exists another widget in the maximized panel that could take its place
305-
const panelChildren = model.getActiveTabset().getChildren();
306-
const index = panelChildren.findIndex(child => child.getId() == action.data.node);
307-
// Understand if the tab to the left or right of the destroyed tab will be the next one to be maximized
308-
if (index != -1 && panelChildren.length > 1) {
309-
if (index == 0) {
310-
this.onActionMaximizeWidget(panelChildren[1].getId());
311-
} else {
312-
this.onActionMaximizeWidget(panelChildren[index - 1].getId());
313-
}
314-
}
315-
}
316-
}
317-
226+
318227

319228
clickOnBordersAction (node) {
320229
const model = this.getModel()
@@ -329,7 +238,7 @@ class LayoutManager extends Component {
329238
renderValues.leading = <Icon className={node.getConfig().icon}/>
330239
}
331240
render () {
332-
const { classes } = this.props
241+
const { classes, widgets } = this.props
333242
return (
334243
<div className={classes.container}>
335244
<div className={classes.spacer}/>
@@ -339,12 +248,11 @@ class LayoutManager extends Component {
339248
model={this.getModel()}
340249
factory={this.factory.bind(this)}
341250
iconFactory={this.iconFactory.bind(this)}
342-
onAction={action => this.onAction(action)}
251+
onAction={action => onAction(action, widgets, this.getModel(), this.props.updateWidget, this.activateWidget, this.destroyWidget, this.maximizeWidget, this.minimizeWidget)}
343252
clickOnBordersAction={node => this.clickOnBordersAction(node)}
344253
onRenderTab={(node,renderValues) => this.onRenderTab(node,renderValues)}
345254
/>
346255
</div>
347-
348256
<div className={classes.spacer}/>
349257
</div>
350258
)
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import Actions from '@geppettoengine/geppetto-client/js/components/interface/flexLayout2/src/model/Actions';
2+
import { WidgetStatus } from '../../constants';
3+
4+
const onAction = (action, widgets, model, udpateWidget, activateWidget, destroyWidget, maximizeWidget, minimizeWidget) => {
5+
switch (action.type){
6+
case Actions.SET_ACTIVE_TABSET:
7+
break;
8+
case Actions.SELECT_TAB:
9+
activateWidget(action.data.tabNode);
10+
break;
11+
case Actions.DELETE_TAB:
12+
onActionDeleteWidget(action, widgets, model, destroyWidget);
13+
break;
14+
case Actions.MAXIMIZE_TOGGLE:
15+
onActionMaximizeWidget(action, widgets, model, maximizeWidget);
16+
break;
17+
case Actions.ADJUST_SPLIT:
18+
break;
19+
case Actions.ADD_NODE:{
20+
action.data.index = findWidgetInsertionIndex(action, widgets, model)
21+
break
22+
}
23+
case Actions.MOVE_NODE:{
24+
// If the new tabset already exists, set insertion position
25+
if (action.data.location === 'center') {
26+
action.data.index = findWidgetInsertionIndex(action, widgets, model)
27+
}
28+
// store the tabset id where the node will be moved from
29+
var fromTabsetId = getTabsetId(action, model)
30+
break
31+
}
32+
}
33+
34+
model.doAction(action);
35+
36+
// Flexlayout needs to create a tabset before we can update the panelName for the moved widget
37+
if (action.type === Actions.MOVE_NODE){
38+
moveNode(action, widgets, model, fromTabsetId, udpateWidget, activateWidget)
39+
}
40+
window.dispatchEvent(new Event('resize'));
41+
}
42+
43+
const getTabsetId = (action, model) => {
44+
const widgetId = action.data.fromNode
45+
return model.getNodeById(widgetId).getParent().getId()
46+
}
47+
48+
const moveNode = (action, widgets, model, fromTabsetId, udpateWidget, activateWidget, minimizeWidget) => {
49+
// Update widget.panelName for new tabset location
50+
const widgetId = action.data.fromNode
51+
const widget = { ...widgets[widgetId] }
52+
const panelName = getTabsetId(action, model)
53+
widget.status = WidgetStatus.ACTIVE
54+
widget.panelName = panelName
55+
widget.instancePath = widgetId
56+
udpateWidget(widget)
57+
58+
// Elect a new active widget in old panel
59+
const fromTabset = model.getNodeById(fromTabsetId)
60+
61+
if (fromTabset) {
62+
const fromTabsetChildren = fromTabset.getChildren().filter(child => child.getId() !== action.data.fromNode)
63+
if (fromTabsetChildren.length > 0) {
64+
const newActiveWidget = fromTabsetChildren[0].getConfig()
65+
newActiveWidget.status = WidgetStatus.ACTIVE
66+
newActiveWidget.instancePath = newActiveWidget.id
67+
activateWidget(newActiveWidget.id)
68+
}
69+
}
70+
71+
72+
}
73+
74+
const findWidgetInsertionIndex = (action, widgets, model) => {
75+
var position = 0
76+
if (action.type === Actions.ADD_NODE) {
77+
position = action.data.json.config.pos
78+
} else {
79+
position = widgets[action.data.fromNode].pos
80+
}
81+
82+
const tabset = model.getNodeById(action.data.toNode)
83+
const positions = tabset.getChildren().map(node => node.getConfig().pos)
84+
var index = -1
85+
for (let i = 0; i < positions.length; i++) {
86+
if (position < positions[i]) {
87+
index = i
88+
break
89+
}
90+
}
91+
return index
92+
}
93+
94+
const findMaximizedWidget = widgets => Object.values(widgets).find(widget => widget && widget.status == WidgetStatus.MAXIMIZED)
95+
96+
const onActionDeleteWidget = (action, widgets, model, destroyWidget) => {
97+
const maximizedWidget = findMaximizedWidget(widgets);
98+
// change widget status
99+
destroyWidget(action.data.node);
100+
// check if the current maximized widget is the same than in the action dispatched
101+
if (maximizedWidget && maximizedWidget.id == action.data.node) {
102+
// find if there exists another widget in the maximized panel that could take its place
103+
const panelChildren = model.getActiveTabset().getChildren();
104+
const index = panelChildren.findIndex(child => child.getId() == action.data.node);
105+
// Understand if the tab to the left or right of the destroyed tab will be the next one to be maximized
106+
if (index != -1 && panelChildren.length > 1) {
107+
if (index == 0) {
108+
onActionMaximizeWidget(panelChildren[1].getId(), widgets, model);
109+
} else {
110+
onActionMaximizeWidget(panelChildren[index - 1].getId(), widgets, model);
111+
}
112+
}
113+
}
114+
}
115+
116+
const onActionMaximizeWidget = (action, widgets, model, activateWidget, maximizeWidget) => {
117+
const panel2maximize = model.getNodeById(action.data.node);
118+
119+
if (panel2maximize.getChildren().length > 0) {
120+
const widgetId2maximize = panel2maximize.getSelectedNode().getId();
121+
const maximizedWidget = this.findMaximizedWidget(widgets);
122+
if (maximizedWidget) {
123+
if (maximizedWidget.id !== widgetId2maximize) {
124+
maximizeWidget(widgetId2maximize, maximizeWidget);
125+
}
126+
activateWidget(maximizedWidget.id, activateWidget);
127+
128+
} else {
129+
maximizeWidget(widgetId2maximize);
130+
}
131+
}
132+
133+
}
134+
135+
export default onAction

0 commit comments

Comments
 (0)