/* * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ /** * MacrosAiDialog.js * * Created on 23.04.2025 * */ define([], function () { 'use strict'; Common.Views.MacrosAiDialog = Common.UI.Window.extend(_.extend({ initialize : function(options) { var _options = {}; var windowSize = { width: { init: 400, min: 400, max: 800 }, height: { init: 200, min: 200, max: 400 } }; var windowClasses = 'modal-dlg invisible-borders'; if(options.inputType == 'codeEditor') { windowSize = { width: { init: 600, min: 600, max: 1000 }, height: { init: 400, min: 400, max: 600 } } windowClasses += ' padding-none'; } _.extend(_options, { id: 'macros-ai-dialog', title: options.title, width: windowSize.width.init, height: windowSize.height.init, minwidth: windowSize.width.min, minheight: windowSize.height.min, maxwidth: windowSize.width.max, maxheight: windowSize.height.max, resizable: true, cls: windowClasses, buttons: [ {caption: this.textCreate, value: 'ok', primary: true}, 'cancel' ] }, options || {}); this.api = options.api; this.instruction = options.instruction; this.inputType = options.inputType || 'textarea'; //'textarea' or 'codeEditor' this._state = { codeEditorValue: '' }; if(this.inputType == 'textarea') { this.template = [ '
', '
', '
' ].join(''); } else { this.template = [ '
', '
' ].join(''); } _options.tpl = _.template(this.template)(_options); Common.UI.Window.prototype.initialize.call(this, _options); }, render: function() { Common.UI.Window.prototype.render.call(this); var $window = this.getChild(); if(this.inputType == 'textarea') { this.textareaPrompt = new Common.UI.TextareaField({ el : $window.find('#macros-ai-dialog-textarea'), placeHolder : this.textAreaPlaceholder }); } else { this.createCodeEditor(); } $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); }, createCodeEditor: function() { var me = this; this.codeEditor = new Common.UI.MonacoEditor({ parentEl: '#macros-ai-dialog-code-editor', language: 'vba' }); this.codeEditor.on('ready', function() { me.codeEditor.updateTheme(); me.codeEditor.setValue('', {row: 0, column: 0}); }); this.codeEditor.on('change', function(value, pos) { me._state.codeEditorValue = value; }); }, getFocusedComponents: function() { return [].concat(this.getFooterButtons()); }, show: function() { Common.UI.Window.prototype.show.apply(this, arguments); if(this.textareaPrompt) { var me = this; _.delay(function(){ me.textareaPrompt.focus(); },50); } }, onPrimary: function(event) { this._handleInput('ok'); return false; }, onBtnClick: function(event) { this._handleInput(event.currentTarget.attributes['result'].value); }, close: function(suppressevent) { if(this.codeEditor) { this.codeEditor.destroyEditor(); } Common.UI.Window.prototype.close.call(this, arguments); }, _handleInput: function(state) { if (this.options.handler) { if(state == 'ok') { var me = this; var content = this.inputType == 'textarea' ? this.textareaPrompt.getValue() : this._state.codeEditorValue; me.api.AI({ type : "text", data : [{role: "system", content: this.instruction}, {role:"user", content: content}] }, function(data){ if (!data.error) { if(!data || !data.text) { return me._handleInput("cancel"); } function trimResult(data, posStart, isSpaces) { let pos = posStart || 0; if (-1 != pos) { let trimC = ["\"", "'", "\n", "\r"]; if (true === isSpaces) trimC.push(" "); while (pos < data.length && trimC.includes(data[pos])) pos++; let posEnd = data.length - 1; while (posEnd > 0 && trimC.includes(data[posEnd])) posEnd--; if (posEnd > pos) return data.substring(pos, posEnd + 1); } return data; } var cleanResult = data.text.replace(/```javascript|```/g, ""); cleanResult = trimResult(cleanResult, 0, true); me.close(); me.options.handler.call(me, state, cleanResult); } else { if ("no-engine" === data.type) return me._handleInput("cancel"); console.log(data.error); } }); } else { this.close(); this.options.handler.call(this, state); } } }, textCreate : 'Create', textAreaPlaceholder : 'Input a prompt for the query', }, Common.Views.MacrosAiDialog || {})); });