@ibiz-template/vue3-components 0.7.41-alpha.40 → 0.7.41-alpha.42

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.
Files changed (66) hide show
  1. package/dist/ibiz-markdown-editor-pEdb_gS_.js +1 -0
  2. package/dist/index-BObZTN7-.js +11 -0
  3. package/dist/{index-BewO9StC.js → index-CD2XM6M6.js} +1 -1
  4. package/dist/{index-ClxO69TM.js → index-CaWTEUU1.js} +1 -1
  5. package/dist/index.min.css +1 -1
  6. package/dist/index.system.min.js +1 -1
  7. package/dist/wang-editor-Ck-JCWqK.js +1 -0
  8. package/dist/{xlsx-util-Cg5zMYCC.js → xlsx-util-B1eGfH7d.js} +1 -1
  9. package/es/control/form/form-detail/form-item/composite-form-item-ex/composite-form-item-ex.controller.mjs +18 -7
  10. package/es/control/form/form-detail/form-item/composite-form-item-ex/composite-form-item-ex.css +1 -1
  11. package/es/control/form/form-detail/form-item/composite-form-item-ex/composite-form-item-ex.mjs +12 -2
  12. package/es/editor/code/monaco-editor/monaco-editor.mjs +48 -33
  13. package/es/editor/html/wang-editor/config/index.mjs +3 -0
  14. package/es/editor/html/wang-editor/config/toolbar.mjs +90 -0
  15. package/es/editor/html/wang-editor/constants/svg.mjs +8 -0
  16. package/es/editor/html/wang-editor/wang-editor.css +1 -1
  17. package/es/editor/html/wang-editor/wang-editor.mjs +63 -40
  18. package/es/editor/markdown/ibiz-markdown-editor/custom-menu.mjs +274 -3
  19. package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
  20. package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.mjs +40 -7
  21. package/es/editor/markdown/ibiz-markdown-editor/render-util.mjs +33 -4
  22. package/es/editor/text-box/input/input.mjs +41 -32
  23. package/es/index.mjs +1 -1
  24. package/es/locale/en/index.mjs +3 -1
  25. package/es/locale/zh-CN/index.mjs +3 -1
  26. package/es/util/ai-chat-util/ai-chat-util.mjs +215 -0
  27. package/es/util/app-util/app-util.mjs +20 -48
  28. package/es/util/index.mjs +1 -1
  29. package/es/util/inline-ai-util/inline-ai-textarea/icon.mjs +75 -1
  30. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -1
  31. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.mjs +140 -43
  32. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.mjs +132 -48
  33. package/es/util/inline-ai-util/inline-ai-util.mjs +2 -1
  34. package/es/web-app/main.mjs +2 -0
  35. package/lib/control/form/form-detail/form-item/composite-form-item-ex/composite-form-item-ex.cjs +12 -2
  36. package/lib/control/form/form-detail/form-item/composite-form-item-ex/composite-form-item-ex.controller.cjs +18 -7
  37. package/lib/control/form/form-detail/form-item/composite-form-item-ex/composite-form-item-ex.css +1 -1
  38. package/lib/editor/code/monaco-editor/monaco-editor.cjs +47 -32
  39. package/lib/editor/html/wang-editor/config/index.cjs +7 -0
  40. package/lib/editor/html/wang-editor/config/toolbar.cjs +92 -0
  41. package/lib/editor/html/wang-editor/constants/svg.cjs +14 -0
  42. package/lib/editor/html/wang-editor/wang-editor.cjs +62 -39
  43. package/lib/editor/html/wang-editor/wang-editor.css +1 -1
  44. package/lib/editor/markdown/ibiz-markdown-editor/custom-menu.cjs +274 -3
  45. package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.cjs +40 -7
  46. package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
  47. package/lib/editor/markdown/ibiz-markdown-editor/render-util.cjs +33 -4
  48. package/lib/editor/text-box/input/input.cjs +40 -31
  49. package/lib/index.cjs +2 -2
  50. package/lib/locale/en/index.cjs +3 -1
  51. package/lib/locale/zh-CN/index.cjs +3 -1
  52. package/lib/util/ai-chat-util/ai-chat-util.cjs +217 -0
  53. package/lib/util/app-util/app-util.cjs +19 -47
  54. package/lib/util/index.cjs +2 -2
  55. package/lib/util/inline-ai-util/inline-ai-textarea/icon.cjs +78 -0
  56. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.cjs +131 -47
  57. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -1
  58. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.cjs +139 -42
  59. package/lib/util/inline-ai-util/inline-ai-util.cjs +2 -1
  60. package/lib/web-app/main.cjs +2 -0
  61. package/package.json +5 -5
  62. package/dist/ibiz-markdown-editor-CxFS8frQ.js +0 -1
  63. package/dist/index-2eZnbrr4.js +0 -11
  64. package/dist/wang-editor-BPl509oX.js +0 -1
  65. package/es/util/ai-util/ai-util.mjs +0 -68
  66. package/lib/util/ai-util/ai-util.cjs +0 -71
@@ -1,20 +1,30 @@
1
1
  import qs from 'qs';
2
2
  import { notNilEmpty } from 'qx-util';
3
- import { onMounted, onUnmounted, ref } from 'vue';
3
+ import { useUIStore } from '@ibiz-template/vue3-util';
4
+ import { onMounted, onUnmounted, ref, watch, nextTick } from 'vue';
4
5
  import { calcResPath } from '@ibiz-template/runtime';
5
6
  import { RegenerateIcon, insertTextIcon, ReplaceTextIcon, CopyTextIcon, CancelIcon } from './icon.mjs';
6
7
 
7
8
  "use strict";
8
9
  const computedInLineAIParams = (props) => {
9
- var _a;
10
+ var _a, _b, _c, _d, _e, _f, _g;
11
+ const { params, context, editorParams } = props;
12
+ const getBooleanValue = (value) => {
13
+ if (value === "false")
14
+ return false;
15
+ if (value === "true")
16
+ return true;
17
+ return null;
18
+ };
10
19
  return {
11
- srfaiappendcurdata: (_a = props.context.srfaiappendcurdata) != null ? _a : true,
12
- srfaiautoappend: props.params.srfaiautoappend === "true" || props.params.srfaiautoappend === true,
13
- srfmode: props.params.srfmode,
14
- srfaiagent: props.params.srfaiagent
20
+ srfaiappendcurdata: (_c = (_b = (_a = getBooleanValue(context.srfaiappendcurdata)) != null ? _a : getBooleanValue(params.srfaiappendcurdata)) != null ? _b : getBooleanValue(editorParams.srfaiappendcurdata)) != null ? _c : true,
21
+ autoquestion: (_e = (_d = getBooleanValue(params.autoquestion)) != null ? _d : getBooleanValue(editorParams.autoquestion)) != null ? _e : false,
22
+ srfmode: params.srfmode,
23
+ srfaiagent: params.srfaiagent,
24
+ inlinecompletionmode: (_g = (_f = params.inlinecompletionmode) != null ? _f : editorParams.inlinecompletionmode) != null ? _g : "async"
15
25
  };
16
26
  };
17
- const useInLineAIContainerClick = (props, content, isLoading) => {
27
+ const useInLineAIContainerClick = (props, message, isLoading) => {
18
28
  const handclick = async (evt) => {
19
29
  const target = evt.target;
20
30
  if (!target.closest(".ibiz-inline-ai-textarea-container") && !target.closest(".ibiz-inline-ai-alert")) {
@@ -22,7 +32,7 @@ const useInLineAIContainerClick = (props, content, isLoading) => {
22
32
  evt.stopPropagation();
23
33
  return;
24
34
  }
25
- const isChange = props.content !== content.value;
35
+ const isChange = props.content !== message.value.content;
26
36
  let isClose = true;
27
37
  if (isChange) {
28
38
  isClose = await ibiz.confirm.warning({
@@ -50,21 +60,24 @@ const useAI = (props, opts) => {
50
60
  const params = { srfactag: deACMode.codeName };
51
61
  const app = ibiz.hub.getApp(deACMode.appId);
52
62
  let history = [];
53
- const calcAIPath = (appDataEntity, isHistories = false) => {
63
+ let appDataEntity;
64
+ const calcAIPath = (isHistories = false, isAsync = false) => {
65
+ if (!appDataEntity)
66
+ return "";
54
67
  const srfkey = context[appDataEntity.codeName.toLowerCase()];
55
- const curPath = "/".concat(appDataEntity.deapicodeName2, "/chatcompletion").concat(isHistories ? "/histories" : "").concat(srfkey ? "/".concat(srfkey) : "");
68
+ const curPath = "/".concat(appDataEntity.deapicodeName2, "/").concat(isAsync ? "sse" : "", "chatcompletion").concat(isHistories ? "/histories" : "").concat(srfkey ? "/".concat(srfkey) : "");
56
69
  const resPath = calcResPath(context, appDataEntity);
57
70
  return resPath ? "/".concat(resPath).concat(curPath) : "".concat(curPath);
58
71
  };
59
72
  const loadAiHistory = async () => {
60
- const appDataEntity = await ibiz.hub.getAppDataEntity(
73
+ appDataEntity = await ibiz.hub.getAppDataEntity(
61
74
  deACMode.appDataEntityId,
62
75
  deACMode.appId
63
76
  );
64
- const path = calcAIPath(appDataEntity, true);
77
+ const path = calcAIPath(true);
65
78
  const body = {};
66
79
  if (srfaiappendcurdata)
67
- Object.assign(body, { data });
80
+ Object.assign(body, data);
68
81
  if (srfmode)
69
82
  Object.assign(body, { mode: srfmode });
70
83
  if (srfaiagent)
@@ -97,14 +110,13 @@ const useAI = (props, opts) => {
97
110
  }
98
111
  return url;
99
112
  };
100
- const askAI = async (content) => {
101
- var _a, _b;
113
+ const prepareData = (question, isAsync = false) => {
102
114
  const body = {
103
115
  messages: [
104
116
  ...history,
105
117
  {
106
118
  role: "USER",
107
- content
119
+ content: question
108
120
  }
109
121
  ]
110
122
  };
@@ -112,32 +124,96 @@ const useAI = (props, opts) => {
112
124
  Object.assign(body, { mode: srfmode });
113
125
  if (srfaiagent)
114
126
  Object.assign(body, { srfaiagent });
115
- abortController.value = new AbortController();
116
- const appDataEntity = await ibiz.hub.getAppDataEntity(
117
- deACMode.appDataEntityId,
118
- deACMode.appId
119
- );
120
- const path = attachUrlParam(calcAIPath(appDataEntity));
121
- const response = await app.net.request(path, {
122
- method: "post",
123
- data: body,
124
- signal: abortController.value.signal
127
+ let url = calcAIPath(false, isAsync);
128
+ if (!isAsync)
129
+ url = attachUrlParam(url);
130
+ return { body, url };
131
+ };
132
+ const parseContent = (text) => {
133
+ let think;
134
+ let content;
135
+ if (!text)
136
+ return { think, content };
137
+ const openThinkIndex = text.indexOf("<think>");
138
+ const closeThinkIndex = text.indexOf("</think>");
139
+ if (openThinkIndex !== -1) {
140
+ think = closeThinkIndex === -1 ? text.slice(openThinkIndex + 7) : text.slice(openThinkIndex + 7, closeThinkIndex);
141
+ content = closeThinkIndex === -1 ? void 0 : text.slice(closeThinkIndex + 8);
142
+ } else {
143
+ content = text;
144
+ }
145
+ return { think, content };
146
+ };
147
+ const asyncAskAI = (question, callBack, errorBack) => {
148
+ return new Promise((resolve) => {
149
+ abortController.value = new AbortController();
150
+ const { body, url } = prepareData(question, true);
151
+ app.net.sse(url, params, {
152
+ headers: {
153
+ "Content-Type": "application/json"
154
+ },
155
+ body: JSON.stringify(body),
156
+ onmessage: (e) => {
157
+ var _a;
158
+ try {
159
+ if (e.data) {
160
+ const msg = JSON.parse(e.data);
161
+ let content = msg.actionresult;
162
+ if (msg.actionstate === 30 && content)
163
+ content = (_a = JSON.parse(content).choices) == null ? void 0 : _a[0].content;
164
+ callBack({ state: msg.actionstate, content });
165
+ }
166
+ } catch (error) {
167
+ ibiz.log.error(error);
168
+ }
169
+ },
170
+ onclose: () => resolve(),
171
+ onerror: (error) => {
172
+ callBack({ state: 40, content: error.message });
173
+ errorBack();
174
+ throw error;
175
+ },
176
+ signal: abortController.value.signal
177
+ });
125
178
  });
126
- if (response.ok) {
127
- const result = (_b = (_a = response.data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.content;
128
- return result;
179
+ };
180
+ const syncAskAI = async (question) => {
181
+ var _a, _b;
182
+ abortController.value = new AbortController();
183
+ const { body, url } = prepareData(question);
184
+ const answer = {
185
+ state: 10,
186
+ content: ""
187
+ };
188
+ try {
189
+ const response = await app.net.request(url, {
190
+ method: "post",
191
+ data: body,
192
+ signal: abortController.value.signal
193
+ });
194
+ if (response.ok)
195
+ Object.assign(answer, {
196
+ state: 30,
197
+ content: (_b = (_a = response.data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.content
198
+ });
199
+ return answer;
200
+ } catch (error) {
201
+ Object.assign(answer, {
202
+ state: 40,
203
+ content: error.message
204
+ });
205
+ return answer;
129
206
  }
130
- return "";
131
207
  };
132
- onMounted(() => {
133
- loadAiHistory();
134
- });
135
208
  return {
136
- askAI,
209
+ syncAskAI,
210
+ asyncAskAI,
211
+ parseContent,
212
+ loadAiHistory,
137
213
  abortController
138
214
  };
139
215
  };
140
- const useBase = (props, container, target) => {
216
+ const useBase = (props, element, message) => {
141
217
  const actions = [
142
218
  {
143
219
  title: ibiz.i18n.t("util.inlineAiUtil.regenerate"),
@@ -173,7 +249,9 @@ const useBase = (props, container, target) => {
173
249
  actionName: "cancel"
174
250
  }
175
251
  ];
252
+ const { zIndex } = useUIStore();
176
253
  const { options } = props;
254
+ const { containerRef, actionsRef, textareaRef } = element;
177
255
  const editorRect = options.editorElement.getBoundingClientRect();
178
256
  const offsetX = options.left - editorRect.left;
179
257
  const offsetY = options.top - editorRect.top;
@@ -182,20 +260,32 @@ const useBase = (props, container, target) => {
182
260
  const containerStyle = ref({
183
261
  width: "".concat(options.width, "px"),
184
262
  left: "".concat(options.left, "px"),
185
- top: "".concat(options.top, "px")
263
+ top: "".concat(options.top, "px"),
264
+ zIndex: zIndex.increment()
186
265
  });
187
266
  const contentStyle = ref({
188
- height: "".concat(options.height || 300, "px"),
189
- "max-height": "".concat(options.maxHeight, "px")
267
+ height: options.height ? "".concat(options.height, "px") : "auto",
268
+ "max-height": "".concat(options.maxHeight || (options.height && options.height > 300 ? options.height : 300), "px")
190
269
  });
270
+ watch(
271
+ () => message.value.content,
272
+ () => {
273
+ nextTick(() => {
274
+ if (!textareaRef.value)
275
+ return;
276
+ textareaRef.value.style.height = "auto";
277
+ textareaRef.value.style.height = "".concat(textareaRef.value.scrollHeight, "px");
278
+ });
279
+ }
280
+ );
191
281
  const updatePosition = () => {
192
- if (!container.value || !target.value)
282
+ if (!containerRef.value || !actionsRef.value)
193
283
  return;
194
284
  const rect = options.editorElement.getBoundingClientRect();
195
285
  let top = rect.top + offsetY;
196
286
  let left = rect.left + offsetX;
197
- const containerWidth = container.value.offsetWidth;
198
- const containerHeight = container.value.offsetHeight;
287
+ const containerWidth = containerRef.value.offsetWidth;
288
+ const containerHeight = containerRef.value.offsetHeight;
199
289
  const windowWidth = window.innerWidth;
200
290
  const windowHeight = window.innerHeight;
201
291
  const margin = 8;
@@ -212,7 +302,7 @@ const useBase = (props, container, target) => {
212
302
  containerStyle.value.top = "".concat(top, "px");
213
303
  containerStyle.value.left = "".concat(left, "px");
214
304
  const position = containerHeight + 4;
215
- const targetHeight = target.value.offsetHeight;
305
+ const targetHeight = actionsRef.value.offsetHeight;
216
306
  if (windowHeight - (top + containerHeight + targetHeight) > margin) {
217
307
  actionStyle.value.top = "".concat(position, "px");
218
308
  actionStyle.value.bottom = "auto";
@@ -231,18 +321,25 @@ const useBase = (props, container, target) => {
231
321
  ticking = true;
232
322
  }
233
323
  };
324
+ let observer;
234
325
  onMounted(() => {
235
- updatePosition();
236
326
  document.addEventListener("scroll", optimizedUpdatePosition, {
237
327
  capture: true
238
328
  });
239
329
  window.addEventListener("resize", optimizedUpdatePosition);
330
+ if (containerRef.value) {
331
+ observer = new ResizeObserver(optimizedUpdatePosition);
332
+ observer.observe(containerRef.value);
333
+ }
240
334
  });
241
335
  onUnmounted(() => {
336
+ zIndex.decrement();
242
337
  document.removeEventListener("scroll", optimizedUpdatePosition, {
243
338
  capture: true
244
339
  });
245
340
  window.removeEventListener("resize", optimizedUpdatePosition);
341
+ observer == null ? void 0 : observer.disconnect();
342
+ observer = null;
246
343
  });
247
344
  return { theme, actions, actionStyle, containerStyle, contentStyle };
248
345
  };
@@ -1,7 +1,7 @@
1
1
  import { defineComponent, createVNode, withDirectives, vModelText, ref, computed, onMounted } from 'vue';
2
2
  import { useNamespace } from '@ibiz-template/vue3-util';
3
3
  import { computedInLineAIParams, useBase, useAI, useInLineAIContainerClick } from './inline-ai-textarea.hook.mjs';
4
- import { AIIcon, StopIcon, SendIcon } from './icon.mjs';
4
+ import { AIIcon, StopIcon, SendIcon, LoadingIcon, ThinkSuccessIcon, DownIcon, UpIcon } from './icon.mjs';
5
5
  import './inline-ai-textarea.css';
6
6
 
7
7
  "use strict";
@@ -15,6 +15,10 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
15
15
  type: Object,
16
16
  required: true
17
17
  },
18
+ editorParams: {
19
+ type: Object,
20
+ required: true
21
+ },
18
22
  data: {
19
23
  type: Object,
20
24
  required: true
@@ -53,21 +57,28 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
53
57
  const containerRef = ref();
54
58
  const actionsRef = ref();
55
59
  const textareaRef = ref();
56
- const textareaContent = ref(props.content);
60
+ const message = ref({
61
+ role: "USER",
62
+ error: void 0,
63
+ think: void 0,
64
+ content: props.content
65
+ });
57
66
  let question;
58
- const contentType = ref("USER");
67
+ let answerContent;
59
68
  const isLoading = ref(false);
69
+ const isCollapse = ref(false);
60
70
  const disabled = computed(() => {
61
- return contentType.value === "ASSISTANT" || isLoading.value;
71
+ return message.value.role === "ASSISTANT" || isLoading.value;
62
72
  });
63
73
  const isShow = computed(() => {
64
- return contentType.value === "ASSISTANT" && !isLoading.value;
74
+ return message.value.role === "ASSISTANT" && !isLoading.value;
65
75
  });
66
76
  const {
67
- srfaiappendcurdata,
68
- srfaiautoappend,
69
77
  srfmode,
70
- srfaiagent
78
+ srfaiagent,
79
+ autoquestion,
80
+ srfaiappendcurdata,
81
+ inlinecompletionmode
71
82
  } = computedInLineAIParams(props);
72
83
  const {
73
84
  theme,
@@ -75,34 +86,75 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
75
86
  actionStyle,
76
87
  containerStyle,
77
88
  contentStyle
78
- } = useBase(props, containerRef, actionsRef);
89
+ } = useBase(props, {
90
+ containerRef,
91
+ actionsRef,
92
+ textareaRef
93
+ }, message);
79
94
  const {
80
- askAI,
95
+ syncAskAI,
96
+ asyncAskAI,
97
+ parseContent,
98
+ loadAiHistory,
81
99
  abortController
82
100
  } = useAI(props, {
83
- srfaiappendcurdata,
84
101
  srfmode,
85
- srfaiagent
102
+ srfaiagent,
103
+ srfaiappendcurdata
86
104
  });
105
+ useInLineAIContainerClick(props, message, isLoading);
87
106
  const stopQuestionAndClose = () => {
88
107
  var _a;
89
108
  (_a = abortController.value) == null ? void 0 : _a.abort();
90
109
  props.unMountAIChat();
91
110
  };
92
- useInLineAIContainerClick(props, textareaContent, isLoading);
93
- const restoreFocus = () => {
94
- var _a;
95
- (_a = textareaRef.value) == null ? void 0 : _a.blur();
96
- props.restoreSelection();
111
+ const handleAnswer = (answer) => {
112
+ switch (answer.state) {
113
+ case 20:
114
+ answerContent += answer.content;
115
+ Object.assign(message.value, parseContent(answerContent));
116
+ break;
117
+ case 30:
118
+ answerContent = answer.content;
119
+ Object.assign(message.value, parseContent(answerContent));
120
+ break;
121
+ case 40:
122
+ isCollapse.value = true;
123
+ Object.assign(message.value, {
124
+ error: answer.content,
125
+ think: void 0,
126
+ content: void 0
127
+ });
128
+ break;
129
+ default:
130
+ break;
131
+ }
132
+ message.value.role = "ASSISTANT";
97
133
  };
98
134
  const sendQuestion = async (content) => {
135
+ var _a;
136
+ if (!content || isLoading.value)
137
+ return;
138
+ isLoading.value = true;
99
139
  try {
100
- isLoading.value = true;
101
- restoreFocus();
140
+ (_a = textareaRef.value) == null ? void 0 : _a.blur();
141
+ props.restoreSelection();
102
142
  question = content;
103
- textareaContent.value = "";
104
- textareaContent.value = await askAI(question);
105
- contentType.value = "ASSISTANT";
143
+ answerContent = void 0;
144
+ Object.assign(message.value, {
145
+ error: void 0,
146
+ think: void 0,
147
+ content: void 0
148
+ });
149
+ isCollapse.value = false;
150
+ if (inlinecompletionmode === "async") {
151
+ await asyncAskAI(question, handleAnswer, () => {
152
+ isLoading.value = false;
153
+ });
154
+ } else {
155
+ const answer = await syncAskAI(question);
156
+ handleAnswer(answer);
157
+ }
106
158
  } catch (error) {
107
159
  ibiz.log.error(error);
108
160
  } finally {
@@ -112,13 +164,15 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
112
164
  const onKeydown = (e) => {
113
165
  if (e.code === "Enter" && !e.isComposing) {
114
166
  e.stopPropagation();
115
- if (e.shiftKey === false) {
116
- sendQuestion(textareaContent.value);
117
- }
167
+ if (e.shiftKey === false)
168
+ sendQuestion(message.value.content);
118
169
  }
119
170
  };
171
+ const onCollapseChange = () => {
172
+ isCollapse.value = !isCollapse.value;
173
+ };
120
174
  const handleAction = (_e, actionName) => {
121
- const content = textareaContent.value;
175
+ const content = message.value.content;
122
176
  switch (actionName) {
123
177
  case "regenerate":
124
178
  sendQuestion(question);
@@ -142,32 +196,69 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
142
196
  break;
143
197
  }
144
198
  };
145
- onMounted(() => {
199
+ onMounted(async () => {
146
200
  var _a;
147
- if (srfaiautoappend) {
148
- sendQuestion(textareaContent.value);
201
+ await loadAiHistory();
202
+ if (autoquestion) {
203
+ await sendQuestion(message.value.content);
149
204
  } else {
150
205
  (_a = textareaRef.value) == null ? void 0 : _a.focus();
151
206
  }
152
207
  });
208
+ const renderLoading = () => {
209
+ const value = message.value.error || message.value.content || message.value.think;
210
+ if (!isLoading.value || value)
211
+ return;
212
+ return createVNode("div", {
213
+ "class": ns.e("loading")
214
+ }, [createVNode("div", {
215
+ "class": ns.em("loading", "dot")
216
+ }, null), createVNode("div", {
217
+ "class": ns.em("loading", "dot")
218
+ }, null), createVNode("div", {
219
+ "class": ns.em("loading", "dot")
220
+ }, null)]);
221
+ };
222
+ const renderContent = () => {
223
+ if (message.value.error)
224
+ return createVNode("div", {
225
+ "class": ns.e("error")
226
+ }, [message.value.error]);
227
+ if (message.value.think)
228
+ return createVNode("div", {
229
+ "class": ns.e("think")
230
+ }, [createVNode("div", {
231
+ "class": ns.em("think", "header"),
232
+ "onClick": onCollapseChange
233
+ }, [createVNode("div", {
234
+ "class": [ns.em("think", "state-icon"), ns.is("loading", isLoading.value)]
235
+ }, [isLoading.value ? LoadingIcon : ThinkSuccessIcon]), createVNode("div", {
236
+ "class": ns.em("think", "title")
237
+ }, [isLoading.value ? ibiz.i18n.t("util.inlineAiUtil.thinking") : ibiz.i18n.t("util.inlineAiUtil.thinked")]), createVNode("div", {
238
+ "class": ns.em("think", "collapse-icon")
239
+ }, [isCollapse.value ? DownIcon : UpIcon])]), !isCollapse.value && createVNode("div", {
240
+ "class": ns.em("think", "content")
241
+ }, [message.value.think])]);
242
+ };
153
243
  return {
154
244
  ns,
155
245
  theme,
156
246
  isShow,
157
247
  actions,
248
+ message,
158
249
  disabled,
159
250
  isLoading,
160
251
  actionsRef,
161
252
  textareaRef,
162
253
  actionStyle,
163
- contentType,
164
254
  containerRef,
165
255
  contentStyle,
166
256
  containerStyle,
167
- textareaContent,
168
257
  onKeydown,
169
258
  sendQuestion,
170
259
  handleAction,
260
+ renderLoading,
261
+ renderContent,
171
262
  stopQuestionAndClose
172
263
  };
173
264
  },
@@ -185,33 +276,26 @@ const InlineAITextArea = /* @__PURE__ */ defineComponent({
185
276
  "class": this.ns.em("content", "ai-icon")
186
277
  }, [AIIcon])]), createVNode("div", {
187
278
  "class": this.ns.em("content", "textarea")
188
- }, [this.isLoading && createVNode("div", {
189
- "class": this.ns.e("loading")
190
- }, [createVNode("div", {
191
- "class": this.ns.em("loading", "dot")
192
- }, null), createVNode("div", {
193
- "class": this.ns.em("loading", "dot")
194
- }, null), createVNode("div", {
195
- "class": this.ns.em("loading", "dot")
196
- }, null)]), withDirectives(createVNode("textarea", {
279
+ }, [this.renderLoading(), this.renderContent(), withDirectives(createVNode("textarea", {
197
280
  "ref": "textareaRef",
198
281
  "disabled": this.disabled,
199
282
  "onKeydown": this.onKeydown,
200
- "onUpdate:modelValue": ($event) => this.textareaContent = $event
201
- }, null), [[vModelText, this.textareaContent]])]), createVNode("div", {
283
+ "onUpdate:modelValue": ($event) => this.message.content = $event,
284
+ "class": this.ns.is("hidden", !!this.message.error)
285
+ }, null), [[vModelText, this.message.content]])]), createVNode("div", {
202
286
  "class": this.ns.em("content", "suffix")
203
287
  }, [this.isLoading && createVNode("div", {
204
288
  "class": this.ns.em("content", "stop-icon"),
205
289
  "onClick": () => this.stopQuestionAndClose()
206
290
  }, [StopIcon, createVNode("span", null, [ibiz.i18n.t("util.inlineAiUtil.stopEdit")])]), !this.disabled && createVNode("div", {
207
291
  "class": this.ns.em("content", "sand-icon"),
208
- "onClick": () => this.sendQuestion(this.textareaContent)
209
- }, [SendIcon])])]), createVNode("div", {
210
- "class": [this.ns.e("footer"), this.ns.is("show", this.isShow)]
211
- }, [ibiz.i18n.t("util.inlineAiUtil.info")]), createVNode("div", {
292
+ "onClick": () => this.sendQuestion(this.message.content)
293
+ }, [SendIcon])])]), this.isShow && createVNode("div", {
294
+ "class": this.ns.e("footer")
295
+ }, [ibiz.i18n.t("util.inlineAiUtil.info")]), this.isShow && createVNode("div", {
212
296
  "ref": "actionsRef",
213
- "class": [this.ns.e("actions"), this.ns.is("show", this.isShow)],
214
- "style": this.actionStyle
297
+ "style": this.actionStyle,
298
+ "class": this.ns.e("actions")
215
299
  }, [this.actions.map((action) => {
216
300
  if (action.itemType === "divider")
217
301
  return createVNode("div", {
@@ -116,7 +116,7 @@ class InLineAIUtil {
116
116
  this.container.className = this.ns.b();
117
117
  document.body.appendChild(this.container);
118
118
  const { editor } = params;
119
- const { insertText, replaceSelectionText, restoreSelection } = editor;
119
+ const { insertText, replaceSelectionText, restoreSelection, editorParams } = editor;
120
120
  delete params.editor;
121
121
  const unMountAIChat = () => {
122
122
  this.destroyInlineAIComponent();
@@ -125,6 +125,7 @@ class InLineAIUtil {
125
125
  context,
126
126
  params,
127
127
  data,
128
+ editorParams,
128
129
  content: selectText,
129
130
  deACMode,
130
131
  options,
@@ -22,6 +22,7 @@ import { LoadingUtil } from '../util/loading-util/loading-util.mjs';
22
22
  import { NoticeUtil } from '../util/notice-util/notice-util.mjs';
23
23
  import { OverlayController } from '../util/overlay-controller/overlay-controller.mjs';
24
24
  import { InLineAIUtil } from '../util/inline-ai-util/inline-ai-util.mjs';
25
+ import { AIChatUtil } from '../util/ai-chat-util/ai-chat-util.mjs';
25
26
  import { FullscreenUtil } from '../util/fullscreen/fullscreen-util.mjs';
26
27
 
27
28
  "use strict";
@@ -83,6 +84,7 @@ async function runApp(plugins, opts) {
83
84
  ibiz.notice = new NoticeUtil();
84
85
  ibiz.overlay = new OverlayController();
85
86
  ibiz.inLineAIUtil = new InLineAIUtil();
87
+ ibiz.aiChatUtil = new AIChatUtil();
86
88
  ibiz.util.text.format = (value, code) => {
87
89
  return app.config.globalProperties.$textFormat(value, code);
88
90
  };
@@ -70,14 +70,20 @@ const CompositeFormItemEx = /* @__PURE__ */ vue.defineComponent({
70
70
  const isIncludes = this.c.includesList.some((id) => id === "".concat(editorType, "_").concat(editorStyle));
71
71
  const editorSwitchMenu = vue.createVNode(vue.resolveComponent("el-popover"), {
72
72
  "trigger": "click",
73
- "popper-class": this.ns2.b("menu-popover")
73
+ "popper-class": this.ns2.b("menu-popover"),
74
+ "offset": 0
74
75
  }, {
75
76
  reference: () => {
77
+ const option = this.c.switchOptions.find((item) => item.id === this.c.state.editorId);
76
78
  return vue.createVNode("div", {
77
79
  "class": this.ns2.b("menu")
78
80
  }, [vue.createVNode("div", {
81
+ "class": this.ns2.be("menu", "text-icon")
82
+ }, [vue.createVNode(vue.resolveComponent("iBizIcon"), {
83
+ "icon": option == null ? void 0 : option.icon
84
+ }, null)]), vue.createVNode("div", {
79
85
  "class": this.ns2.be("menu", "text")
80
- }, [this.c.state.editorId]), vue.createVNode("div", {
86
+ }, [(option == null ? void 0 : option.name) || this.c.state.editorId]), vue.createVNode("div", {
81
87
  "class": this.ns2.be("menu", "icon")
82
88
  }, [vue.createVNode("svg", {
83
89
  "xmlns": "http://www.w3.org/2000/svg",
@@ -101,6 +107,10 @@ const CompositeFormItemEx = /* @__PURE__ */ vue.defineComponent({
101
107
  "class": this.ns2.be("menu-item", "icon")
102
108
  }, [vue.createVNode("path", {
103
109
  "d": "M574.116299 786.736392 1238.811249 48.517862C1272.390222 11.224635 1329.414799 7.827718 1366.75664 41.450462 1403.840015 74.840484 1406.731043 132.084741 1373.10189 169.433699L655.118888 966.834607C653.072421 969.716875 650.835807 972.514337 648.407938 975.210759 615.017957 1012.29409 558.292155 1015.652019 521.195664 982.250188L72.778218 578.493306C35.910826 545.297758 32.859041 488.584019 66.481825 451.242134 99.871807 414.158803 156.597563 410.800834 193.694055 444.202665L574.116299 786.736392Z"
110
+ }, null)]), vue.createVNode("div", {
111
+ "class": this.ns2.be("menu-item", "text-icon")
112
+ }, [vue.createVNode(vue.resolveComponent("iBizIcon"), {
113
+ "icon": option.icon
104
114
  }, null)]), vue.createVNode("span", {
105
115
  "class": this.ns2.be("menu-item", "text")
106
116
  }, [option.name])]);