Skip to content

Commit 5a5b417

Browse files
authored
🎨 [Frontend] Suport Center: Chat bubble and Fogbugz link (#8369)
1 parent 15fd04e commit 5a5b417

File tree

14 files changed

+363
-88
lines changed

14 files changed

+363
-88
lines changed

services/static-webserver/client/Manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"css": [
3636
"jsontreeviewer/jsonTree.css",
3737
"hint/hint.css",
38+
"marked/markdown.css",
3839
"common/common.css"
3940
]
4041
},

services/static-webserver/client/source/class/osparc/conversation/AddMessage.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,12 @@ qx.Class.define("osparc.conversation.AddMessage", {
8383
}
8484
case "comment-field":
8585
control = new osparc.editor.MarkdownEditor();
86-
control.addListener("keydown", e => {
87-
if (e.isCtrlPressed() && e.getKeyIdentifier() === "Enter") {
88-
this.addComment();
89-
e.stopPropagation();
90-
e.preventDefault();
91-
}
92-
}, this);
93-
control.getChildControl("buttons").exclude();
86+
control.addListener("textChanged", () => this.__addCommentPressed(), this);
87+
control.setCompact(true);
9488
control.getChildControl("text-area").getContentElement().setStyles({
9589
"border-top-right-radius": "0px", // no roundness there to match the arrow button
9690
});
91+
// make it more compact
9792
this.getChildControl("add-comment-layout").add(control, {
9893
flex: 1
9994
});
@@ -102,7 +97,8 @@ qx.Class.define("osparc.conversation.AddMessage", {
10297
control = new qx.ui.form.Button(null, "@FontAwesome5Solid/arrow-up/16").set({
10398
backgroundColor: "input_background",
10499
allowGrowX: false,
105-
alignX: "right"
100+
alignX: "right",
101+
alignY: "middle",
106102
});
107103
control.getContentElement().setStyles({
108104
"border-bottom": "1px solid " + qx.theme.manager.Color.getInstance().resolve("default-button-active"),
@@ -161,9 +157,6 @@ qx.Class.define("osparc.conversation.AddMessage", {
161157
// edit mode
162158
const commentField = this.getChildControl("comment-field");
163159
commentField.setText(message["content"]);
164-
165-
const addMessageButton = this.getChildControl("add-comment-button");
166-
addMessageButton.setLabel(this.tr("Edit message"));
167160
}
168161
},
169162

services/static-webserver/client/source/class/osparc/conversation/MessageUI.js

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ qx.Class.define("osparc.conversation.MessageUI", {
2828

2929
this.__studyData = studyData;
3030

31-
const layout = new qx.ui.layout.Grid(12, 2);
32-
layout.setColumnFlex(1, 1); // content
33-
this._setLayout(layout);
31+
this._setLayout(new qx.ui.layout.HBox(10));
3432
this.setPadding(5);
3533

3634
this.set({
@@ -69,22 +67,22 @@ qx.Class.define("osparc.conversation.MessageUI", {
6967
case "thumbnail":
7068
control = new osparc.ui.basic.UserThumbnail(32).set({
7169
marginTop: 4,
70+
alignY: "top",
7271
});
73-
this._add(control, {
74-
row: 0,
75-
column: isMyMessage ? 2 : 0,
76-
rowSpan: 2,
77-
});
72+
this._addAt(control, isMyMessage ? 1 : 0);
73+
break;
74+
case "main-layout":
75+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox(2).set({
76+
alignX: isMyMessage ? "right" : "left"
77+
}));
78+
this._addAt(control, isMyMessage ? 0 : 1, { flex: 1});
7879
break;
7980
case "header-layout":
8081
control = new qx.ui.container.Composite(new qx.ui.layout.HBox(5).set({
8182
alignX: isMyMessage ? "right" : "left"
8283
}));
8384
control.addAt(new qx.ui.basic.Label("-"), 1);
84-
this._add(control, {
85-
row: 0,
86-
column: 1
87-
});
85+
this.getChildControl("main-layout").addAt(control, 0);
8886
break;
8987
case "user-name":
9088
control = new qx.ui.basic.Label().set({
@@ -100,25 +98,21 @@ qx.Class.define("osparc.conversation.MessageUI", {
10098
});
10199
this.getChildControl("header-layout").addAt(control, isMyMessage ? 0 : 2);
102100
break;
103-
case "message-content":
104-
control = new osparc.ui.markdown.Markdown().set({
105-
noMargin: true,
106-
allowGrowX: true,
107-
});
108-
control.getContentElement().setStyles({
109-
"text-align": isMyMessage ? "right" : "left",
110-
});
111-
this._add(control, {
112-
row: 1,
113-
column: 1,
101+
case "message-bubble":
102+
control = new qx.ui.container.Composite(new qx.ui.layout.VBox().set({
103+
alignX: isMyMessage ? "right" : "left"
104+
})).set({
105+
decorator: "chat-bubble",
106+
allowGrowX: false,
107+
padding: 8,
114108
});
109+
const bubbleStyle = isMyMessage ? { "border-top-right-radius": "0px" } : { "border-top-left-radius": "0px" };
110+
control.getContentElement().setStyles(bubbleStyle);
111+
this.getChildControl("main-layout").addAt(control, 1);
115112
break;
116-
case "spacer":
117-
control = new qx.ui.core.Spacer();
118-
this._add(control, {
119-
row: 1,
120-
column: isMyMessage ? 0 : 2,
121-
});
113+
case "message-content":
114+
control = new osparc.ui.markdown.MarkdownChat();
115+
this.getChildControl("message-bubble").add(control);
122116
break;
123117
case "menu-button": {
124118
const buttonSize = 22;
@@ -129,14 +123,10 @@ qx.Class.define("osparc.conversation.MessageUI", {
129123
allowGrowY: false,
130124
marginTop: 4,
131125
alignY: "top",
132-
icon: "@FontAwesome5Solid/ellipsis-v/14",
126+
icon: "@FontAwesome5Solid/ellipsis-v/12",
133127
focusable: false
134128
});
135-
this._add(control, {
136-
row: 0,
137-
column: 3,
138-
rowSpan: 2,
139-
});
129+
this._addAt(control, 2);
140130
break;
141131
}
142132
}
@@ -145,13 +135,6 @@ qx.Class.define("osparc.conversation.MessageUI", {
145135
},
146136

147137
__applyMessage: function(message) {
148-
const isMyMessage = this.self().isMyMessage(message);
149-
this._getLayout().setColumnFlex(isMyMessage ? 0 : 2, 3); // spacer
150-
151-
const thumbnail = this.getChildControl("thumbnail");
152-
153-
const userName = this.getChildControl("user-name");
154-
155138
const createdDateData = new Date(message["created"]);
156139
const createdDate = osparc.utils.Utils.formatDateAndTime(createdDateData);
157140
const lastUpdate = this.getChildControl("last-updated");
@@ -166,6 +149,8 @@ qx.Class.define("osparc.conversation.MessageUI", {
166149
const messageContent = this.getChildControl("message-content");
167150
messageContent.setValue(message["content"]);
168151

152+
const thumbnail = this.getChildControl("thumbnail");
153+
const userName = this.getChildControl("user-name");
169154
if (message["userGroupId"] === "system") {
170155
userName.setValue("Support");
171156
} else {
@@ -180,8 +165,6 @@ qx.Class.define("osparc.conversation.MessageUI", {
180165
});
181166
}
182167

183-
this.getChildControl("spacer");
184-
185168
if (this.self().isMyMessage(message)) {
186169
const menuButton = this.getChildControl("menu-button");
187170

services/static-webserver/client/source/class/osparc/data/model/Conversation.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,13 @@ qx.Class.define("osparc.data.model.Conversation", {
293293
return null;
294294
},
295295

296+
getFogbugzLink: function() {
297+
if (this.getExtraContext() && "fogbugz_case_url" in this.getExtraContext()) {
298+
return this.getExtraContext()["fogbugz_case_url"];
299+
}
300+
return null;
301+
},
302+
296303
getAppointment: function() {
297304
if (this.getExtraContext() && "appointment" in this.getExtraContext()) {
298305
return this.getExtraContext()["appointment"];

services/static-webserver/client/source/class/osparc/editor/MarkdownEditor.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ qx.Class.define("osparc.editor.MarkdownEditor", {
4242
});
4343
},
4444

45+
properties: {
46+
compact: {
47+
check: "Boolean",
48+
init: null,
49+
apply: "__applyCompact",
50+
}
51+
},
52+
4553
members: {
4654
_createChildControlImpl: function(id) {
4755
let control;
@@ -69,6 +77,12 @@ qx.Class.define("osparc.editor.MarkdownEditor", {
6977
}
7078
}
7179
return control || this.base(arguments, id);
72-
}
80+
},
81+
82+
__applyCompact: function(value) {
83+
this.getChildControl("buttons").setVisibility(value ? "excluded" : "visible");
84+
this.getChildControl("tabs").getChildControl("bar").setVisibility(value ? "excluded" : "visible");
85+
this.getChildControl("subtitle").setVisibility(value ? "excluded" : "visible");
86+
},
7387
}
7488
});

services/static-webserver/client/source/class/osparc/editor/TextEditor.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ qx.Class.define("osparc.editor.TextEditor", {
3232
}
3333

3434
this.__addButtons();
35+
36+
this.addListener("keydown", e => {
37+
if (e.isCtrlPressed() && e.getKeyIdentifier() === "Enter") {
38+
const text = this.getChildControl("text-area").getValue();
39+
this.fireDataEvent("textChanged", text);
40+
e.stopPropagation();
41+
e.preventDefault();
42+
}
43+
}, this);
3544
},
3645

3746
events: {

services/static-webserver/client/source/class/osparc/study/Conversation.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ qx.Class.define("osparc.study.Conversation", {
342342
switch (message["type"]) {
343343
case "MESSAGE":
344344
control = new osparc.conversation.MessageUI(message, this.__studyData);
345+
control.getChildControl("message-content").set({
346+
measurerMaxWidth: 400,
347+
});
345348
control.addListener("messageUpdated", e => this.updateMessage(e.getData()));
346349
control.addListener("messageDeleted", e => this.deleteMessage(e.getData()));
347350
break;

services/static-webserver/client/source/class/osparc/support/Conversation.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ qx.Class.define("osparc.support.Conversation", {
105105
this.bind("conversation", control, "conversationId", {
106106
converter: conversation => conversation ? conversation.getConversationId() : null
107107
});
108-
// make it more compact
109-
control.getChildControl("comment-field").getChildControl("tabs").getChildControl("bar").exclude();
110-
control.getChildControl("comment-field").getChildControl("subtitle").exclude();
111108
this._addAt(control, 4);
112109
break;
113110
case "share-project-layout":
@@ -155,6 +152,7 @@ qx.Class.define("osparc.support.Conversation", {
155152
// make these checks first, setConversation will reload messages
156153
if (
157154
this.__messages.length === 1 &&
155+
this.__messages[0]["systemMessageType"] &&
158156
this.__messages[0]["systemMessageType"] === osparc.support.Conversation.SYSTEM_MESSAGE_TYPE.BOOK_A_CALL
159157
) {
160158
isBookACall = true;

services/static-webserver/client/source/class/osparc/support/ConversationPage.js

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,6 @@ qx.Class.define("osparc.support.ConversationPage", {
196196
return new qx.ui.basic.Label(text).set({
197197
font: "text-12",
198198
textColor: "text-disabled",
199-
rich: true,
200199
allowGrowX: true,
201200
selectable: true,
202201
});
@@ -207,31 +206,24 @@ qx.Class.define("osparc.support.ConversationPage", {
207206
if (extraContext && Object.keys(extraContext).length) {
208207
const ticketIdLabel = createExtraContextLabel(`Ticket ID: ${osparc.utils.Utils.uuidToShort(conversation.getConversationId())}`);
209208
extraContextLayout.add(ticketIdLabel);
210-
const contextProjectId = conversation.getContextProjectId();
211-
if (contextProjectId && amISupporter) {
212-
const projectIdLabel = createExtraContextLabel(`Project ID: ${osparc.utils.Utils.uuidToShort(contextProjectId)}`);
213-
extraContextLayout.add(projectIdLabel);
214-
}
215-
/*
216-
const appointment = conversation.getAppointment();
217-
if (appointment) {
218-
const appointmentLabel = createExtraContextLabel();
219-
let appointmentText = "Appointment: ";
220-
if (appointment === "requested") {
221-
// still pending
222-
appointmentText += appointment;
223-
} else {
224-
// already set
225-
appointmentText += osparc.utils.Utils.formatDateAndTime(new Date(appointment));
226-
appointmentLabel.set({
227-
cursor: "pointer",
228-
toolTipText: osparc.utils.Utils.formatDateWithCityAndTZ(new Date(appointment)),
209+
if (amISupporter) {
210+
const fogbugzLink = conversation.getFogbugzLink();
211+
if (fogbugzLink) {
212+
const text = "Fogbugz Case: " + fogbugzLink.split("/").pop();
213+
const fogbugzLabel = new osparc.ui.basic.LinkLabel(text, fogbugzLink).set({
214+
font: "link-label-12",
215+
textColor: "text-disabled",
216+
allowGrowX: true,
229217
});
218+
extraContextLayout.add(fogbugzLabel);
219+
}
220+
const contextProjectId = conversation.getContextProjectId();
221+
if (contextProjectId) {
222+
const projectIdLabel = createExtraContextLabel(`Project ID: ${osparc.utils.Utils.uuidToShort(contextProjectId)}`);
223+
extraContextLayout.add(projectIdLabel);
230224
}
231-
appointmentLabel.setValue(appointmentText);
232-
extraContextLayout.add(appointmentLabel);
225+
233226
}
234-
*/
235227
}
236228
};
237229
updateExtraContext();

services/static-webserver/client/source/class/osparc/theme/Decoration.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ qx.Theme.define("osparc.theme.Decoration", {
2929
"chat-bubble": {
3030
style: {
3131
radius: 4,
32-
width: 1,
33-
color: "text-disabled"
32+
// width: 1,
33+
// color: "text-disabled",
34+
backgroundColor: "background-main-2",
3435
}
3536
},
3637

0 commit comments

Comments
 (0)