Skip to content

Commit 0d67f94

Browse files
author
maksat.allakyev
committed
Add copy and refresh buttons for AIChat - Assistant messages
1 parent 85bfa6d commit 0d67f94

File tree

2 files changed

+90
-23
lines changed

2 files changed

+90
-23
lines changed

CS/ReportingApp/wwwroot/css/site.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,9 @@ min-height: 100%;
112112
line-height: 50px;
113113
height: 60px;
114114
}
115+
116+
.dx-chat-messagegroup-alignment-start:last-child .dx-chat-messagebubble:last-child .dx-bubble-button-containder {
117+
display: flex;
118+
gap: 4px;
119+
margin-top: 8px;
120+
}

CS/ReportingApp/wwwroot/js/aiIntegration.js

Lines changed: 84 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,107 @@
1-
function normilizeAIResponse(text) {
1+

2+
let lastUserQuery;
3+
4+
const assistant = {
5+
id: 'assistant',
6+
name: 'Virtual Assistant',
7+
};
8+
9+
const user = {
10+
id: 'user',
11+
};
12+
13+
function normilizeAIResponse(text) {
214
text = text.replace(/\d+:\d+[^\】]+/g, "");
315
let html = marked.parse(text);
416
if (/<p>\.\s*<\/p>\s*$/.test(html))
517
html = html.replace(/<p>\.\s*<\/p>\s*$/, "")
618
return html;
719
}
820

21+
function copyText(text) {
22+
navigator.clipboard.writeText(text);
23+
}
24+
25+
async function getAIResponse(text, id) {
26+
const formData = new FormData();
27+
formData.append('text', text);
28+
formData.append('chatId', id);
29+
lastUserQuery = text;
30+
const response = await fetch(`/AI/GetAnswer`, {
31+
method: 'POST',
32+
body: formData
33+
});
34+
return await response.text();
35+
}
36+
37+
function RenderAssistantMessage(instance, message) {
38+
instance.option({ typingUsers: [] });
39+
instance.renderMessage({ timestamp: new Date(), text: message, author: assistant.name, id: assistant.id });
40+
}
41+
42+
async function refreshAnswer(instance) {
43+
const items = instance.option('items');
44+
const newItems = items.slice(0, -1);
45+
instance.option({ items: newItems });
46+
instance.option({ typingUsers: [assistant] });
47+
const aiResponse = await getAIResponse(lastUserQuery, assistant.id);
48+
setTimeout(() => {
49+
instance.option({ typingUsers: [] });
50+
RenderAssistantMessage(instance, aiResponse);
51+
}, 200);
52+
}
53+
954
function createAssistantTab(chatId) {
55+
assistant.id = chatId;
1056
const model = {
1157
title: 'AI Assistant',
12-
chatId: chatId,
1358
showAvatar: false,
1459
showUserName: false,
1560
showMessageTimestamp: false,
16-
user: {
17-
id: 1,
18-
},
61+
user: user,
1962
messageTemplate: (data, container) => {
20-
if(data.message.author.id === 'Assistant')
21-
return normilizeAIResponse(data.message.text);
22-
return data.message.text;
63+
const { message } = data;
64+
65+
if (message.author.id && message.author.id !== assistant.id)
66+
return message.text;
67+
68+
const $textElement = $('<div>')
69+
.html(normilizeAIResponse(message.text))
70+
.appendTo(container);
71+
const $buttonContainer = $('<div>')
72+
.addClass('dx-bubble-button-containder');
73+
$('<div>')
74+
.dxButton({
75+
icon: 'copy',
76+
stylingMode: 'text',
77+
onClick: () => {
78+
const text = $textElement.text();
79+
copyText(text);
80+
}
81+
})
82+
.appendTo($buttonContainer);
83+
$('<div>')
84+
.dxButton({
85+
icon: 'refresh',
86+
stylingMode: 'text',
87+
onClick: () => {
88+
refreshAnswer(data.component);
89+
},
90+
})
91+
.appendTo($buttonContainer);
92+
$buttonContainer.appendTo(container);
2393
},
24-
onMessageEntered: (e) => {
94+
onMessageEntered: async (e) => {
2595
const instance = e.component;
2696
instance.renderMessage(e.message);
97+
instance.option({ typingUsers: [assistant] });
98+
const userInput = e.message.text;
2799

28-
const formData = new FormData();
29-
formData.append('text', e.message.text);
30-
formData.append('chatId', model.chatId);
31-
fetch(`/AI/GetAnswer`, {
32-
method: 'POST',
33-
body: formData
34-
}).then((x) => {
35-
x.text().then((res) => {
36-
instance.renderMessage({
37-
text: res,
38-
author: { id: 'Assistant' }
39-
}, { id: 'Assistant' });
40-
});
41-
});
100+
var response = await getAIResponse(userInput, assistant.id);
101+
RenderAssistantMessage(instance, response);
42102
}
43103
};
104+
44105
return new DevExpress.Analytics.Utils.TabInfo({
45106
text: 'AI Assistant',
46107
template: 'dxrd-ai-panel',

0 commit comments

Comments
 (0)