agents.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /**
  2. * Copyright (c) UNA, Inc - https://una.io
  3. * MIT License - https://opensource.org/licenses/MIT
  4. *
  5. * @defgroup UnaStudio UNA Studio
  6. * @{
  7. */
  8. function BxDolStudioPageAgents(oOptions)
  9. {
  10. BxDolStudioPage.call(this, oOptions);
  11. this.sPageUrl = oOptions.sPageUrl;
  12. this.sActionUrl = oOptions.sActionUrl;
  13. this.sObjName = oOptions.sObjName == undefined ? 'oBxDolStudioPageAgents' : oOptions.sObjName;
  14. this.sActionUrlGrid = oOptions.sActionUrlGrid == undefined ? this.sActionUrl : oOptions.sActionUrlGrid;
  15. this.sObjNameGrid = oOptions.sObjNameGrid == undefined ? '' : oOptions.sObjNameGrid;
  16. var $this = this;
  17. $(document).ready(function () {
  18. $this.initGrid();
  19. });
  20. }
  21. BxDolStudioPageAgents.prototype = Object.create(BxDolStudioPage.prototype);
  22. BxDolStudioPageAgents.prototype.constructor = BxDolStudioPageAgents;
  23. BxDolStudioPageAgents.prototype.initGrid = function() {
  24. if (typeof(glGrids) == 'undefined' || !this.sObjNameGrid || !glGrids[this.sObjNameGrid])
  25. return;
  26. glGrids[this.sObjNameGrid].setOnReload(function() {
  27. document.location = document.location;
  28. });
  29. };
  30. BxDolStudioPageAgents.prototype.initAgentChat = function(sSelector, iAgentId, aThreads) {
  31. var $this = this;
  32. if (typeof aThreads === 'undefined') {
  33. this._fetchAgentChatThreads(iAgentId, function(aList) {
  34. $this.initAgentChat(sSelector, iAgentId, aList || []);
  35. });
  36. return;
  37. }
  38. var oChat = $(sSelector);
  39. if (!oChat.length)
  40. return;
  41. this.destroyAgentChat();
  42. this._ensureAgentChatStyles();
  43. this._sAgentChatSelector = sSelector;
  44. this._iAgentChatId = iAgentId;
  45. var oBox = oChat.closest('.bx-agents-popup-chat-wrap');
  46. if (!oBox.length)
  47. oBox = this._ensureAgentChatWrap(oChat, iAgentId);
  48. if (!aThreads.length && !oBox.find('.bx-agents-popup-chat-thread').length)
  49. aThreads = [{ thread_id: '', writable: 1, context_pid: 0, title: 'Guest', meta: '' }];
  50. if (aThreads.length)
  51. this._fillAgentChatThreads(oBox, aThreads);
  52. this._oAgentChatBox = oBox;
  53. oBox.off('click.agentChat').on('click.agentChat', '.bx-agents-popup-chat-thread', function(e) {
  54. e.preventDefault();
  55. $this._openAgentChatThread($(this));
  56. });
  57. this._bindAgentChatSearch(oBox);
  58. var oFirst = oBox.find('.bx-agents-popup-chat-thread').first();
  59. if (oFirst.length)
  60. this._openAgentChatThread(oFirst);
  61. else
  62. this._initWritableAgentChat(sSelector, iAgentId, 0);
  63. };
  64. BxDolStudioPageAgents.prototype._fetchAgentChatThreads = function(iAgentId, fDone) {
  65. var sUrl = (typeof sUrlRoot !== 'undefined' ? sUrlRoot : '/') + 'grid.php?o=sys_studio_agents_agents&a=get_chat_threads&id=' + encodeURIComponent(iAgentId) + '&_r=' + Date.now();
  66. if (typeof glGrids !== 'undefined' && this.sObjNameGrid && glGrids[this.sObjNameGrid] && glGrids[this.sObjNameGrid]._sCsrfToken)
  67. sUrl += '&csrf_token=' + encodeURIComponent(glGrids[this.sObjNameGrid]._sCsrfToken);
  68. $.getJSON(sUrl, function(oData) {
  69. fDone((oData && oData.threads) ? oData.threads : []);
  70. }).fail(function() {
  71. fDone([]);
  72. });
  73. };
  74. BxDolStudioPageAgents.prototype._ensureAgentChatWrap = function(oChat, iAgentId) {
  75. oChat.wrap('<div class="bx-agents-popup-chat-wrap" data-agent-id="' + parseInt(iAgentId, 10) + '"><div class="bx-agents-popup-chat-main"></div></div>');
  76. var oMain = oChat.parent();
  77. var oBox = oMain.parent();
  78. oMain.append('<div class="bx-agents-popup-chat-note" style="display:none;">View only</div>');
  79. oChat.before('<div class="bx-agents-popup-chat-artifacts" style="display:none;"></div>');
  80. oBox.prepend('<aside class="bx-agents-popup-chat-list"><div class="bx-agents-popup-chat-list-title">Chats</div><div class="bx-agents-popup-chat-list-items"></div></aside>');
  81. return oBox;
  82. };
  83. BxDolStudioPageAgents.prototype._fillAgentChatThreads = function(oBox, aThreads) {
  84. var oItems = oBox.find('.bx-agents-popup-chat-list-items');
  85. if (!oItems.length)
  86. return;
  87. oItems.empty();
  88. for (var i = 0; i < aThreads.length; i++) {
  89. var t = aThreads[i] || {};
  90. var bMine = parseInt(t.writable, 10) === 1;
  91. var oBtn = $('<button type="button" class="bx-agents-popup-chat-thread"></button>');
  92. if (bMine)
  93. oBtn.addClass('bx-agents-popup-chat-thread-mine');
  94. oBtn.attr({
  95. 'data-thread-id': t.thread_id || '',
  96. 'data-writable': bMine ? 1 : 0,
  97. 'data-context': parseInt(t.context_pid, 10) || 0,
  98. 'data-status': t.status === 'closed' ? 'closed' : 'opened'
  99. });
  100. oBtn.data('artifacts', Array.isArray(t.artifacts) ? t.artifacts : []);
  101. oBtn.data('messages', Array.isArray(t.messages) ? t.messages : null);
  102. oBtn.append($('<span class="bx-agents-popup-chat-thread-title"></span>').text(t.title || 'Chat'));
  103. var sStatus = t.status === 'closed' ? 'closed' : 'opened';
  104. var oMeta = $('<span class="bx-agents-popup-chat-thread-meta"></span>')
  105. .addClass(sStatus === 'closed' ? 'bx-agents-popup-chat-thread-status-closed' : 'bx-agents-popup-chat-thread-status-opened')
  106. .text(t.meta || ('status: ' + sStatus));
  107. oBtn.append(oMeta);
  108. oItems.append(oBtn);
  109. }
  110. };
  111. BxDolStudioPageAgents.prototype._bindAgentChatSearch = function(oBox) {
  112. var oInput = oBox.find('.bx-agents-popup-chat-list-search-input');
  113. if (!oInput.length)
  114. return;
  115. oInput.val('').off('input.agentChat').on('input.agentChat', function() {
  116. var sQuery = $.trim($(this).val()).toLowerCase();
  117. var iShown = 0;
  118. oBox.find('.bx-agents-popup-chat-thread').each(function() {
  119. var bMatch = !sQuery || $(this).text().toLowerCase().indexOf(sQuery) !== -1;
  120. $(this).toggle(bMatch);
  121. if (bMatch)
  122. iShown++;
  123. });
  124. oBox.find('.bx-agents-popup-chat-list-empty').toggle(!iShown);
  125. });
  126. };
  127. BxDolStudioPageAgents.prototype._ensureAgentChatStyles = function() {
  128. var oStyle = document.getElementById('bx-agents-popup-chat-inline-css');
  129. if (!oStyle) {
  130. oStyle = document.createElement('style');
  131. oStyle.id = 'bx-agents-popup-chat-inline-css';
  132. document.head.appendChild(oStyle);
  133. }
  134. oStyle.textContent =
  135. '#grid-popup-sys_studio_agents_agents-message .bx-popup-width{width:68rem;max-width:calc(100vw - 2rem);}' +
  136. '.bx-agents-popup-chat-wrap{display:flex;gap:0.75rem;min-height:32rem;max-height:min(36rem,calc(100vh - 10rem));}' +
  137. '.bx-agents-popup-chat-list{flex:0 0 15.5rem;width:15.5rem;display:flex;flex-direction:column;min-height:0;border-right:1px solid rgba(0,0,0,.08);padding-right:0.75rem;}' +
  138. '.bx-agents-popup-chat-list-title{font-weight:600;margin-bottom:0.5rem;}' +
  139. '.bx-agents-popup-chat-list-search{margin:0 0 0.5rem;}' +
  140. '.bx-agents-popup-chat-list-search-input{width:100%;box-sizing:border-box;padding:0.35rem 0.5rem;border:1px solid rgba(127,127,127,.35);border-radius:0.375rem;background:transparent;color:inherit;font-size:0.85rem;}' +
  141. '.bx-agents-popup-chat-list-empty{opacity:.6;font-size:0.85rem;padding:0.5rem 0;}' +
  142. '.bx-agents-popup-chat-list-items{overflow-y:auto;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:0.25rem;}' +
  143. '.bx-agents-popup-chat-thread{display:block;width:100%;text-align:left;border:0;background:transparent;padding:0.5rem 0.6rem;border-radius:0.4rem;cursor:pointer;}' +
  144. '.bx-agents-popup-chat-thread:hover,.bx-agents-popup-chat-thread-active{background:rgba(37,99,235,.08);}' +
  145. '.bx-agents-popup-chat-thread-title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}' +
  146. '.bx-agents-popup-chat-thread-meta{display:block;font-size:0.75rem;margin-top:0.15rem;white-space:pre-line;line-height:1.25;}' +
  147. '.bx-agents-popup-chat-thread-status-opened{color:#15803d;}' +
  148. '.bx-agents-popup-chat-thread-status-closed{color:#b45309;}' +
  149. '.bx-agents-popup-chat-thread-dates{display:block;font-size:0.7rem;opacity:.6;margin-top:0.1rem;line-height:1.25;}' +
  150. '.bx-agents-popup-chat-thread-dates span{display:block;}' +
  151. '.bx-agents-popup-chat-artifacts{flex:0 0 auto;margin:0 0 0.5rem;padding:0.5rem 0.65rem;font-size:0.8rem;line-height:1.35;border:1px solid rgba(0,0,0,.12);border-radius:0.4rem;max-height:8rem;overflow-y:auto;background:#fffbe6;}' +
  152. '.bx-agents-popup-chat-artifacts-row{display:flex;gap:0.5rem;min-width:0;}' +
  153. '.bx-agents-popup-chat-artifacts-k{flex:0 0 7rem;font-weight:600;opacity:.7;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}' +
  154. '.bx-agents-popup-chat-artifacts-v{flex:1 1 auto;min-width:0;overflow-wrap:anywhere;}' +
  155. '.bx-agents-popup-chat-artifacts-empty{opacity:.6;}' +
  156. '.bx-agents-popup-chat-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;}' +
  157. '.bx-agents-popup-chat{height:auto;flex:1 1 auto;min-height:16rem;max-height:100%;display:flex;flex-direction:column;}' +
  158. '.bx-agents-popup-chat-note{margin-top:0.5rem;font-size:0.8rem;opacity:.7;}' +
  159. '.bx-ai-chat-message-inner{display:flex;flex-direction:column;gap:0.4rem;}' +
  160. '.bx-ai-chat-image{display:block;max-width:12rem;max-height:12rem;border-radius:0.5rem;object-fit:cover;}' +
  161. '.bx-ai-chat-actions{display:flex;flex-wrap:wrap;gap:0.35rem;margin-top:0.15rem;}' +
  162. '.bx-ai-chat-action{display:inline-flex;align-items:center;padding:0.2rem 0.65rem;border-radius:999px;font-size:0.8rem;line-height:1.3;border:1px solid rgba(127,127,127,.35);background:rgba(127,127,127,.12);color:inherit;text-decoration:none;}' +
  163. '.bx-ai-chat-action-link:hover{opacity:.85;}' +
  164. '.bx-agents-popup-thread{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;height:100%;}' +
  165. '.bx-agents-popup-thread-messages{flex:1;overflow-y:auto;min-height:16rem;}' +
  166. '.bx-agents-popup-thread-empty{opacity:.6;font-size:0.85rem;padding:0.5rem;}';
  167. };
  168. BxDolStudioPageAgents.prototype._openAgentChatThread = function(oBtn) {
  169. var sSelector = this._sAgentChatSelector;
  170. var iAgentId = this._iAgentChatId;
  171. var oBox = this._oAgentChatBox;
  172. if (!oBtn || !oBtn.length || !sSelector)
  173. return;
  174. if (oBox && oBox.length) {
  175. oBox.find('.bx-agents-popup-chat-thread').removeClass('bx-agents-popup-chat-thread-active');
  176. oBtn.addClass('bx-agents-popup-chat-thread-active');
  177. }
  178. var bWritable = parseInt(oBtn.attr('data-writable'), 10) === 1;
  179. var iContext = parseInt(oBtn.attr('data-context'), 10) || 0;
  180. var sThreadId = oBtn.attr('data-thread-id') || '';
  181. var bClosed = oBtn.attr('data-status') === 'closed';
  182. this.destroyAgentChat(true);
  183. this._renderAgentChatArtifacts(oBox, oBtn.data('artifacts') || []);
  184. if (oBox && oBox.length)
  185. oBox.find('.bx-agents-popup-chat-note').toggle(!bWritable || bClosed);
  186. this._loadReadonlyAgentChat(sSelector, iAgentId, sThreadId, oBtn.data('messages'));
  187. };
  188. BxDolStudioPageAgents.prototype._chatQueryFromThreadId = function(sThreadId) {
  189. var s = String(sThreadId || '');
  190. var i = s.lastIndexOf('.');
  191. if (i === -1)
  192. return '';
  193. var sChat = s.slice(i + 1);
  194. return /^[A-Za-z0-9_-]{8,64}$/.test(sChat) ? sChat : '';
  195. };
  196. BxDolStudioPageAgents.prototype._initWritableAgentChat = function(sSelector, iAgentId, iContext, sThreadId) {
  197. if (typeof una === 'undefined' || !una.Chat)
  198. return;
  199. var sRoot = (typeof sUrlRoot !== 'undefined') ? sUrlRoot : '/';
  200. var sEndpoint = sRoot + 'sys-ai-chat/' + encodeURIComponent(iAgentId);
  201. var aQuery = [];
  202. iContext = parseInt(iContext, 10) || 0;
  203. if (iContext > 0)
  204. aQuery.push('context=' + encodeURIComponent(iContext));
  205. var sChat = this._chatQueryFromThreadId(sThreadId);
  206. if (sChat)
  207. aQuery.push('chat=' + encodeURIComponent(sChat));
  208. if (aQuery.length)
  209. sEndpoint += '?' + aQuery.join('&');
  210. this._oAgentChat = una.Chat.init(sSelector, {
  211. agentId: iAgentId,
  212. formatting: true,
  213. contextProfileId: iContext,
  214. endpoint: sEndpoint
  215. });
  216. };
  217. BxDolStudioPageAgents.prototype._loadReadonlyAgentChat = function(sSelector, iAgentId, sThreadId, aCached) {
  218. var $this = this;
  219. var el = typeof sSelector === 'string' ? document.querySelector(sSelector) : sSelector;
  220. if (!el)
  221. return;
  222. this._iAgentChatLoad = (this._iAgentChatLoad || 0) + 1;
  223. var iLoad = this._iAgentChatLoad;
  224. el.innerHTML = '';
  225. if (Array.isArray(aCached)) {
  226. this._renderReadonlyAgentChat(el, aCached);
  227. return;
  228. }
  229. var sUrl = (typeof sUrlRoot !== 'undefined' ? sUrlRoot : '/') + 'grid.php?o=sys_studio_agents_agents&a=get_chat_thread&id=' + encodeURIComponent(iAgentId) + '&thread_id=' + encodeURIComponent(sThreadId) + '&_r=' + Date.now();
  230. if (typeof glGrids !== 'undefined' && this.sObjNameGrid && glGrids[this.sObjNameGrid] && glGrids[this.sObjNameGrid]._sCsrfToken)
  231. sUrl += '&csrf_token=' + encodeURIComponent(glGrids[this.sObjNameGrid]._sCsrfToken);
  232. if (this._oAgentChatXhr && this._oAgentChatXhr.abort)
  233. this._oAgentChatXhr.abort();
  234. this._oAgentChatXhr = $.getJSON(sUrl, function(oData) {
  235. if (iLoad !== $this._iAgentChatLoad)
  236. return;
  237. if (!oData || (oData.code && oData.code != 200)) {
  238. el.innerHTML = '<div class="bx-def-font-small" style="color:#c0392b;">' + $this._escAgentChat((oData && (oData.msg || oData.message)) || 'Error') + '</div>';
  239. return;
  240. }
  241. $this._renderAgentChatArtifacts($this._oAgentChatBox, oData.artifacts || []);
  242. $this._renderReadonlyAgentChat(el, oData.messages || []);
  243. }).fail(function() {
  244. if (iLoad !== $this._iAgentChatLoad)
  245. return;
  246. el.innerHTML = '';
  247. });
  248. };
  249. BxDolStudioPageAgents.prototype._ensureAgentChatArtifactsPanel = function(oBox) {
  250. if (!oBox || !oBox.length)
  251. return $();
  252. var oPanel = oBox.find('.bx-agents-popup-chat-main > .bx-agents-popup-chat-artifacts');
  253. if (oPanel.length)
  254. return oPanel;
  255. oPanel = $('<div class="bx-agents-popup-chat-artifacts"></div>');
  256. var oChat = oBox.find('.bx-agents-popup-chat-main > .bx-agents-popup-chat').first();
  257. if (oChat.length)
  258. oChat.before(oPanel);
  259. else
  260. oBox.find('.bx-agents-popup-chat-main').prepend(oPanel);
  261. return oPanel;
  262. };
  263. BxDolStudioPageAgents.prototype._fillAgentChatArtifactsEl = function(oPanel, aArtifacts) {
  264. if (!oPanel || !oPanel.length)
  265. return;
  266. aArtifacts = Array.isArray(aArtifacts) ? aArtifacts : [];
  267. oPanel.empty();
  268. if (!aArtifacts.length) {
  269. oPanel.hide();
  270. return;
  271. }
  272. for (var i = 0; i < aArtifacts.length; i++) {
  273. var a = aArtifacts[i] || {};
  274. var oRow = $('<div class="bx-agents-popup-chat-artifacts-row"></div>');
  275. oRow.append($('<span class="bx-agents-popup-chat-artifacts-k"></span>').text(a.field_name || ''));
  276. oRow.append($('<span class="bx-agents-popup-chat-artifacts-v"></span>').text(a.field_value || ''));
  277. oPanel.append(oRow);
  278. }
  279. oPanel.show();
  280. };
  281. BxDolStudioPageAgents.prototype._renderAgentChatArtifacts = function(oBox, aArtifacts) {
  282. this._fillAgentChatArtifactsEl(this._ensureAgentChatArtifactsPanel(oBox), aArtifacts);
  283. };
  284. BxDolStudioPageAgents.prototype._renderReadonlyAgentChat = function(el, aMessages) {
  285. if (aMessages && !Array.isArray(aMessages))
  286. aMessages = Object.keys(aMessages).map(function(k) { return aMessages[k]; });
  287. aMessages = Array.isArray(aMessages) ? aMessages : [];
  288. var html = '<div class="bx-agents-popup-thread">' +
  289. '<div class="bx-agents-popup-thread-messages bx-def-border bx-def-round-corners bx-def-padding">';
  290. var n = 0;
  291. for (var i = 0; i < aMessages.length; i++) {
  292. var m = aMessages[i] || {};
  293. var isUser = m.role === 'user';
  294. var aParts = Array.isArray(m.parts) ? m.parts : [];
  295. var body = '';
  296. var text = '';
  297. if (typeof m.content === 'string')
  298. text = m.content;
  299. for (var j = 0; j < aParts.length; j++) {
  300. var p = aParts[j] || {};
  301. if (p.type === 'image' || p.type === 'image_url') {
  302. var src = this._agentChatImageSrc(p);
  303. if (src)
  304. body += '<img class="bx-ai-chat-image" src="' + this._escAgentChat(src) + '" alt="" />';
  305. continue;
  306. }
  307. if ((p.type === 'text' || !p.type) && p.content)
  308. text += (text ? '\n' : '') + p.content;
  309. }
  310. if (text)
  311. body += '<div class="bx-ai-chat-text">' + this._escAgentChat(text).replace(/\n/g, '<br />') + '</div>';
  312. if (!isUser)
  313. body += this._renderAgentChatActions(m.actions || (m.metadata && m.metadata.actions) || []);
  314. if (!body)
  315. continue;
  316. n++;
  317. html += '<div class="bx-ai-chat-message" style="display:flex;justify-content:' + (isUser ? 'flex-end' : 'flex-start') + ';margin:6px 0;">' +
  318. '<div class="bx-ai-chat-message-inner bx-def-padding-sec bx-def-round-corners" style="max-width:85%;background:' + (isUser ? '#2563eb' : 'rgba(127,127,127,.18)') + ';color:' + (isUser ? '#fff' : 'inherit') + ';">' +
  319. body +
  320. '</div></div>';
  321. }
  322. if (!n)
  323. html += '<div class="bx-agents-popup-thread-empty">No messages</div>';
  324. html += '</div></div>';
  325. el.innerHTML = html;
  326. var list = el.querySelector('.bx-agents-popup-thread-messages');
  327. if (list)
  328. list.scrollTop = list.scrollHeight;
  329. };
  330. BxDolStudioPageAgents.prototype._agentChatImageSrc = function(p) {
  331. if (!p)
  332. return '';
  333. if (p.url)
  334. return this._agentChatSafeUrl(p.url);
  335. var src = p.source || {};
  336. var kind = String(src.type || '').toLowerCase();
  337. if (kind === 'url')
  338. return this._agentChatSafeUrl(src.value || src.url || '');
  339. if (kind === 'data' && src.value) {
  340. var mime = String(src.mimeType || src.mediaType || 'image/jpeg').toLowerCase();
  341. if (!/^image\/(jpeg|png|gif|webp)$/.test(mime))
  342. mime = 'image/jpeg';
  343. var v = String(src.value).replace(/\s+/g, '');
  344. if (/^data:image\/(jpeg|png|gif|webp);base64,/i.test(v))
  345. return v;
  346. if (!/^[A-Za-z0-9+/=]+$/.test(v))
  347. return '';
  348. return 'data:' + mime + ';base64,' + v;
  349. }
  350. return this._agentChatSafeUrl(p.content || '');
  351. };
  352. BxDolStudioPageAgents.prototype._agentChatSafeUrl = function(s) {
  353. s = String(s == null ? '' : s);
  354. if (/^https?:\/\//i.test(s))
  355. return s;
  356. if (s.charAt(0) === '/' && s.charAt(1) !== '/')
  357. return s;
  358. return '';
  359. };
  360. BxDolStudioPageAgents.prototype._renderAgentChatActions = function(aActions) {
  361. if (!aActions || !aActions.length)
  362. return '';
  363. var html = '<div class="bx-ai-chat-actions">';
  364. var n = 0;
  365. for (var i = 0; i < aActions.length; i++) {
  366. var a = aActions[i] || {};
  367. var label = this._escAgentChat(a.label || '');
  368. if (!label)
  369. continue;
  370. var type = String(a.type || '').toLowerCase();
  371. if (type === 'link') {
  372. var url = this._agentChatSafeUrl(a.url || '');
  373. if (!url)
  374. continue;
  375. html += '<a class="bx-ai-chat-action bx-ai-chat-action-link" href="' + this._escAgentChat(url) + '" target="_blank" rel="noopener noreferrer">' + label + '</a>';
  376. } else {
  377. html += '<span class="bx-ai-chat-action bx-ai-chat-action-reply">' + label + '</span>';
  378. }
  379. n++;
  380. }
  381. return n ? html + '</div>' : '';
  382. };
  383. BxDolStudioPageAgents.prototype._escAgentChat = function(s) {
  384. return String(s == null ? '' : s)
  385. .replace(/&/g, '&amp;')
  386. .replace(/</g, '&lt;')
  387. .replace(/>/g, '&gt;')
  388. .replace(/"/g, '&quot;');
  389. };
  390. BxDolStudioPageAgents.prototype.destroyAgentChat = function(bKeepBox) {
  391. this._iAgentChatLoad = (this._iAgentChatLoad || 0) + 1;
  392. if (this._oAgentChatXhr && this._oAgentChatXhr.abort) {
  393. try { this._oAgentChatXhr.abort(); } catch (e) {}
  394. }
  395. this._oAgentChatXhr = null;
  396. if (this._oAgentChat) {
  397. try {
  398. this._oAgentChat.destroy();
  399. } catch (e) {}
  400. this._oAgentChat = null;
  401. }
  402. if (this._sAgentChatSelector) {
  403. var el = document.querySelector(this._sAgentChatSelector);
  404. if (el)
  405. el.innerHTML = '';
  406. }
  407. if (!bKeepBox) {
  408. if (this._oAgentChatBox && this._oAgentChatBox.length)
  409. this._oAgentChatBox.off('click.agentChat');
  410. this._oAgentChatBox = null;
  411. this._sAgentChatSelector = '';
  412. this._iAgentChatId = 0;
  413. }
  414. };
  415. BxDolStudioPageAgents.prototype.agentActions = function(oSource) {
  416. var iId = $(oSource).parents('.bx-agt-agent:first').attr('data-id');
  417. bx_menu_popup_inline('#bx-agt-agent-actions-' + iId, oSource);
  418. };
  419. BxDolStudioPageAgents.prototype.agentAction = function(sAction, iId, iConfirm, iResetPaginate) {
  420. $('.bx-popup-applied:visible').dolPopupHide();
  421. if (typeof(glGrids) == 'undefined' || !this.sObjNameGrid || !glGrids[this.sObjNameGrid])
  422. return;
  423. glGrids[this.sObjNameGrid].actionSingle(sAction, iId, {
  424. confirm: iConfirm,
  425. reset_paginate: iResetPaginate
  426. });
  427. };
  428. BxDolStudioPageAgents.prototype.agentAdd = function() {
  429. if (typeof(glGrids) == 'undefined' || !this.sObjNameGrid || !glGrids[this.sObjNameGrid])
  430. return;
  431. glGrids[this.sObjNameGrid].action('add', {}, '', false, 0);
  432. };
  433. BxDolStudioPageAgents.prototype.agentActivate = function(oSource) {
  434. var oDate = new Date();
  435. var oAgent = $(oSource).parents('.bx-agt-agent:first');
  436. jQuery.get(
  437. this.sActionUrl,
  438. {
  439. agt_action: 'agent-activate',
  440. agt_value: parseInt(oAgent.attr('data-id')),
  441. _t: oDate.getTime()
  442. },
  443. function(oData) {
  444. processJsonData(oData);
  445. },
  446. 'json'
  447. );
  448. };
  449. BxDolStudioPageAgents.prototype.agentCheckName = function(oSource, sTitleId, sNameId, iId) {
  450. var oDate = new Date();
  451. var oForm = jQuery(oSource).parents('.bx-form-advanced:first');
  452. var oName = oForm.find("[name='" + sNameId + "']");
  453. var sName = oName.val();
  454. var bName = sName.length != 0;
  455. var oTitle = oForm.find("[name='" + sTitleId + "']");
  456. var sTitle = oTitle.val();
  457. var bTitle = sTitle.length != 0;
  458. if(!bName && !bTitle)
  459. return;
  460. var sTitleCheck = '';
  461. if(bName)
  462. sTitleCheck = sName;
  463. else if(bTitle) {
  464. sTitleCheck = sTitle;
  465. sTitle = sTitle.replace(/[^A-Za-z0-9_]/g, '-');
  466. sTitle = sTitle.replace(/[-]{2,}/g, '-');
  467. oName.val(sTitle.toLowerCase());
  468. }
  469. jQuery.get(
  470. this.sActionUrl,
  471. {
  472. agt_action: 'agent-check-name',
  473. agt_value: sTitleCheck,
  474. id: iId && parseInt(iId) > 0 ? iId : 0,
  475. _t: oDate.getTime()
  476. },
  477. function(oData) {
  478. if(!oData || oData.name == undefined)
  479. return;
  480. oName.val(oData.name);
  481. },
  482. 'json'
  483. );
  484. };
  485. BxDolStudioPageAgents.prototype.toolAdd = function(oButton, sName) {
  486. var oButton = $(oButton);
  487. var oSubentry = oButton.parents('#bx-form-element-' + sName).find('.bx-form-input-tools:first').clone();
  488. oSubentry.find("select").val('');
  489. oSubentry.find("input[type = 'hidden']").remove();
  490. oButton.parents('.bx-form-input-tools-add:first').before(oSubentry);
  491. };
  492. BxDolStudioPageAgents.prototype.toolDelete = function(oButton) {
  493. $(oButton).parents('.bx-form-input-tools:first').remove();
  494. };
  495. /** @} */