Skip to content

Commit b0342a5

Browse files
authored
Nodes Tree UI/UX: Show/hide action buttons (ITISFoundation#2565)
1 parent cbaaeb2 commit b0342a5

File tree

7 files changed

+225
-192
lines changed

7 files changed

+225
-192
lines changed

services/web/client/source/class/osparc/auth/Manager.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ qx.Class.define("osparc.auth.Manager", {
153153
profile["groups"]["organizations"].forEach(org => orgIds.push(org["gid"]));
154154
osparc.auth.Data.getInstance().setOrgIds(orgIds);
155155
}
156-
osparc.data.Permissions.getInstance().setRole(profile.role);
156+
const role = profile.role.toLowerCase();
157+
osparc.data.Permissions.getInstance().setRole(role);
157158

158159
this.__fetchStartUpResources();
159160
},

services/web/client/source/class/osparc/component/widget/NodeTreeItem.js

Lines changed: 138 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
Authors:
1414
* Tobias Oetiker (oetiker)
15+
* Odei Maiz (odeimaiz)
1516
1617
************************************************************************ */
1718

@@ -37,9 +38,17 @@
3738
*/
3839

3940
qx.Class.define("osparc.component.widget.NodeTreeItem", {
40-
extend : qx.ui.tree.VirtualTreeItem,
41+
extend: qx.ui.tree.VirtualTreeItem,
4142

42-
properties : {
43+
construct: function(study) {
44+
this.base(arguments);
45+
46+
this.__study = study;
47+
this.__setNotHoveredStyle();
48+
this.__attachEventHandlers();
49+
},
50+
51+
properties: {
4352
nodeId : {
4453
check : "String",
4554
event: "changeNodeId",
@@ -48,7 +57,78 @@ qx.Class.define("osparc.component.widget.NodeTreeItem", {
4857
}
4958
},
5059

51-
members : {
60+
events: {
61+
"openNode": "qx.event.type.Data",
62+
"renameNode": "qx.event.type.Data",
63+
"deleteNode": "qx.event.type.Data"
64+
},
65+
66+
members: {
67+
__study: null,
68+
69+
_createChildControlImpl: function(id) {
70+
let control;
71+
switch (id) {
72+
case "buttons": {
73+
control = new qx.ui.container.Composite(new qx.ui.layout.HBox(0).set({
74+
alignY: "middle"
75+
}));
76+
control.exclude();
77+
this.addWidget(control);
78+
break;
79+
}
80+
case "open-btn": {
81+
const part = this.getChildControl("buttons");
82+
control = new qx.ui.form.Button().set({
83+
backgroundColor: "transparent",
84+
toolTipText: this.tr("openNode"),
85+
icon: "@FontAwesome5Solid/edit/9"
86+
});
87+
control.addListener("execute", () => this.fireDataEvent("openNode", this.getNodeId()));
88+
part.add(control);
89+
break;
90+
}
91+
case "rename-btn": {
92+
const part = this.getChildControl("buttons");
93+
control = new qx.ui.form.Button().set({
94+
backgroundColor: "transparent",
95+
toolTipText: this.tr("renameNode"),
96+
icon: "@FontAwesome5Solid/i-cursor/9"
97+
});
98+
control.addListener("execute", () => this.fireDataEvent("renameNode", this.getNodeId()));
99+
part.add(control);
100+
break;
101+
}
102+
case "delete-btn": {
103+
const part = this.getChildControl("buttons");
104+
control = new qx.ui.form.Button().set({
105+
backgroundColor: "transparent",
106+
toolTipText: this.tr("deleteNode"),
107+
icon: "@FontAwesome5Solid/trash/9"
108+
});
109+
control.addListener("execute", () => this.fireDataEvent("deleteNode", this.getNodeId()));
110+
part.add(control);
111+
break;
112+
}
113+
case "node-id": {
114+
control = new qx.ui.basic.Label().set({
115+
maxWidth: 250
116+
});
117+
this.bind("nodeId", control, "value", {
118+
converter: value => value && value.substring(0, 8)
119+
});
120+
const permissions = osparc.data.Permissions.getInstance();
121+
control.setVisibility(permissions.canDo("study.nodestree.uuid.read") ? "visible" : "excluded");
122+
permissions.addListener("changeRole", () => {
123+
control.setVisibility(permissions.canDo("study.nodestree.uuid.read") ? "visible" : "excluded");
124+
});
125+
this.addWidget(control);
126+
}
127+
}
128+
129+
return control || this.base(arguments, id);
130+
},
131+
52132
_addWidgets: function() {
53133
// Here's our indentation and tree-lines
54134
this.addSpacer();
@@ -69,13 +149,10 @@ qx.Class.define("osparc.component.widget.NodeTreeItem", {
69149
flex: 1
70150
});
71151

72-
if (osparc.data.Permissions.getInstance().canDo("study.nodestree.uuid.read")) {
73-
// Add a NodeId
74-
const nodeIdWidget = new qx.ui.basic.Label();
75-
this.bind("nodeId", nodeIdWidget, "value");
76-
nodeIdWidget.setMaxWidth(250);
77-
this.addWidget(nodeIdWidget);
78-
}
152+
this.getChildControl("open-btn");
153+
this.getChildControl("rename-btn");
154+
this.getChildControl("delete-btn");
155+
this.getChildControl("node-id");
79156
},
80157

81158
_applyNodeId: function(nodeId) {
@@ -85,6 +162,57 @@ qx.Class.define("osparc.component.widget.NodeTreeItem", {
85162
} else {
86163
osparc.utils.Utils.setIdToWidget(this, "nodeTreeItem_" + nodeId);
87164
}
165+
const opnBtn = this.getChildControl("open-btn");
166+
osparc.utils.Utils.setIdToWidget(opnBtn, "openNodeBtn_"+this.getNodeId());
167+
},
168+
169+
__setHoveredStyle: function() {
170+
this.getContentElement().setStyles({
171+
"border-radius": "4px",
172+
"border": "1px solid " + qx.theme.manager.Color.getInstance().resolve("background-selected")
173+
});
174+
},
175+
176+
__setNotHoveredStyle: function() {
177+
this.getContentElement().setStyles({
178+
"border-radius": "4px",
179+
"border": "1px solid transparent"
180+
});
181+
},
182+
183+
__attachEventHandlers: function() {
184+
this.addListener("mouseover", () => {
185+
this.getChildControl("buttons").show();
186+
this.__setHoveredStyle();
187+
});
188+
this.addListener("mouseout", () => {
189+
if (!this.hasState("selected")) {
190+
this.getChildControl("buttons").exclude();
191+
}
192+
this.__setNotHoveredStyle();
193+
});
194+
},
195+
196+
// overridden
197+
addState: function(state) {
198+
this.base(arguments, state);
199+
200+
if (state === "selected") {
201+
this.getChildControl("buttons").show();
202+
this.getChildControl("delete-btn").setEnabled(false);
203+
}
204+
},
205+
206+
// overridden
207+
removeState: function(state) {
208+
this.base(arguments, state);
209+
if (state === "selected") {
210+
this.getChildControl("buttons").exclude();
211+
const studyId = this.__study.getUuid();
212+
const readOnly = this.__study.isReadOnly();
213+
// disable delete button if the study is read only or if it's the study node item
214+
this.getChildControl("delete-btn").setEnabled(!readOnly && studyId !== this.getNodeId());
215+
}
88216
}
89217
}
90218
});

0 commit comments

Comments
 (0)