@ibiz-template/vue3-components 0.7.41-alpha.38 → 0.7.41-alpha.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ibiz-markdown-editor-D4Og0fLv.js +1 -0
- package/dist/{index-Dp8ExwuL.js → index-BewO9StC.js} +1 -1
- package/dist/{index-C28lnh2e.js → index-ClxO69TM.js} +1 -1
- package/dist/index-DHKZJQyN.js +11 -0
- package/dist/index.min.css +1 -1
- package/dist/index.system.min.js +1 -1
- package/dist/{wang-editor-DDVqSnRX.js → wang-editor-BYeoazrn.js} +1 -1
- package/dist/{xlsx-util-BMANxyk-.js → xlsx-util-DpgMzatq.js} +1 -1
- package/es/control/form/form-detail/form-item/form-item-container/form-item-container.mjs +42 -8
- package/es/editor/code/code-editor.controller.mjs +72 -25
- package/es/editor/code/monaco-editor/monaco-editor.css +1 -1
- package/es/editor/code/monaco-editor/monaco-editor.mjs +20 -8
- package/es/editor/html/html-editor.controller.mjs +49 -4
- package/es/editor/html/wang-editor/wang-editor.mjs +7 -1
- package/es/editor/markdown/ibiz-markdown-editor/custom-menu.mjs +5 -7
- package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
- package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.mjs +42 -4
- package/es/editor/markdown/markdown-editor.controller.mjs +111 -6
- package/es/locale/en/index.mjs +5 -2
- package/es/locale/zh-CN/index.mjs +5 -2
- package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -1
- package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.mjs +76 -21
- package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.mjs +48 -33
- package/lib/control/form/form-detail/form-item/form-item-container/form-item-container.cjs +42 -8
- package/lib/editor/code/code-editor.controller.cjs +72 -25
- package/lib/editor/code/monaco-editor/monaco-editor.cjs +20 -8
- package/lib/editor/code/monaco-editor/monaco-editor.css +1 -1
- package/lib/editor/html/html-editor.controller.cjs +49 -4
- package/lib/editor/html/wang-editor/wang-editor.cjs +7 -1
- package/lib/editor/markdown/ibiz-markdown-editor/custom-menu.cjs +5 -7
- package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.cjs +42 -4
- package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
- package/lib/editor/markdown/markdown-editor.controller.cjs +111 -6
- package/lib/locale/en/index.cjs +5 -2
- package/lib/locale/zh-CN/index.cjs +5 -2
- package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.cjs +48 -33
- package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -1
- package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.cjs +76 -21
- package/package.json +4 -4
- package/dist/ibiz-markdown-editor-qRaayafj.js +0 -1
- package/dist/index-BiYphJ2f.js +0 -11
|
@@ -89,6 +89,20 @@ class MarkDownEditorController extends EditorController {
|
|
|
89
89
|
* @memberof MarkDownEditorController
|
|
90
90
|
*/
|
|
91
91
|
__publicField(this, "selectionAreaPosition", null);
|
|
92
|
+
/**
|
|
93
|
+
* 选区方向 true表示正向,从左到右;false表示反向,从右到左
|
|
94
|
+
*
|
|
95
|
+
* @type {boolean}
|
|
96
|
+
* @memberof MarkDownEditorController
|
|
97
|
+
*/
|
|
98
|
+
__publicField(this, "selectionDirection", true);
|
|
99
|
+
/**
|
|
100
|
+
* 当前编辑器使用主题
|
|
101
|
+
*
|
|
102
|
+
* @type {string}
|
|
103
|
+
* @memberof MarkDownEditorController
|
|
104
|
+
*/
|
|
105
|
+
__publicField(this, "currentEditorTheme", "light");
|
|
92
106
|
}
|
|
93
107
|
async onInit() {
|
|
94
108
|
await super.onInit();
|
|
@@ -174,6 +188,33 @@ class MarkDownEditorController extends EditorController {
|
|
|
174
188
|
setCursorPos(start, end) {
|
|
175
189
|
this.selectionAreaPosition = { start, end };
|
|
176
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* 设置当前编辑器的主题
|
|
193
|
+
*
|
|
194
|
+
* @param {string} theme
|
|
195
|
+
* @memberof MarkDownEditorController
|
|
196
|
+
*/
|
|
197
|
+
setCurrentEditorTheme(theme) {
|
|
198
|
+
this.currentEditorTheme = theme;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* 设置当前选区方向
|
|
202
|
+
*
|
|
203
|
+
* @param {boolean} direction
|
|
204
|
+
* @memberof MarkDownEditorController
|
|
205
|
+
*/
|
|
206
|
+
setSelectionDirection(direction) {
|
|
207
|
+
this.selectionDirection = direction;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* 获取当前主题
|
|
211
|
+
*
|
|
212
|
+
* @return {*} {('light' | 'dark')}
|
|
213
|
+
* @memberof MarkDownEditorController
|
|
214
|
+
*/
|
|
215
|
+
getCurrentTheme() {
|
|
216
|
+
return this.currentEditorTheme === "dark" ? "dark" : "light";
|
|
217
|
+
}
|
|
177
218
|
/**
|
|
178
219
|
* 获取选中文本
|
|
179
220
|
*
|
|
@@ -184,6 +225,30 @@ class MarkDownEditorController extends EditorController {
|
|
|
184
225
|
var _a;
|
|
185
226
|
return (_a = this.mdeditor) == null ? void 0 : _a.editor.editor.getSelection();
|
|
186
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* 获取内联AI编辑器主题
|
|
230
|
+
*
|
|
231
|
+
* @return {*} {('light' | 'dark')}
|
|
232
|
+
* @memberof MarkDownEditorController
|
|
233
|
+
*/
|
|
234
|
+
getInLineAiEditorTheme() {
|
|
235
|
+
return this.getCurrentTheme();
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* 判断选区方向
|
|
239
|
+
*
|
|
240
|
+
* @param {IData} posA
|
|
241
|
+
* @param {IData} posB
|
|
242
|
+
* @return {*} {boolean}
|
|
243
|
+
* @memberof MarkDownEditorController
|
|
244
|
+
*/
|
|
245
|
+
isPositionBefore(posA, posB) {
|
|
246
|
+
if (posA.line < posB.line)
|
|
247
|
+
return true;
|
|
248
|
+
if (posA.line > posB.line)
|
|
249
|
+
return false;
|
|
250
|
+
return posA.ch < posB.ch;
|
|
251
|
+
}
|
|
187
252
|
/**
|
|
188
253
|
* 插入文本
|
|
189
254
|
*
|
|
@@ -191,8 +256,32 @@ class MarkDownEditorController extends EditorController {
|
|
|
191
256
|
* @memberof MarkDownEditorController
|
|
192
257
|
*/
|
|
193
258
|
insertText(text) {
|
|
194
|
-
var _a;
|
|
195
|
-
(
|
|
259
|
+
var _a, _b, _c;
|
|
260
|
+
if (this.selectionAreaPosition) {
|
|
261
|
+
const { start, end } = this.selectionAreaPosition;
|
|
262
|
+
const contentToInsert = "\n".concat(text, "\n");
|
|
263
|
+
const hasSelection = !(start.line === end.line && start.ch === end.ch);
|
|
264
|
+
if (!hasSelection) {
|
|
265
|
+
(_a = this.mdeditor) == null ? void 0 : _a.editor.editor.replaceSelection(contentToInsert);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
let insetPos;
|
|
269
|
+
if (this.selectionDirection) {
|
|
270
|
+
insetPos = end;
|
|
271
|
+
} else {
|
|
272
|
+
insetPos = start;
|
|
273
|
+
}
|
|
274
|
+
(_b = this.mdeditor) == null ? void 0 : _b.editor.editor.setCursor(insetPos);
|
|
275
|
+
(_c = this.mdeditor) == null ? void 0 : _c.editor.editor.replaceSelection(contentToInsert);
|
|
276
|
+
if (this.selectionDirection === false) {
|
|
277
|
+
const index = (contentToInsert.match(/\n/g) || []).length;
|
|
278
|
+
this.selectionAreaPosition.start.line += index;
|
|
279
|
+
this.selectionAreaPosition.end.line += index;
|
|
280
|
+
this.selectionAreaPosition.end.ch -= this.selectionAreaPosition.start.ch;
|
|
281
|
+
this.selectionAreaPosition.start.ch = 0;
|
|
282
|
+
}
|
|
283
|
+
this.restoreSelection();
|
|
284
|
+
}
|
|
196
285
|
}
|
|
197
286
|
/**
|
|
198
287
|
* 替换选中文本
|
|
@@ -223,14 +312,30 @@ class MarkDownEditorController extends EditorController {
|
|
|
223
312
|
* @memberof MarkDownEditorController
|
|
224
313
|
*/
|
|
225
314
|
getInLineAiChatOptions() {
|
|
226
|
-
var _a;
|
|
315
|
+
var _a, _b, _c;
|
|
227
316
|
const editorRect = (_a = this.mdeditor) == null ? void 0 : _a.wrapperDom.getBoundingClientRect();
|
|
317
|
+
const bubbleRect = (_b = this.mdeditor) == null ? void 0 : _b.bubble.bubbleDom.getBoundingClientRect();
|
|
228
318
|
return {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
319
|
+
// 编辑器的左侧距离 + 10px
|
|
320
|
+
left: editorRect.left + 10,
|
|
321
|
+
// 浮动工具栏的顶部距离位置
|
|
322
|
+
top: bubbleRect.top,
|
|
323
|
+
// 编辑器的宽度 - 右侧工具栏的宽度(38px) - 左侧边距(10px)- 右侧边距(10px)
|
|
324
|
+
width: editorRect.width - 58,
|
|
325
|
+
editorElement: (_c = this.mdeditor) == null ? void 0 : _c.wrapperDom,
|
|
326
|
+
editorTheme: this.getCurrentTheme()
|
|
232
327
|
};
|
|
233
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* 返回内联AI编辑器元素
|
|
331
|
+
*
|
|
332
|
+
* @return {*} {Element}
|
|
333
|
+
* @memberof MarkDownEditorController
|
|
334
|
+
*/
|
|
335
|
+
getInLineAiEditorElement() {
|
|
336
|
+
var _a;
|
|
337
|
+
return (_a = this.mdeditor) == null ? void 0 : _a.wrapperDom;
|
|
338
|
+
}
|
|
234
339
|
/**
|
|
235
340
|
* 执行内联AIUI操作
|
|
236
341
|
*
|
package/es/locale/en/index.mjs
CHANGED
|
@@ -625,7 +625,8 @@ var index = {
|
|
|
625
625
|
noEditorArea: "Editor content area not found",
|
|
626
626
|
noSelStart: "No start position of current selection",
|
|
627
627
|
noEditorRect: "No editor DOM node position info",
|
|
628
|
-
noSelCoords: "No scroll coordinates of selection"
|
|
628
|
+
noSelCoords: "No scroll coordinates of selection",
|
|
629
|
+
editorNotInit: "Editor not initialized"
|
|
629
630
|
},
|
|
630
631
|
dateRange: {
|
|
631
632
|
rangeSeparator: "To"
|
|
@@ -842,7 +843,9 @@ var index = {
|
|
|
842
843
|
replaceText: "Replace Text",
|
|
843
844
|
copyText: "Copy Text",
|
|
844
845
|
info: "The content is generated by AI, please carefully discern.",
|
|
845
|
-
stopEdit: "Terminate editing"
|
|
846
|
+
stopEdit: "Terminate editing",
|
|
847
|
+
warningTitle: "Confirm termination",
|
|
848
|
+
warningDesc: "Are you sure to terminate the creation?"
|
|
846
849
|
}
|
|
847
850
|
},
|
|
848
851
|
// runTime
|
|
@@ -621,7 +621,8 @@ var index = {
|
|
|
621
621
|
noEditorArea: "\u672A\u627E\u5230\u7F16\u8F91\u5668\u5185\u5BB9\u533A\u57DF",
|
|
622
622
|
noSelStart: "\u672A\u83B7\u53D6\u5230\u5F53\u524D\u9009\u4E2D\u533A\u57DF\u7684\u8D77\u59CB\u4F4D\u7F6E",
|
|
623
623
|
noEditorRect: "\u672A\u83B7\u53D6\u5230\u7F16\u8F91\u5668DOM\u8282\u70B9\u7684\u4F4D\u7F6E\u4FE1\u606F",
|
|
624
|
-
noSelCoords: "\u672A\u8BA1\u7B97\u51FA\u9009\u4E2D\u4F4D\u7F6E\u7684\u6EDA\u52A8\u53EF\u89C6\u5750\u6807"
|
|
624
|
+
noSelCoords: "\u672A\u8BA1\u7B97\u51FA\u9009\u4E2D\u4F4D\u7F6E\u7684\u6EDA\u52A8\u53EF\u89C6\u5750\u6807",
|
|
625
|
+
editorNotInit: "\u7F16\u8F91\u5668\u672A\u521D\u59CB\u5316"
|
|
625
626
|
},
|
|
626
627
|
dateRange: {
|
|
627
628
|
rangeSeparator: "\u81F3"
|
|
@@ -838,7 +839,9 @@ var index = {
|
|
|
838
839
|
replaceText: "\u66FF\u6362\u6587\u672C",
|
|
839
840
|
copyText: "\u590D\u5236\u6587\u672C",
|
|
840
841
|
info: "\u5185\u5BB9\u7531 AI \u751F\u6210\uFF0C\u8BF7\u4ED4\u7EC6\u7504\u522B\u3002",
|
|
841
|
-
stopEdit: "\u7EC8\u6B62\u7F16\u8F91"
|
|
842
|
+
stopEdit: "\u7EC8\u6B62\u7F16\u8F91",
|
|
843
|
+
warningTitle: "\u786E\u8BA4\u4E2D\u6B62",
|
|
844
|
+
warningDesc: "\u786E\u8BA4\u4E2D\u6B62\u521B\u4F5C\u5417\uFF1F"
|
|
842
845
|
}
|
|
843
846
|
},
|
|
844
847
|
// runTime
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.ibiz-inline-ai-container-context-menu{--ibiz-inline-ai-context-menu-color-bg:var(--ibiz-color-bg-2);--ibiz-inline-ai-context-menu-color-text:var(--ibiz-color-text-0);--ibiz-inline-ai-context-menu-color-bg-active:var(--ibiz-color-fill-0);--mx-menu-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-backgroud:var(--ibiz-inline-ai-context-menu-color-bg);--mx-menu-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-open-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active)}.ibiz-inline-ai-container-context-menu .scroll-content{pointer-events:unset}.ibiz-inline-ai-container-context-menu .mx-context-menu{cursor:pointer}.ibiz-inline-ai-textarea-container{position:absolute;z-index:
|
|
1
|
+
.ibiz-inline-ai-container-context-menu{--ibiz-inline-ai-context-menu-color-bg:var(--ibiz-color-bg-2);--ibiz-inline-ai-context-menu-color-text:var(--ibiz-color-text-0);--ibiz-inline-ai-context-menu-color-bg-active:var(--ibiz-color-fill-0);--mx-menu-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-backgroud:var(--ibiz-inline-ai-context-menu-color-bg);--mx-menu-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-open-hover-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-open-hover-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-active-backgroud:var(--ibiz-inline-ai-context-menu-color-bg-active);--mx-menu-active-text:var(--ibiz-inline-ai-context-menu-color-text);--mx-menu-backgroud-radius:0}.ibiz-inline-ai-container-context-menu .scroll-content{pointer-events:unset}.ibiz-inline-ai-container-context-menu .mx-context-menu-item{cursor:pointer}.ibiz-inline-ai-textarea-container{--ibiz-inline-ai-textarea-container-color-bg-0:rgb(255, 255, 255);--ibiz-inline-ai-textarea-container-color-bg-1:rgb(249, 249, 249);--ibiz-inline-ai-textarea-container-color-border:rgba(29, 31, 35, 0.1);--ibiz-inline-ai-textarea-container-color-text-0:rgb(29, 31, 35);--ibiz-inline-ai-textarea-container-color-text-1:rgba(29, 31, 35, 0.35);--ibiz-inline-ai-textarea-container-color-text-2:rgb(85, 125, 165);--ibiz-inline-ai-textarea-container-color-text-hove-1:rgb(105, 148, 190);--ibiz-inline-ai-textarea-container-color-bg-hover-1:rgb(217, 236, 255);--ibiz-inline-ai-textarea-container-color-bg-hover-2:rgba(46, 50, 55, 0.05);--ibiz-inline-ai-textarea-container-color-loading:#65b3fc}.ibiz-inline-ai-textarea-container--dark{--ibiz-inline-ai-textarea-container-color-bg-0:rgb(28, 28, 28);--ibiz-inline-ai-textarea-container-color-bg-1:rgb(53, 54, 60);--ibiz-inline-ai-textarea-container-color-border:rgba(255, 255, 255, 0.08);--ibiz-inline-ai-textarea-container-color-text-0:rgb(255, 255, 255);--ibiz-inline-ai-textarea-container-color-text-1:rgba(249, 249, 249, 0.35);--ibiz-inline-ai-textarea-container-color-text-2:rgb(70, 107, 144);--ibiz-inline-ai-textarea-container-color-text-hove-1:rgb(105, 148, 190);--ibiz-inline-ai-textarea-container-color-bg-hover-1:rgba(85, 125, 165, 0.2);--ibiz-inline-ai-textarea-container-color-bg-hover-2:rgb(67, 68, 74);--ibiz-inline-ai-textarea-container-color-loading:rgba(204, 204, 204, 0.6)}.ibiz-inline-ai-textarea-container{position:absolute;z-index:2000;color:var(--ibiz-inline-ai-textarea-container-color-text-0);-webkit-user-select:none;-moz-user-select:none;user-select:none}.ibiz-inline-ai-textarea-container .ibiz-inline-ai-textarea-container__content{border:1px solid var(--ibiz-inline-ai-textarea-container-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:0 0 16px var(--ibiz-color-shadow)}.ibiz-inline-ai-textarea-container.is-show-ai{border:1px solid var(--ibiz-inline-ai-textarea-container-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:0 0 16px var(--ibiz-color-shadow)}.ibiz-inline-ai-textarea-container.is-show-ai .ibiz-inline-ai-textarea-container__content{border:none;border-radius:var(--ibiz-border-radius-small) var(--ibiz-border-radius-small) 0 0;box-shadow:none}.ibiz-inline-ai-textarea-container.is-show-ai .ibiz-inline-ai-textarea-container__footer{border-radius:0 0 var(--ibiz-border-radius-small) var(--ibiz-border-radius-small)}.ibiz-inline-ai-textarea-container__content{position:relative;display:flex;gap:var(--ibiz-spacing-tight);padding:var(--ibiz-spacing-base-tight);background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0)}.ibiz-inline-ai-textarea-container__content--prefix{flex-shrink:0;color:var(--ibiz-inline-ai-textarea-container-color-text-1)}.ibiz-inline-ai-textarea-container__content--textarea{position:relative;flex-grow:1}.ibiz-inline-ai-textarea-container__content--textarea textarea{width:100%;height:100%;padding:0;color:var(--ibiz-inline-ai-textarea-container-color-text-0);resize:none;background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0);border:none;outline:0}.ibiz-inline-ai-textarea-container__content--textarea textarea:disabled{background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0)}.ibiz-inline-ai-textarea-container__content--suffix{display:flex;flex-direction:column-reverse;flex-shrink:0}.ibiz-inline-ai-textarea-container__content--sand-icon{display:flex;align-items:center;justify-content:center;width:28px;height:28px;color:var(--ibiz-inline-ai-textarea-container-color-text-2);cursor:pointer;border-radius:var(--ibiz-spacing-extra-tight)}.ibiz-inline-ai-textarea-container__content--sand-icon:hover{background-color:var(--ibiz-inline-ai-textarea-container-color-bg-hover-1)}.ibiz-inline-ai-textarea-container__content--stop-icon{display:flex;gap:var(--ibiz-spacing-extra-tight);align-items:center;font-size:var(--ibiz-font-size-small);color:var(--ibiz-inline-ai-textarea-container-color-text-1);cursor:pointer}.ibiz-inline-ai-textarea-container__content--stop-icon:hover{color:var(--ibiz-inline-ai-textarea-container-color-text-hove-1)}.ibiz-inline-ai-textarea-container__footer{padding:var(--ibiz-spacing-base-tight) var(--ibiz-spacing-base);font-size:var(--ibiz-font-size-small);color:var(--ibiz-inline-ai-textarea-container-color-text-1);visibility:hidden;background-color:var(--ibiz-inline-ai-textarea-container-color-bg-1);border-top:1px solid var(--ibiz-inline-ai-textarea-container-color-border)}.ibiz-inline-ai-textarea-container__footer.is-show{visibility:visible}.ibiz-inline-ai-textarea-container__actions{position:absolute;width:240px;padding:var(--ibiz-spacing-base-tight) 0;font-size:var(--ibiz-font-size-regular);visibility:hidden;background-color:var(--ibiz-inline-ai-textarea-container-color-bg-0);border:1px solid var(--ibiz-inline-ai-textarea-container-color-border);border-radius:var(--ibiz-border-radius-small);box-shadow:0 0 16px var(--ibiz-color-shadow)}.ibiz-inline-ai-textarea-container__actions.is-show{visibility:visible}.ibiz-inline-ai-textarea-container__actions--action{display:flex;gap:var(--ibiz-spacing-tight);align-items:center;padding:var(--ibiz-spacing-tight) var(--ibiz-spacing-base-loose);cursor:pointer}.ibiz-inline-ai-textarea-container__actions--action:hover{background-color:var(--ibiz-inline-ai-textarea-container-color-bg-hover-2)}.ibiz-inline-ai-textarea-container__actions--action.is-danger:hover{color:var(--ibiz-color-danger)}.ibiz-inline-ai-textarea-container__actions--divider{margin:var(--ibiz-spacing-extra-tight) var(--ibiz-spacing-base-loose);border-top:1px solid var(--ibiz-inline-ai-textarea-container-color-border)}.ibiz-inline-ai-textarea-container__loading{position:absolute;top:0;left:0;display:flex;gap:8px;align-items:center;width:100%;height:100%;overflow:hidden}@keyframes bounce{0%,100%,80%{transform:scale(0)}40%{transform:scale(1)}}.ibiz-inline-ai-textarea-container__loading--dot{width:12px;height:12px;background:var(--ibiz-inline-ai-textarea-container-color-loading);border-radius:50%;animation:bounce 1.5s infinite ease-in-out}.ibiz-inline-ai-textarea-container__loading--dot:nth-child(2){animation-delay:.2s}.ibiz-inline-ai-textarea-container__loading--dot:nth-child(3){animation-delay:.4s}
|
|
@@ -8,14 +8,27 @@ const computedInLineAIParams = (props) => {
|
|
|
8
8
|
return {
|
|
9
9
|
srfaiappendcurdata: (_a = props.context.srfaiappendcurdata) != null ? _a : true,
|
|
10
10
|
srfaiautoappend: props.params.srfaiautoappend === "true" || props.params.srfaiautoappend === true,
|
|
11
|
-
srfmode: props.params.srfmode
|
|
11
|
+
srfmode: props.params.srfmode,
|
|
12
|
+
srfaiagent: props.params.srfaiagent
|
|
12
13
|
};
|
|
13
14
|
};
|
|
14
|
-
const useInLineAIContainerClick = (props) => {
|
|
15
|
-
const handclick = (evt) => {
|
|
15
|
+
const useInLineAIContainerClick = (props, content, isLoading) => {
|
|
16
|
+
const handclick = async (evt) => {
|
|
16
17
|
const target = evt.target;
|
|
17
|
-
if (!target.closest(".ibiz-inline-ai-textarea-container")) {
|
|
18
|
-
props.
|
|
18
|
+
if (!target.closest(".ibiz-inline-ai-textarea-container") && !target.closest(".ibiz-inline-ai-alert") && !isLoading.value) {
|
|
19
|
+
const isChange = props.content !== content.value;
|
|
20
|
+
let isClose = true;
|
|
21
|
+
if (isChange) {
|
|
22
|
+
isClose = await ibiz.confirm.warning({
|
|
23
|
+
title: ibiz.i18n.t("util.inlineAiUtil.warningTitle"),
|
|
24
|
+
desc: ibiz.i18n.t("util.inlineAiUtil.warningDesc"),
|
|
25
|
+
options: {
|
|
26
|
+
modalClass: "ibiz-inline-ai-alert"
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (isClose)
|
|
31
|
+
props.unMountAIChat();
|
|
19
32
|
}
|
|
20
33
|
};
|
|
21
34
|
onMounted(() => {
|
|
@@ -27,7 +40,7 @@ const useInLineAIContainerClick = (props) => {
|
|
|
27
40
|
};
|
|
28
41
|
const useAI = (props, opts) => {
|
|
29
42
|
const { context, data, deACMode } = props;
|
|
30
|
-
const { srfaiappendcurdata, srfmode } = opts;
|
|
43
|
+
const { srfaiappendcurdata, srfmode, srfaiagent } = opts;
|
|
31
44
|
const params = { srfactag: deACMode.codeName };
|
|
32
45
|
const app = ibiz.hub.getApp(deACMode.appId);
|
|
33
46
|
let history = [];
|
|
@@ -48,6 +61,8 @@ const useAI = (props, opts) => {
|
|
|
48
61
|
Object.assign(body, { data });
|
|
49
62
|
if (srfmode)
|
|
50
63
|
Object.assign(body, { mode: srfmode });
|
|
64
|
+
if (srfaiagent)
|
|
65
|
+
Object.assign(body, { srfaiagent });
|
|
51
66
|
const response = await app.net.post(path, body, params);
|
|
52
67
|
if (response.ok && Array.isArray(response.data)) {
|
|
53
68
|
history = response.data.filter(
|
|
@@ -68,6 +83,8 @@ const useAI = (props, opts) => {
|
|
|
68
83
|
};
|
|
69
84
|
if (srfmode)
|
|
70
85
|
Object.assign(body, { mode: srfmode });
|
|
86
|
+
if (srfaiagent)
|
|
87
|
+
Object.assign(body, { srfaiagent });
|
|
71
88
|
const appDataEntity = await ibiz.hub.getAppDataEntity(
|
|
72
89
|
deACMode.appDataEntityId,
|
|
73
90
|
deACMode.appId
|
|
@@ -123,24 +140,47 @@ const useBase = (props, container, target) => {
|
|
|
123
140
|
actionName: "cancel"
|
|
124
141
|
}
|
|
125
142
|
];
|
|
143
|
+
const { options } = props;
|
|
144
|
+
const editorRect = options.editorElement.getBoundingClientRect();
|
|
145
|
+
const offsetX = options.left - editorRect.left;
|
|
146
|
+
const offsetY = options.top - editorRect.top;
|
|
147
|
+
const theme = options.editorTheme || "light";
|
|
126
148
|
const actionStyle = ref({});
|
|
127
149
|
const containerStyle = ref({
|
|
128
|
-
width: "".concat(
|
|
129
|
-
left: "".concat(
|
|
130
|
-
top: "".concat(
|
|
150
|
+
width: "".concat(options.width, "px"),
|
|
151
|
+
left: "".concat(options.left, "px"),
|
|
152
|
+
top: "".concat(options.top, "px")
|
|
131
153
|
});
|
|
132
154
|
const contentStyle = ref({
|
|
133
|
-
height: "".concat(
|
|
134
|
-
"max-height": "".concat(
|
|
155
|
+
height: "".concat(options.height || 80, "px"),
|
|
156
|
+
"max-height": "".concat(options.maxHeight, "px")
|
|
135
157
|
});
|
|
136
|
-
const
|
|
158
|
+
const updatePosition = () => {
|
|
137
159
|
if (!container.value || !target.value)
|
|
138
160
|
return;
|
|
139
|
-
const
|
|
161
|
+
const rect = options.editorElement.getBoundingClientRect();
|
|
162
|
+
let top = rect.top + offsetY;
|
|
163
|
+
let left = rect.left + offsetX;
|
|
164
|
+
const containerWidth = container.value.offsetWidth;
|
|
165
|
+
const containerHeight = container.value.offsetHeight;
|
|
166
|
+
const windowWidth = window.innerWidth;
|
|
167
|
+
const windowHeight = window.innerHeight;
|
|
168
|
+
const margin = 8;
|
|
169
|
+
if (left + containerWidth + margin > windowWidth) {
|
|
170
|
+
left = windowWidth - containerWidth - margin;
|
|
171
|
+
} else if (left < margin) {
|
|
172
|
+
left = margin;
|
|
173
|
+
}
|
|
174
|
+
if (top + containerHeight + margin > windowHeight) {
|
|
175
|
+
top = windowHeight - containerHeight - margin;
|
|
176
|
+
} else if (top < margin) {
|
|
177
|
+
top = margin;
|
|
178
|
+
}
|
|
179
|
+
containerStyle.value.top = "".concat(top, "px");
|
|
180
|
+
containerStyle.value.left = "".concat(left, "px");
|
|
181
|
+
const position = containerHeight + 4;
|
|
140
182
|
const targetHeight = target.value.offsetHeight;
|
|
141
|
-
|
|
142
|
-
const position = (isInit ? containerRect.height + 41 : containerRect.height) + 4;
|
|
143
|
-
if (spaceBelow >= targetHeight + 8) {
|
|
183
|
+
if (windowHeight - (top + containerHeight + targetHeight) > margin) {
|
|
144
184
|
actionStyle.value.top = "".concat(position, "px");
|
|
145
185
|
actionStyle.value.bottom = "auto";
|
|
146
186
|
} else {
|
|
@@ -148,15 +188,30 @@ const useBase = (props, container, target) => {
|
|
|
148
188
|
actionStyle.value.top = "auto";
|
|
149
189
|
}
|
|
150
190
|
};
|
|
151
|
-
|
|
191
|
+
let ticking = false;
|
|
192
|
+
const optimizedUpdatePosition = () => {
|
|
193
|
+
if (!ticking) {
|
|
194
|
+
requestAnimationFrame(() => {
|
|
195
|
+
updatePosition();
|
|
196
|
+
ticking = false;
|
|
197
|
+
});
|
|
198
|
+
ticking = true;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
152
201
|
onMounted(() => {
|
|
153
|
-
|
|
154
|
-
|
|
202
|
+
updatePosition();
|
|
203
|
+
document.addEventListener("scroll", optimizedUpdatePosition, {
|
|
204
|
+
capture: true
|
|
205
|
+
});
|
|
206
|
+
window.addEventListener("resize", optimizedUpdatePosition);
|
|
155
207
|
});
|
|
156
208
|
onUnmounted(() => {
|
|
157
|
-
|
|
209
|
+
document.removeEventListener("scroll", optimizedUpdatePosition, {
|
|
210
|
+
capture: true
|
|
211
|
+
});
|
|
212
|
+
window.removeEventListener("resize", optimizedUpdatePosition);
|
|
158
213
|
});
|
|
159
|
-
return { actions, actionStyle, containerStyle, contentStyle };
|
|
214
|
+
return { theme, actions, actionStyle, containerStyle, contentStyle };
|
|
160
215
|
};
|
|
161
216
|
|
|
162
217
|
export { computedInLineAIParams, useAI, useBase, useInLineAIContainerClick };
|
|
@@ -52,32 +52,45 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
|
|
|
52
52
|
const ns = useNamespace("inline-ai-textarea-container");
|
|
53
53
|
const containerRef = ref();
|
|
54
54
|
const actionsRef = ref();
|
|
55
|
+
const textareaRef = ref();
|
|
56
|
+
const textareaContent = ref(props.content);
|
|
57
|
+
let question;
|
|
58
|
+
const contentType = ref("USER");
|
|
59
|
+
const isLoading = ref(false);
|
|
60
|
+
const disabled = computed(() => {
|
|
61
|
+
return contentType.value === "ASSISTANT" || isLoading.value;
|
|
62
|
+
});
|
|
63
|
+
const isShow = computed(() => {
|
|
64
|
+
return contentType.value === "ASSISTANT" && !isLoading.value;
|
|
65
|
+
});
|
|
55
66
|
const {
|
|
56
67
|
srfaiappendcurdata,
|
|
57
68
|
srfaiautoappend,
|
|
58
|
-
srfmode
|
|
69
|
+
srfmode,
|
|
70
|
+
srfaiagent
|
|
59
71
|
} = computedInLineAIParams(props);
|
|
60
72
|
const {
|
|
73
|
+
theme,
|
|
61
74
|
actions,
|
|
62
75
|
actionStyle,
|
|
63
76
|
containerStyle,
|
|
64
77
|
contentStyle
|
|
65
78
|
} = useBase(props, containerRef, actionsRef);
|
|
66
|
-
useInLineAIContainerClick(props);
|
|
79
|
+
useInLineAIContainerClick(props, textareaContent, isLoading);
|
|
67
80
|
const {
|
|
68
81
|
askAI
|
|
69
82
|
} = useAI(props, {
|
|
70
83
|
srfaiappendcurdata,
|
|
71
|
-
srfmode
|
|
72
|
-
|
|
73
|
-
const textareaContent = ref(props.content);
|
|
74
|
-
let question;
|
|
75
|
-
const contentType = ref("USER");
|
|
76
|
-
const isLoading = ref(false);
|
|
77
|
-
const disabled = computed(() => {
|
|
78
|
-
return contentType.value === "ASSISTANT" || isLoading.value;
|
|
84
|
+
srfmode,
|
|
85
|
+
srfaiagent
|
|
79
86
|
});
|
|
87
|
+
const restoreFocus = () => {
|
|
88
|
+
var _a;
|
|
89
|
+
(_a = textareaRef.value) == null ? void 0 : _a.blur();
|
|
90
|
+
props.restoreSelection();
|
|
91
|
+
};
|
|
80
92
|
const sendQuestion = async (content) => {
|
|
93
|
+
restoreFocus();
|
|
81
94
|
question = content;
|
|
82
95
|
textareaContent.value = "";
|
|
83
96
|
isLoading.value = true;
|
|
@@ -122,15 +135,22 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
|
|
|
122
135
|
}
|
|
123
136
|
};
|
|
124
137
|
onMounted(() => {
|
|
125
|
-
|
|
138
|
+
var _a;
|
|
139
|
+
if (srfaiautoappend) {
|
|
126
140
|
sendQuestion(textareaContent.value);
|
|
141
|
+
} else {
|
|
142
|
+
(_a = textareaRef.value) == null ? void 0 : _a.focus();
|
|
143
|
+
}
|
|
127
144
|
});
|
|
128
145
|
return {
|
|
129
146
|
ns,
|
|
147
|
+
theme,
|
|
148
|
+
isShow,
|
|
130
149
|
actions,
|
|
150
|
+
disabled,
|
|
131
151
|
isLoading,
|
|
132
152
|
actionsRef,
|
|
133
|
-
|
|
153
|
+
textareaRef,
|
|
134
154
|
actionStyle,
|
|
135
155
|
contentType,
|
|
136
156
|
containerRef,
|
|
@@ -146,8 +166,8 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
|
|
|
146
166
|
render() {
|
|
147
167
|
return createVNode("div", {
|
|
148
168
|
"ref": "containerRef",
|
|
149
|
-
"
|
|
150
|
-
"
|
|
169
|
+
"style": this.containerStyle,
|
|
170
|
+
"class": [this.ns.b(), this.ns.m(this.theme), this.ns.is("show-ai", this.isShow)]
|
|
151
171
|
}, [createVNode("div", {
|
|
152
172
|
"class": this.ns.e("content"),
|
|
153
173
|
"style": this.contentStyle
|
|
@@ -158,36 +178,31 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
|
|
|
158
178
|
}, [AIIcon])]), createVNode("div", {
|
|
159
179
|
"class": this.ns.em("content", "textarea")
|
|
160
180
|
}, [this.isLoading && createVNode("div", {
|
|
161
|
-
"class": "
|
|
162
|
-
"style": ""
|
|
181
|
+
"class": this.ns.e("loading")
|
|
163
182
|
}, [createVNode("div", {
|
|
164
|
-
"class": "
|
|
165
|
-
},
|
|
166
|
-
"class": "
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
"
|
|
171
|
-
"cy": "25",
|
|
172
|
-
"r": "20",
|
|
173
|
-
"fill": "none"
|
|
174
|
-
}, null)])])]), withDirectives(createVNode("textarea", {
|
|
183
|
+
"class": this.ns.em("loading", "dot")
|
|
184
|
+
}, null), createVNode("div", {
|
|
185
|
+
"class": this.ns.em("loading", "dot")
|
|
186
|
+
}, null), createVNode("div", {
|
|
187
|
+
"class": this.ns.em("loading", "dot")
|
|
188
|
+
}, null)]), withDirectives(createVNode("textarea", {
|
|
189
|
+
"ref": "textareaRef",
|
|
175
190
|
"disabled": this.disabled,
|
|
176
191
|
"onKeydown": this.onKeydown,
|
|
177
192
|
"onUpdate:modelValue": ($event) => this.textareaContent = $event
|
|
178
|
-
}, null), [[vModelText, this.textareaContent]])]),
|
|
193
|
+
}, null), [[vModelText, this.textareaContent]])]), createVNode("div", {
|
|
179
194
|
"class": this.ns.em("content", "suffix")
|
|
180
|
-
}, [this.isLoading
|
|
195
|
+
}, [this.isLoading && createVNode("div", {
|
|
181
196
|
"class": this.ns.em("content", "stop-icon"),
|
|
182
197
|
"onClick": () => this.stopQuestion()
|
|
183
|
-
}, [StopIcon, createVNode("span", null, [ibiz.i18n.t("util.inlineAiUtil.stopEdit")])])
|
|
198
|
+
}, [StopIcon, createVNode("span", null, [ibiz.i18n.t("util.inlineAiUtil.stopEdit")])]), !this.disabled && createVNode("div", {
|
|
184
199
|
"class": this.ns.em("content", "sand-icon"),
|
|
185
200
|
"onClick": () => this.sendQuestion(this.textareaContent)
|
|
186
|
-
}, [SendIcon])])]),
|
|
187
|
-
"class": this.ns.e("footer")
|
|
201
|
+
}, [SendIcon])])]), createVNode("div", {
|
|
202
|
+
"class": [this.ns.e("footer"), this.ns.is("show", this.isShow)]
|
|
188
203
|
}, [ibiz.i18n.t("util.inlineAiUtil.info")]), createVNode("div", {
|
|
189
204
|
"ref": "actionsRef",
|
|
190
|
-
"class": [this.ns.e("actions"), this.ns.is("show", this.
|
|
205
|
+
"class": [this.ns.e("actions"), this.ns.is("show", this.isShow)],
|
|
191
206
|
"style": this.actionStyle
|
|
192
207
|
}, [this.actions.map((action) => {
|
|
193
208
|
if (action.itemType === "divider")
|
|
@@ -56,7 +56,7 @@ const IBizFormItemContainer = /* @__PURE__ */ vue.defineComponent({
|
|
|
56
56
|
}, null);
|
|
57
57
|
}
|
|
58
58
|
};
|
|
59
|
-
const
|
|
59
|
+
const renderTipsIcon = () => {
|
|
60
60
|
return vue.createVNode(vue.resolveComponent("el-tooltip"), {
|
|
61
61
|
"effect": "light",
|
|
62
62
|
"visible": visible.value,
|
|
@@ -66,16 +66,42 @@ const IBizFormItemContainer = /* @__PURE__ */ vue.defineComponent({
|
|
|
66
66
|
"placement": labelPos === "RIGHT" ? "right" : "left"
|
|
67
67
|
}, {
|
|
68
68
|
default: () => {
|
|
69
|
-
return vue.createVNode("
|
|
70
|
-
"class": [ns.em("label", "content"), ns.is("tooltip", enableInputTip)]
|
|
71
|
-
}, [enableInputTip && ibiz.config.form.showTipsIcon && vue.createVNode("ion-icon", {
|
|
69
|
+
return vue.createVNode("ion-icon", {
|
|
72
70
|
"name": "bulb-outline",
|
|
73
71
|
"class": ns.em("label", "icon")
|
|
74
|
-
}, null)
|
|
72
|
+
}, null);
|
|
73
|
+
},
|
|
74
|
+
content: () => {
|
|
75
|
+
return vue.createVNode("div", {
|
|
76
|
+
"class": ns.em("popper", "content")
|
|
77
|
+
}, [vue.createVNode("div", {
|
|
78
|
+
"class": ns.em("popper", "tooltip")
|
|
79
|
+
}, [renderTipContent()]), c.state.inputTipUrl && vue.createVNode("a", {
|
|
80
|
+
"target": "_blank",
|
|
81
|
+
"href": c.state.inputTipUrl,
|
|
82
|
+
"title": ibiz.i18n.t("component.formItemContainer.more")
|
|
83
|
+
}, [ibiz.i18n.t("component.formItemContainer.more")])]);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
const renderLabelWithoutTips = () => {
|
|
88
|
+
return vue.createVNode(vue.resolveComponent("el-tooltip"), {
|
|
89
|
+
"effect": "light",
|
|
90
|
+
"visible": visible.value,
|
|
91
|
+
"onUpdate:visible": ($event) => visible.value = $event,
|
|
92
|
+
"popper-class": [ns.e("popper"), ns.is(ibiz.config.tooltiprendermode.toLowerCase(), true)],
|
|
93
|
+
"disabled": !enableInputTip,
|
|
94
|
+
"placement": labelPos === "RIGHT" ? "right" : "left"
|
|
95
|
+
}, {
|
|
96
|
+
default: () => {
|
|
97
|
+
return vue.createVNode("div", {
|
|
98
|
+
"class": [ns.em("label", "content"), ns.is("tooltip", enableInputTip)]
|
|
99
|
+
}, [sysImage && vue.createVNode(vue3Util.IBizIcon, {
|
|
75
100
|
"class": ns.em("label", "icon"),
|
|
76
101
|
"icon": sysImage
|
|
77
102
|
}, null), vue.createVNode("div", {
|
|
78
|
-
"class": ns.em("label", "text")
|
|
103
|
+
"class": ns.em("label", "text"),
|
|
104
|
+
"title": enableInputTip ? void 0 : core.showTitle(c.labelCaption)
|
|
79
105
|
}, [c.labelCaption])]);
|
|
80
106
|
},
|
|
81
107
|
content: () => {
|
|
@@ -92,10 +118,18 @@ const IBizFormItemContainer = /* @__PURE__ */ vue.defineComponent({
|
|
|
92
118
|
});
|
|
93
119
|
};
|
|
94
120
|
const renderLabel = () => {
|
|
121
|
+
const showTipsIcon = enableInputTip && ibiz.config.form.showTipsIcon;
|
|
95
122
|
return vue.createVNode("div", {
|
|
96
|
-
"title": enableInputTip ? void 0 : core.showTitle(c.labelCaption),
|
|
97
123
|
"class": [ns.e("label"), ...c.labelClass || []]
|
|
98
|
-
}, [
|
|
124
|
+
}, [showTipsIcon && vue.createVNode("div", {
|
|
125
|
+
"class": [ns.em("label", "content"), ns.is("tooltip", enableInputTip)]
|
|
126
|
+
}, [renderTipsIcon(), sysImage && vue.createVNode(vue3Util.IBizIcon, {
|
|
127
|
+
"class": ns.em("label", "icon"),
|
|
128
|
+
"icon": sysImage
|
|
129
|
+
}, null), vue.createVNode("div", {
|
|
130
|
+
"class": ns.em("label", "text"),
|
|
131
|
+
"title": core.showTitle(c.labelCaption)
|
|
132
|
+
}, [c.labelCaption])]), !showTipsIcon && renderLabelWithoutTips()]);
|
|
99
133
|
};
|
|
100
134
|
return {
|
|
101
135
|
ns,
|