diff --git a/sdkjs-plugins/content/ai/resources/styles/customAssistant.css b/sdkjs-plugins/content/ai/resources/styles/customAssistant.css
index 4b3ccf77..b3980001 100644
--- a/sdkjs-plugins/content/ai/resources/styles/customAssistant.css
+++ b/sdkjs-plugins/content/ai/resources/styles/customAssistant.css
@@ -43,6 +43,21 @@ label {
text-align: center;
}
+#warning_text {
+ display: flex;
+ flex-direction: row;
+ padding-top: 8px;
+ gap: 12px;
+ line-height: 16px;
+}
+ #warning_text svg {
+ margin-top: 7px;
+ }
+ #warning_text p {
+ width: calc(100% - 76px);
+ }
+
+
#custom_assistant {
height: auto;
padding: 14px 0 8px 0;
diff --git a/sdkjs-plugins/content/ai/scripts/code.js b/sdkjs-plugins/content/ai/scripts/code.js
index 3dcfb70c..710480b5 100644
--- a/sdkjs-plugins/content/ai/scripts/code.js
+++ b/sdkjs-plugins/content/ai/scripts/code.js
@@ -30,6 +30,8 @@
*
*/
+///
+
let settingsWindow = null;
let aiModelsListWindow = null;
let aiModelEditWindow = null;
@@ -961,7 +963,7 @@ async function onCheckGrammarSpelling(isCurrent)
function customAssistantWindowShow(assistantId, buttonAssistant)
{
if (window.customAssistantWindow) {
- closeCustomAssistantWindow();
+ customAssistantWindowClose();
}
const actionButtonText = assistantId ? 'Save' : 'Create';
const description = assistantId ? 'Edit' : 'Create a new assistant';
@@ -1025,7 +1027,7 @@ function customAssistantWindowShow(assistantId, buttonAssistant)
Asc.Buttons.updateToolbarMenu(window.buttonMainToolbar.id, window.buttonMainToolbar.name, [buttonAssistant]);
customAssistantManager.createAssistant(element);
}
- closeCustomAssistantWindow();
+ customAssistantWindowClose();
} else {
await window.pluginsButtonsCallback(id, windowId, ...args);
}
@@ -1034,7 +1036,7 @@ function customAssistantWindowShow(assistantId, buttonAssistant)
window.customAssistantWindow = customAssistantWindow;
}
-function closeCustomAssistantWindow() {
+function customAssistantWindowClose() {
if (window.customAssistantWindow) {
window.customAssistantWindow.close();
window.customAssistantWindow = null;
@@ -1050,7 +1052,7 @@ function closeCustomAssistantWindow() {
*/
function customAssistantWindowDeleteConfirm(assistantId, buttonAssistant) {
if (window.customAssistantWindow) {
- closeCustomAssistantWindow();
+ customAssistantWindowClose();
}
const savedAssistants = JSON.parse(
@@ -1101,7 +1103,50 @@ if (window.customAssistantWindow) {
}
}
}
- closeCustomAssistantWindow();
+ customAssistantWindowClose();
+ } else {
+ await window.pluginsButtonsCallback(id, windowId, ...args);
+ }
+ }
+
+ window.customAssistantWindow = customAssistantWindow;
+}
+/**
+ * @param {localStorageCustomAssistantItem} assistantData
+ * @param {string} warningText
+ */
+function customAssistantWarning(assistantData, warningText) {
+if (window.customAssistantWindow) {
+ customAssistantWindowClose();
+ }
+
+ let variation = {
+ url : "customAssistant.html",
+ description : window.Asc.plugin.tr('Warning!'),
+ isVisual : true,
+ buttons : [
+ { text: window.Asc.plugin.tr('Ok'), primary: true },
+ ],
+ isModal : true,
+ isCanDocked: false,
+ type: "window",
+ EditorsSupport : ["word"],
+ size : [ 350, 76 ]
+ };
+
+ const customAssistantWindow = new window.Asc.PluginWindow();
+ customAssistantWindow.attachEvent("onWindowReady", function() {
+ Asc.Editor.callMethod("ResizeWindow", [customAssistantWindow.id, [350, 76], [350, 76], [0, 0]]);
+ customAssistantWindow.command('onWarningAssistant', warningText);
+
+ });
+
+ customAssistantWindow.show(variation);
+
+ window.pluginsButtonsCallback = window.Asc.plugin.button;
+ window.Asc.plugin.button = async function(id, windowId, ...args) {
+ if (customAssistantWindow && windowId === customAssistantWindow.id) {
+ customAssistantWindowClose();
} else {
await window.pluginsButtonsCallback(id, windowId, ...args);
}
diff --git a/sdkjs-plugins/content/ai/scripts/customAssistant.js b/sdkjs-plugins/content/ai/scripts/customAssistant.js
index dd3fda31..f7b9a31e 100644
--- a/sdkjs-plugins/content/ai/scripts/customAssistant.js
+++ b/sdkjs-plugins/content/ai/scripts/customAssistant.js
@@ -110,6 +110,20 @@
}
);
+ window.Asc.plugin.attachEvent(
+ "onWarningAssistant",
+ (/** @type {string} */ warningText) => {
+ const image = '';
+ const text = '
' +
+ image + '
' + window.Asc.plugin.tr(warningText) + '
'
+ mainContainer.innerHTML = image + text;
+ }
+ );
+
function onThemeChanged(theme) {
window.Asc.plugin.onThemeChangedBase(theme);
updateBodyThemeClasses(theme.type, theme.name);
diff --git a/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/custom-annotator.js b/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/custom-annotator.js
index 50e376e3..dbf978c2 100644
--- a/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/custom-annotator.js
+++ b/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/custom-annotator.js
@@ -51,6 +51,7 @@ Object.assign(CustomAnnotator.prototype, {
* @param {string} paraId
* @param {string} recalcId
* @param {string} text
+ * @returns {Promise}
*/
annotateParagraph: async function (paraId, recalcId, text) {
this.paragraphs[paraId] = {};
@@ -60,7 +61,10 @@ Object.assign(CustomAnnotator.prototype, {
const argPrompt = this._createPrompt(text);
let response = await this.chatRequest(argPrompt);
- if (!response) return false;
+
+ if (!response || response === '[]') {
+ return false;
+ }
try {
const ranges = this._convertToRanges(paraId, text, JSON.parse(response));
@@ -73,6 +77,8 @@ Object.assign(CustomAnnotator.prototype, {
};
await Asc.Editor.callMethod("AnnotateParagraph", [obj]);
} catch (e) {}
+
+ return true;
},
/**
* @param {string} paraId
@@ -103,18 +109,19 @@ Object.assign(CustomAnnotator.prototype, {
if (annot["original"] !== text.substring(start, start + len)) {
let annotRange = this.getAnnotationRangeObj(paraId, rangeId);
- Asc.Editor.callMethod("RemoveAnnotationRange", [annotRange]);
+ return Asc.Editor.callMethod("RemoveAnnotationRange", [annotRange]);
}
},
/**
* @param {string[]} paraIds
+ * @returns {Promise}
*/
checkParagraphs: async function (paraIds) {
if (this._skipNextChangeParagraph) {
this._skipNextChangeParagraph = false;
- return;
+ return paraIds.map(() => false);
}
- TextAnnotator.prototype.checkParagraphs.call(this, paraIds);
+ return await TextAnnotator.prototype.checkParagraphs.call(this, paraIds);
},
onAccept: async function (paraId, rangeId) {
this._skipNextChangeParagraph = true;
diff --git a/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/manager.js b/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/manager.js
index 460338f5..35390d62 100644
--- a/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/manager.js
+++ b/sdkjs-plugins/content/ai/scripts/text-annotations/custom-annotations/manager.js
@@ -140,7 +140,7 @@ class CustomAssistantManager {
* @param {string} assistantId
* @param {string[]} paraIds
*/
- run(assistantId, paraIds) {
+ async run(assistantId, paraIds) {
const assistant = this._customAssistants.get(assistantId);
if (!assistant) {
console.error("Custom assistant not found: " + assistantId);
@@ -148,17 +148,32 @@ class CustomAssistantManager {
}
if (!this._isCustomAssistantInit.get(assistantId)) {
+ /** @type {Promise[]} */
+ const promises = [];
this._paragraphsStack.forEach((value, paraId) => {
- assistant.onChangeParagraph(
+ const promise = assistant.onChangeParagraph(
paraId,
value.recalcId,
value.text,
value.annotations,
);
+ promises.push(promise);
});
+ await Promise.all(promises);
+ }
+
+ /** @type {boolean[]} */
+ const isParagraphsChecked = await assistant.checkParagraphs(paraIds);
+
+ if (
+ isParagraphsChecked &&
+ isParagraphsChecked.length &&
+ isParagraphsChecked.every(isDone => !isDone)
+ ) {
+ const warningMessage = "Not able to perform this action. Please use prompts related to text analysis, editing, or formatting.";
+ customAssistantWarning(assistant.assistantData, warningMessage);
}
- assistant.checkParagraphs(paraIds);
this._isCustomAssistantInit.set(assistantId, true);
}
diff --git a/sdkjs-plugins/content/ai/scripts/text-annotations/text-annotator.js b/sdkjs-plugins/content/ai/scripts/text-annotations/text-annotator.js
index 3e89196c..378e8fad 100644
--- a/sdkjs-plugins/content/ai/scripts/text-annotations/text-annotator.js
+++ b/sdkjs-plugins/content/ai/scripts/text-annotations/text-annotator.js
@@ -50,19 +50,21 @@ function TextAnnotator(annotatorPopup)
* @param {string} recalcId
* @param {string} text
* @param {string[]} ranges
+ * @returns {Promise}
*/
TextAnnotator.prototype.onChangeParagraph = async function(paraId, recalcId, text, ranges)
{
- this._handleNewRanges(ranges, paraId, text);
+ await this._handleNewRanges(ranges, paraId, text);
this.waitParagraphs[paraId] = {
recalcId : recalcId,
text : text
};
- this._checkParagraph(paraId);
+ return this._checkParagraph(paraId);
};
/**
* @param {string[]} paraIds
+ * @returns {Promise}
*/
TextAnnotator.prototype.checkParagraphs = async function(paraIds)
{
@@ -73,12 +75,19 @@ TextAnnotator.prototype.checkParagraphs = async function(paraIds)
_t.paraToCheck.add(paraId);
});
- this.paraToCheck.forEach(paraId => this._checkParagraph(paraId));
+ /** @type {Promise[]} */
+ const promises = [];
+ this.paraToCheck.forEach(paraId => {promises.push(this._checkParagraph(paraId))});
+ return Promise.all(promises);
};
+/**
+ * @param {string} paraId
+ * @returns {Promise}
+ */
TextAnnotator.prototype._checkParagraph = async function(paraId)
{
if (!this.paraToCheck.has(paraId) || !this.waitParagraphs[paraId])
- return;
+ return false;
let recalcId = this.waitParagraphs[paraId].recalcId;
let text = this.waitParagraphs[paraId].text;
@@ -88,12 +97,14 @@ TextAnnotator.prototype._checkParagraph = async function(paraId)
range["rangeId"] = undefined;
range["all"] = true;
await Asc.Editor.callMethod("RemoveAnnotationRange", [range]);
- await this.annotateParagraph(paraId, recalcId, text);
+ const isAnnotate = await this.annotateParagraph(paraId, recalcId, text);
delete this.waitParagraphs[paraId];
this.paraToCheck.delete(paraId);
this.checked.add(paraId);
+
+ return isAnnotate;
};
TextAnnotator.prototype.annotateParagraph = async function(paraId, recalcId, text)
{
@@ -174,17 +185,18 @@ TextAnnotator.prototype.resetCurrentRange = function()
this.paraId = null;
this.rangeId = null;
};
-TextAnnotator.prototype._handleNewRanges = function(ranges, paraId, text)
+TextAnnotator.prototype._handleNewRanges = async function(ranges, paraId, text)
{
if (!ranges || !Array.isArray(ranges))
return;
-
- ranges.forEach(range => this._handleNewRangePositions(range, paraId, text));
- // ↓↓↓ TODO: the cycle seems to make no sense ↓↓↓
+ const promises = [];
+
for (let i = 0; i < ranges.length; ++i)
{
- this._handleNewRangePositions(ranges[i]);
+ promises[i] = this._handleNewRangePositions(ranges[i], paraId, text);
}
+
+ return Promise.all(promises);
};
TextAnnotator.prototype._handleNewRangePositions = function(range, paraId, text)
{