@ibiz-template/vue3-components 0.7.41-alpha.37 → 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.
Files changed (70) hide show
  1. package/dist/ibiz-markdown-editor-D4Og0fLv.js +1 -0
  2. package/dist/{index-BiFsbM1Y.js → index-BewO9StC.js} +1 -1
  3. package/dist/{index-BFGNWF-0.js → index-ClxO69TM.js} +1 -1
  4. package/dist/index-DHKZJQyN.js +11 -0
  5. package/dist/index.min.css +1 -1
  6. package/dist/index.system.min.js +1 -1
  7. package/dist/wang-editor-BYeoazrn.js +1 -0
  8. package/dist/{xlsx-util-DZ5-cWNj.js → xlsx-util-DpgMzatq.js} +1 -1
  9. package/es/control/form/form-detail/form-item/form-item-container/form-item-container.mjs +42 -8
  10. package/es/control/form/form-detail/form-mdctrl/form-mdctrl-repeater/form-mdctrl-repeater.mjs +10 -0
  11. package/es/control/form/form-detail/form-mdctrl/form-mdctrl-repeater/repeater-grid2/repeater-grid2.css +1 -0
  12. package/es/control/form/form-detail/form-mdctrl/form-mdctrl-repeater/repeater-grid2/repeater-grid2.mjs +309 -0
  13. package/es/editor/code/code-editor.controller.mjs +223 -1
  14. package/es/editor/code/monaco-editor/monaco-editor.css +1 -1
  15. package/es/editor/code/monaco-editor/monaco-editor.mjs +132 -10
  16. package/es/editor/html/html-editor.controller.mjs +122 -2
  17. package/es/editor/html/wang-editor/index.mjs +1 -0
  18. package/es/editor/html/wang-editor/module/index.mjs +1 -0
  19. package/es/editor/html/wang-editor/module/inline-ai-module.mjs +95 -0
  20. package/es/editor/html/wang-editor/wang-editor.css +1 -1
  21. package/es/editor/html/wang-editor/wang-editor.mjs +41 -4
  22. package/es/editor/markdown/ibiz-markdown-editor/custom-menu.mjs +43 -0
  23. package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
  24. package/es/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.mjs +143 -9
  25. package/es/editor/markdown/markdown-editor.controller.mjs +218 -1
  26. package/es/index.mjs +1 -0
  27. package/es/locale/en/index.mjs +18 -2
  28. package/es/locale/zh-CN/index.mjs +18 -2
  29. package/es/util/ai-util/ai-util.mjs +6 -2
  30. package/es/util/app-util/app-util.mjs +41 -2
  31. package/es/util/index.mjs +1 -0
  32. package/es/util/inline-ai-util/inline-ai-textarea/icon.mjs +142 -0
  33. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -0
  34. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.mjs +217 -0
  35. package/es/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.mjs +220 -0
  36. package/es/util/inline-ai-util/inline-ai-util.mjs +145 -0
  37. package/es/web-app/main.mjs +2 -0
  38. package/lib/control/form/form-detail/form-item/form-item-container/form-item-container.cjs +42 -8
  39. package/lib/control/form/form-detail/form-mdctrl/form-mdctrl-repeater/form-mdctrl-repeater.cjs +10 -0
  40. package/lib/control/form/form-detail/form-mdctrl/form-mdctrl-repeater/repeater-grid2/repeater-grid2.cjs +311 -0
  41. package/lib/control/form/form-detail/form-mdctrl/form-mdctrl-repeater/repeater-grid2/repeater-grid2.css +1 -0
  42. package/lib/editor/code/code-editor.controller.cjs +222 -0
  43. package/lib/editor/code/monaco-editor/monaco-editor.cjs +132 -10
  44. package/lib/editor/code/monaco-editor/monaco-editor.css +1 -1
  45. package/lib/editor/html/html-editor.controller.cjs +120 -0
  46. package/lib/editor/html/wang-editor/index.cjs +3 -0
  47. package/lib/editor/html/wang-editor/module/index.cjs +3 -0
  48. package/lib/editor/html/wang-editor/module/inline-ai-module.cjs +98 -0
  49. package/lib/editor/html/wang-editor/wang-editor.cjs +41 -4
  50. package/lib/editor/html/wang-editor/wang-editor.css +1 -1
  51. package/lib/editor/markdown/ibiz-markdown-editor/custom-menu.cjs +45 -0
  52. package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.cjs +143 -9
  53. package/lib/editor/markdown/ibiz-markdown-editor/ibiz-markdown-editor.css +1 -1
  54. package/lib/editor/markdown/markdown-editor.controller.cjs +217 -0
  55. package/lib/index.cjs +2 -0
  56. package/lib/locale/en/index.cjs +18 -2
  57. package/lib/locale/zh-CN/index.cjs +18 -2
  58. package/lib/util/ai-util/ai-util.cjs +6 -2
  59. package/lib/util/app-util/app-util.cjs +40 -1
  60. package/lib/util/index.cjs +2 -0
  61. package/lib/util/inline-ai-util/inline-ai-textarea/icon.cjs +151 -0
  62. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.cjs +222 -0
  63. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.css +1 -0
  64. package/lib/util/inline-ai-util/inline-ai-textarea/inline-ai-textarea.hook.cjs +222 -0
  65. package/lib/util/inline-ai-util/inline-ai-util.cjs +147 -0
  66. package/lib/web-app/main.cjs +2 -0
  67. package/package.json +5 -5
  68. package/dist/ibiz-markdown-editor-Cs1m7gKI.js +0 -1
  69. package/dist/index-Dds3BDDF.js +0 -11
  70. package/dist/wang-editor-4cJ6X_hb.js +0 -1
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+ var vue3Util = require('@ibiz-template/vue3-util');
5
+ var inlineAiTextarea_hook = require('./inline-ai-textarea.hook.cjs');
6
+ var icon = require('./icon.cjs');
7
+ require('./inline-ai-textarea.css');
8
+
9
+ "use strict";
10
+ const InlineAITextArea = /* @__PURE__ */ vue.defineComponent({
11
+ props: {
12
+ context: {
13
+ type: Object,
14
+ required: true
15
+ },
16
+ params: {
17
+ type: Object,
18
+ required: true
19
+ },
20
+ data: {
21
+ type: Object,
22
+ required: true
23
+ },
24
+ content: {
25
+ type: String,
26
+ required: true
27
+ },
28
+ deACMode: {
29
+ type: Object,
30
+ required: true
31
+ },
32
+ options: {
33
+ type: Object,
34
+ required: true
35
+ },
36
+ insertText: {
37
+ type: Function,
38
+ required: true
39
+ },
40
+ replaceSelectionText: {
41
+ type: Function,
42
+ required: true
43
+ },
44
+ restoreSelection: {
45
+ type: Function,
46
+ required: true
47
+ },
48
+ unMountAIChat: {
49
+ type: Function,
50
+ required: true
51
+ }
52
+ },
53
+ setup(props, ctx) {
54
+ const ns = vue3Util.useNamespace("inline-ai-textarea-container");
55
+ const containerRef = vue.ref();
56
+ const actionsRef = vue.ref();
57
+ const textareaRef = vue.ref();
58
+ const textareaContent = vue.ref(props.content);
59
+ let question;
60
+ const contentType = vue.ref("USER");
61
+ const isLoading = vue.ref(false);
62
+ const disabled = vue.computed(() => {
63
+ return contentType.value === "ASSISTANT" || isLoading.value;
64
+ });
65
+ const isShow = vue.computed(() => {
66
+ return contentType.value === "ASSISTANT" && !isLoading.value;
67
+ });
68
+ const {
69
+ srfaiappendcurdata,
70
+ srfaiautoappend,
71
+ srfmode,
72
+ srfaiagent
73
+ } = inlineAiTextarea_hook.computedInLineAIParams(props);
74
+ const {
75
+ theme,
76
+ actions,
77
+ actionStyle,
78
+ containerStyle,
79
+ contentStyle
80
+ } = inlineAiTextarea_hook.useBase(props, containerRef, actionsRef);
81
+ inlineAiTextarea_hook.useInLineAIContainerClick(props, textareaContent, isLoading);
82
+ const {
83
+ askAI
84
+ } = inlineAiTextarea_hook.useAI(props, {
85
+ srfaiappendcurdata,
86
+ srfmode,
87
+ srfaiagent
88
+ });
89
+ const restoreFocus = () => {
90
+ var _a;
91
+ (_a = textareaRef.value) == null ? void 0 : _a.blur();
92
+ props.restoreSelection();
93
+ };
94
+ const sendQuestion = async (content) => {
95
+ restoreFocus();
96
+ question = content;
97
+ textareaContent.value = "";
98
+ isLoading.value = true;
99
+ textareaContent.value = await askAI(question);
100
+ isLoading.value = false;
101
+ contentType.value = "ASSISTANT";
102
+ };
103
+ const stopQuestion = () => {
104
+ props.unMountAIChat();
105
+ };
106
+ const onKeydown = (e) => {
107
+ if (e.code === "Enter" && !e.isComposing) {
108
+ e.stopPropagation();
109
+ if (e.shiftKey === false) {
110
+ sendQuestion(textareaContent.value);
111
+ }
112
+ }
113
+ };
114
+ const handleAction = (_e, actionName) => {
115
+ const content = textareaContent.value;
116
+ switch (actionName) {
117
+ case "regenerate":
118
+ sendQuestion(question);
119
+ break;
120
+ case "insertText":
121
+ props.insertText(content);
122
+ props.unMountAIChat();
123
+ break;
124
+ case "replaceText":
125
+ props.replaceSelectionText(content);
126
+ props.unMountAIChat();
127
+ break;
128
+ case "copyText":
129
+ ibiz.util.text.copy(content);
130
+ props.unMountAIChat();
131
+ break;
132
+ case "cancel":
133
+ props.unMountAIChat();
134
+ break;
135
+ default:
136
+ break;
137
+ }
138
+ };
139
+ vue.onMounted(() => {
140
+ var _a;
141
+ if (srfaiautoappend) {
142
+ sendQuestion(textareaContent.value);
143
+ } else {
144
+ (_a = textareaRef.value) == null ? void 0 : _a.focus();
145
+ }
146
+ });
147
+ return {
148
+ ns,
149
+ theme,
150
+ isShow,
151
+ actions,
152
+ disabled,
153
+ isLoading,
154
+ actionsRef,
155
+ textareaRef,
156
+ actionStyle,
157
+ contentType,
158
+ containerRef,
159
+ contentStyle,
160
+ containerStyle,
161
+ textareaContent,
162
+ onKeydown,
163
+ sendQuestion,
164
+ stopQuestion,
165
+ handleAction
166
+ };
167
+ },
168
+ render() {
169
+ return vue.createVNode("div", {
170
+ "ref": "containerRef",
171
+ "style": this.containerStyle,
172
+ "class": [this.ns.b(), this.ns.m(this.theme), this.ns.is("show-ai", this.isShow)]
173
+ }, [vue.createVNode("div", {
174
+ "class": this.ns.e("content"),
175
+ "style": this.contentStyle
176
+ }, [!this.disabled && vue.createVNode("div", {
177
+ "class": this.ns.em("content", "prefix")
178
+ }, [vue.createVNode("div", {
179
+ "class": this.ns.em("content", "ai-icon")
180
+ }, [icon.AIIcon])]), vue.createVNode("div", {
181
+ "class": this.ns.em("content", "textarea")
182
+ }, [this.isLoading && vue.createVNode("div", {
183
+ "class": this.ns.e("loading")
184
+ }, [vue.createVNode("div", {
185
+ "class": this.ns.em("loading", "dot")
186
+ }, null), vue.createVNode("div", {
187
+ "class": this.ns.em("loading", "dot")
188
+ }, null), vue.createVNode("div", {
189
+ "class": this.ns.em("loading", "dot")
190
+ }, null)]), vue.withDirectives(vue.createVNode("textarea", {
191
+ "ref": "textareaRef",
192
+ "disabled": this.disabled,
193
+ "onKeydown": this.onKeydown,
194
+ "onUpdate:modelValue": ($event) => this.textareaContent = $event
195
+ }, null), [[vue.vModelText, this.textareaContent]])]), vue.createVNode("div", {
196
+ "class": this.ns.em("content", "suffix")
197
+ }, [this.isLoading && vue.createVNode("div", {
198
+ "class": this.ns.em("content", "stop-icon"),
199
+ "onClick": () => this.stopQuestion()
200
+ }, [icon.StopIcon, vue.createVNode("span", null, [ibiz.i18n.t("util.inlineAiUtil.stopEdit")])]), !this.disabled && vue.createVNode("div", {
201
+ "class": this.ns.em("content", "sand-icon"),
202
+ "onClick": () => this.sendQuestion(this.textareaContent)
203
+ }, [icon.SendIcon])])]), vue.createVNode("div", {
204
+ "class": [this.ns.e("footer"), this.ns.is("show", this.isShow)]
205
+ }, [ibiz.i18n.t("util.inlineAiUtil.info")]), vue.createVNode("div", {
206
+ "ref": "actionsRef",
207
+ "class": [this.ns.e("actions"), this.ns.is("show", this.isShow)],
208
+ "style": this.actionStyle
209
+ }, [this.actions.map((action) => {
210
+ if (action.itemType === "divider")
211
+ return vue.createVNode("div", {
212
+ "class": this.ns.em("actions", action.itemType)
213
+ }, null);
214
+ return vue.createVNode("div", {
215
+ "class": [this.ns.em("actions", action.itemType), this.ns.is("danger", action.actionName === "cancel")],
216
+ "onClick": (e) => this.handleAction(e, action.actionName)
217
+ }, [action.icon, vue.createVNode("span", null, [action.title])]);
218
+ })])]);
219
+ }
220
+ });
221
+
222
+ exports.InlineAITextArea = InlineAITextArea;
@@ -0,0 +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);--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}
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+ var runtime = require('@ibiz-template/runtime');
5
+ var icon = require('./icon.cjs');
6
+
7
+ "use strict";
8
+ const computedInLineAIParams = (props) => {
9
+ var _a;
10
+ 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
15
+ };
16
+ };
17
+ const useInLineAIContainerClick = (props, content, isLoading) => {
18
+ const handclick = async (evt) => {
19
+ const target = evt.target;
20
+ if (!target.closest(".ibiz-inline-ai-textarea-container") && !target.closest(".ibiz-inline-ai-alert") && !isLoading.value) {
21
+ const isChange = props.content !== content.value;
22
+ let isClose = true;
23
+ if (isChange) {
24
+ isClose = await ibiz.confirm.warning({
25
+ title: ibiz.i18n.t("util.inlineAiUtil.warningTitle"),
26
+ desc: ibiz.i18n.t("util.inlineAiUtil.warningDesc"),
27
+ options: {
28
+ modalClass: "ibiz-inline-ai-alert"
29
+ }
30
+ });
31
+ }
32
+ if (isClose)
33
+ props.unMountAIChat();
34
+ }
35
+ };
36
+ vue.onMounted(() => {
37
+ document.addEventListener("click", handclick, true);
38
+ });
39
+ vue.onUnmounted(() => {
40
+ document.removeEventListener("click", handclick, true);
41
+ });
42
+ };
43
+ const useAI = (props, opts) => {
44
+ const { context, data, deACMode } = props;
45
+ const { srfaiappendcurdata, srfmode, srfaiagent } = opts;
46
+ const params = { srfactag: deACMode.codeName };
47
+ const app = ibiz.hub.getApp(deACMode.appId);
48
+ let history = [];
49
+ const calcAIPath = (appDataEntity, isHistories = false) => {
50
+ const srfkey = context[appDataEntity.codeName.toLowerCase()];
51
+ const curPath = "/".concat(appDataEntity.deapicodeName2, "/chatcompletion").concat(isHistories ? "/histories" : "").concat(srfkey ? "/".concat(srfkey) : "");
52
+ const resPath = runtime.calcResPath(context, appDataEntity);
53
+ return resPath ? "/".concat(resPath).concat(curPath) : "".concat(curPath);
54
+ };
55
+ const loadAiHistory = async () => {
56
+ const appDataEntity = await ibiz.hub.getAppDataEntity(
57
+ deACMode.appDataEntityId,
58
+ deACMode.appId
59
+ );
60
+ const path = calcAIPath(appDataEntity, true);
61
+ const body = {};
62
+ if (srfaiappendcurdata)
63
+ Object.assign(body, { data });
64
+ if (srfmode)
65
+ Object.assign(body, { mode: srfmode });
66
+ if (srfaiagent)
67
+ Object.assign(body, { srfaiagent });
68
+ const response = await app.net.post(path, body, params);
69
+ if (response.ok && Array.isArray(response.data)) {
70
+ history = response.data.filter(
71
+ (item) => ["USER", "ASSISTANT"].includes(item.role)
72
+ );
73
+ }
74
+ };
75
+ const askAI = async (content) => {
76
+ var _a, _b;
77
+ const body = {
78
+ messages: [
79
+ ...history,
80
+ {
81
+ role: "USER",
82
+ content
83
+ }
84
+ ]
85
+ };
86
+ if (srfmode)
87
+ Object.assign(body, { mode: srfmode });
88
+ if (srfaiagent)
89
+ Object.assign(body, { srfaiagent });
90
+ const appDataEntity = await ibiz.hub.getAppDataEntity(
91
+ deACMode.appDataEntityId,
92
+ deACMode.appId
93
+ );
94
+ const path = calcAIPath(appDataEntity);
95
+ const response = await app.net.post(path, body, params);
96
+ if (response.ok) {
97
+ const result = (_b = (_a = response.data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.content;
98
+ return result;
99
+ }
100
+ return "";
101
+ };
102
+ vue.onMounted(() => {
103
+ loadAiHistory();
104
+ });
105
+ return {
106
+ askAI
107
+ };
108
+ };
109
+ const useBase = (props, container, target) => {
110
+ const actions = [
111
+ {
112
+ title: ibiz.i18n.t("util.inlineAiUtil.regenerate"),
113
+ icon: icon.RegenerateIcon,
114
+ itemType: "action",
115
+ actionName: "regenerate"
116
+ },
117
+ {
118
+ title: ibiz.i18n.t("util.inlineAiUtil.insertText"),
119
+ icon: icon.insertTextIcon,
120
+ itemType: "action",
121
+ actionName: "insertText"
122
+ },
123
+ {
124
+ title: ibiz.i18n.t("util.inlineAiUtil.replaceText"),
125
+ icon: icon.ReplaceTextIcon,
126
+ itemType: "action",
127
+ actionName: "replaceText"
128
+ },
129
+ {
130
+ itemType: "divider"
131
+ },
132
+ {
133
+ title: ibiz.i18n.t("util.inlineAiUtil.copyText"),
134
+ icon: icon.CopyTextIcon,
135
+ itemType: "action",
136
+ actionName: "copyText"
137
+ },
138
+ {
139
+ title: ibiz.i18n.t("app.cancel"),
140
+ icon: icon.CancelIcon,
141
+ itemType: "action",
142
+ actionName: "cancel"
143
+ }
144
+ ];
145
+ const { options } = props;
146
+ const editorRect = options.editorElement.getBoundingClientRect();
147
+ const offsetX = options.left - editorRect.left;
148
+ const offsetY = options.top - editorRect.top;
149
+ const theme = options.editorTheme || "light";
150
+ const actionStyle = vue.ref({});
151
+ const containerStyle = vue.ref({
152
+ width: "".concat(options.width, "px"),
153
+ left: "".concat(options.left, "px"),
154
+ top: "".concat(options.top, "px")
155
+ });
156
+ const contentStyle = vue.ref({
157
+ height: "".concat(options.height || 80, "px"),
158
+ "max-height": "".concat(options.maxHeight, "px")
159
+ });
160
+ const updatePosition = () => {
161
+ if (!container.value || !target.value)
162
+ return;
163
+ const rect = options.editorElement.getBoundingClientRect();
164
+ let top = rect.top + offsetY;
165
+ let left = rect.left + offsetX;
166
+ const containerWidth = container.value.offsetWidth;
167
+ const containerHeight = container.value.offsetHeight;
168
+ const windowWidth = window.innerWidth;
169
+ const windowHeight = window.innerHeight;
170
+ const margin = 8;
171
+ if (left + containerWidth + margin > windowWidth) {
172
+ left = windowWidth - containerWidth - margin;
173
+ } else if (left < margin) {
174
+ left = margin;
175
+ }
176
+ if (top + containerHeight + margin > windowHeight) {
177
+ top = windowHeight - containerHeight - margin;
178
+ } else if (top < margin) {
179
+ top = margin;
180
+ }
181
+ containerStyle.value.top = "".concat(top, "px");
182
+ containerStyle.value.left = "".concat(left, "px");
183
+ const position = containerHeight + 4;
184
+ const targetHeight = target.value.offsetHeight;
185
+ if (windowHeight - (top + containerHeight + targetHeight) > margin) {
186
+ actionStyle.value.top = "".concat(position, "px");
187
+ actionStyle.value.bottom = "auto";
188
+ } else {
189
+ actionStyle.value.bottom = "".concat(position, "px");
190
+ actionStyle.value.top = "auto";
191
+ }
192
+ };
193
+ let ticking = false;
194
+ const optimizedUpdatePosition = () => {
195
+ if (!ticking) {
196
+ requestAnimationFrame(() => {
197
+ updatePosition();
198
+ ticking = false;
199
+ });
200
+ ticking = true;
201
+ }
202
+ };
203
+ vue.onMounted(() => {
204
+ updatePosition();
205
+ document.addEventListener("scroll", optimizedUpdatePosition, {
206
+ capture: true
207
+ });
208
+ window.addEventListener("resize", optimizedUpdatePosition);
209
+ });
210
+ vue.onUnmounted(() => {
211
+ document.removeEventListener("scroll", optimizedUpdatePosition, {
212
+ capture: true
213
+ });
214
+ window.removeEventListener("resize", optimizedUpdatePosition);
215
+ });
216
+ return { theme, actions, actionStyle, containerStyle, contentStyle };
217
+ };
218
+
219
+ exports.computedInLineAIParams = computedInLineAIParams;
220
+ exports.useAI = useAI;
221
+ exports.useBase = useBase;
222
+ exports.useInLineAIContainerClick = useInLineAIContainerClick;
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+
3
+ var vue = require('vue');
4
+ var ContextMenu = require('@imengyu/vue3-context-menu');
5
+ var vue3Util = require('@ibiz-template/vue3-util');
6
+ var inlineAiTextarea = require('./inline-ai-textarea/inline-ai-textarea.cjs');
7
+
8
+ "use strict";
9
+ var __defProp = Object.defineProperty;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __publicField = (obj, key, value) => {
12
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
+ return value;
14
+ };
15
+ class InLineAIUtil {
16
+ /**
17
+ * Creates an instance of InLineAIUtil.
18
+ * @memberof InLineAIUtil
19
+ */
20
+ constructor() {
21
+ __publicField(this, "currentApp", null);
22
+ __publicField(this, "container", null);
23
+ __publicField(this, "ns", vue3Util.useNamespace("inline-ai-container"));
24
+ }
25
+ /**
26
+ * 计算上下文菜单
27
+ * @param deACMode
28
+ * @param clickCallBack
29
+ * @returns
30
+ */
31
+ calcContextMenus(deACMode, clickCallBack) {
32
+ var _a, _b;
33
+ const menus = [];
34
+ if (!deACMode || !deACMode.deuiactionGroup || !deACMode.deuiactionGroup.uiactionGroupDetails)
35
+ return menus;
36
+ (_b = (_a = deACMode.deuiactionGroup) == null ? void 0 : _a.uiactionGroupDetails) == null ? void 0 : _b.forEach((item) => {
37
+ var _a2, _b2, _c;
38
+ const menuItem = {};
39
+ if (item.detailType === "DEUIACTION" && ((_a2 = item.uiactionId) == null ? void 0 : _a2.startsWith("inline"))) {
40
+ if (item.showCaption && item.caption) {
41
+ menuItem.label = item.caption;
42
+ }
43
+ if (item.sysImage && item.showIcon) {
44
+ menuItem.icon = vue.h("iBizIcon", {
45
+ icon: item.sysImage
46
+ });
47
+ }
48
+ menuItem.clickClose = true;
49
+ const { uiactionId } = item;
50
+ if (uiactionId) {
51
+ menuItem.onClick = () => {
52
+ clickCallBack(uiactionId);
53
+ };
54
+ }
55
+ menus.push(menuItem);
56
+ } else if (item.detailType === "DEUIACTIONGROUP" && item.refUIActionGroup && ((_b2 = item.refUIActionGroup.id) == null ? void 0 : _b2.startsWith("inline"))) {
57
+ menuItem.label = item.refUIActionGroup.name;
58
+ const menuItems = (_c = item.refUIActionGroup.uiactionGroupDetails) == null ? void 0 : _c.filter((detail) => {
59
+ var _a3;
60
+ return detail.detailType === "DEUIACTION" && ((_a3 = detail.uiactionId) == null ? void 0 : _a3.startsWith("inline"));
61
+ }).map((detail) => {
62
+ return {
63
+ label: detail.showCaption ? detail.caption : void 0,
64
+ icon: detail.showIcon && detail.sysImage ? vue.h("iBizIcon", {
65
+ icon: detail.sysImage
66
+ }) : void 0,
67
+ clickableWhenHasChildren: true,
68
+ onClick: () => {
69
+ ContextMenu.closeContextMenu();
70
+ clickCallBack(detail.uiactionId);
71
+ }
72
+ };
73
+ });
74
+ menuItem.children = menuItems;
75
+ menus.push(menuItem);
76
+ }
77
+ });
78
+ return menus;
79
+ }
80
+ /**
81
+ * 显示上下文菜单
82
+ * @param x 距离左侧距离
83
+ * @param y 距离上方距离
84
+ * @param menus 菜单集合
85
+ */
86
+ showContextMenus(x, y, menus) {
87
+ ContextMenu.showContextMenu({
88
+ x,
89
+ y,
90
+ customClass: this.ns.b("context-menu"),
91
+ items: menus
92
+ });
93
+ }
94
+ /**
95
+ * 销毁组件实例
96
+ */
97
+ destroyInlineAIComponent() {
98
+ if (this.currentApp && this.container) {
99
+ this.currentApp.unmount();
100
+ this.currentApp = null;
101
+ }
102
+ if (this.container && document.body.contains(this.container)) {
103
+ document.body.removeChild(this.container);
104
+ this.container = null;
105
+ }
106
+ }
107
+ /**
108
+ * 显示AI聊天组件
109
+ * @param selectText
110
+ * @param options
111
+ * @returns
112
+ */
113
+ showAIChat(context, params, data, selectText, deACMode, options) {
114
+ this.destroyInlineAIComponent();
115
+ this.container = document.createElement("div");
116
+ this.container.id = this.ns.b();
117
+ this.container.className = this.ns.b();
118
+ document.body.appendChild(this.container);
119
+ const { editor } = params;
120
+ const { insertText, replaceSelectionText, restoreSelection } = editor;
121
+ delete params.editor;
122
+ const unMountAIChat = () => {
123
+ this.destroyInlineAIComponent();
124
+ };
125
+ this.currentApp = vue.createApp(inlineAiTextarea.InlineAITextArea, {
126
+ context,
127
+ params,
128
+ data,
129
+ content: selectText,
130
+ deACMode,
131
+ options,
132
+ insertText: insertText.bind(editor),
133
+ replaceSelectionText: replaceSelectionText.bind(editor),
134
+ restoreSelection: restoreSelection.bind(editor),
135
+ unMountAIChat
136
+ });
137
+ this.currentApp.mount(this.container);
138
+ }
139
+ /**
140
+ * 隐藏AI聊天组件
141
+ */
142
+ hideAIChat() {
143
+ this.destroyInlineAIComponent();
144
+ }
145
+ }
146
+
147
+ exports.InLineAIUtil = InLineAIUtil;
@@ -23,6 +23,7 @@ var notificationUtil = require('../util/notification-util/notification-util.cjs'
23
23
  var loadingUtil = require('../util/loading-util/loading-util.cjs');
24
24
  var noticeUtil = require('../util/notice-util/notice-util.cjs');
25
25
  var overlayController = require('../util/overlay-controller/overlay-controller.cjs');
26
+ var inlineAiUtil = require('../util/inline-ai-util/inline-ai-util.cjs');
26
27
  var fullscreenUtil = require('../util/fullscreen/fullscreen-util.cjs');
27
28
 
28
29
  "use strict";
@@ -83,6 +84,7 @@ async function runApp(plugins, opts) {
83
84
  ibiz.loading = new loadingUtil.LoadingUtil();
84
85
  ibiz.notice = new noticeUtil.NoticeUtil();
85
86
  ibiz.overlay = new overlayController.OverlayController();
87
+ ibiz.inLineAIUtil = new inlineAiUtil.InLineAIUtil();
86
88
  ibiz.util.text.format = (value, code) => {
87
89
  return app.config.globalProperties.$textFormat(value, code);
88
90
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibiz-template/vue3-components",
3
- "version": "0.7.41-alpha.37",
3
+ "version": "0.7.41-alpha.39",
4
4
  "description": "web端组件库(vue3)",
5
5
  "main": "lib/index.cjs",
6
6
  "module": "es/index.mjs",
@@ -30,16 +30,16 @@
30
30
  "dependencies": {
31
31
  "@amap/amap-jsapi-loader": "^1.0.1",
32
32
  "@floating-ui/dom": "^1.5.3",
33
- "@ibiz-template-plugin/ai-chat": "^0.0.32",
33
+ "@ibiz-template-plugin/ai-chat": "^0.0.33",
34
34
  "@ibiz-template-plugin/gantt": "0.1.8-alpha.316",
35
35
  "@ibiz-template-plugin/bi-report": "0.0.30",
36
36
  "@ibiz-template-plugin/data-view": "0.0.6",
37
37
  "@ibiz-template/core": "0.7.41-alpha.35",
38
38
  "@ibiz-template/devtool": "0.0.13",
39
- "@ibiz-template/model-helper": "0.7.41-alpha.36",
40
- "@ibiz-template/runtime": "0.7.41-alpha.36",
39
+ "@ibiz-template/model-helper": "0.7.41-alpha.38",
40
+ "@ibiz-template/runtime": "0.7.41-alpha.38",
41
41
  "@ibiz-template/theme": "0.7.39",
42
- "@ibiz-template/vue3-util": "0.7.41-alpha.36",
42
+ "@ibiz-template/vue3-util": "0.7.41-alpha.38",
43
43
  "@ibiz-template/web-theme": "3.9.0",
44
44
  "@ibiz/model-core": "^0.1.83",
45
45
  "@imengyu/vue3-context-menu": "^1.3.5",
@@ -1 +0,0 @@
1
- System.register(["vue","@ibiz-template/vue3-util","qx-util","cherry-markdown"],function(e){"use strict";var t,l,n,o,i,r,a,s,c,d,u,m,h,p;return{setters:[function(e){t=e.defineComponent,l=e.createVNode,n=e.ref,o=e.watch,i=e.onMounted,r=e.onBeforeUnmount,a=e.onUnmounted,s=e.nextTick},function(e){c=e.getEditorEmits,d=e.getMarkDownProps,u=e.useNamespace,m=e.useUIStore},function(e){h=e.createUUID},function(e){p=e.default}],execute:function(){e("default",t({name:"IBizMarkDown",props:d(),emits:c(),setup(e,{emit:t}){var l,c;const d=u("markdown"),f=e.controller,b=n("");let v=null;const g=h(),w=ibiz.util.file.getUploadHeaders(),k=n({...w}),y=n(""),C=(null==(l=null==f?void 0:f.editorParams)?void 0:l.customTheme)||(null==(c=null==f?void 0:f.editorParams)?void 0:c.customtheme),{UIStore:x}=m(),U=n(C||x.theme),z=n("editOnly");let T=null,D=0;const E=n({});let P=!1;o(()=>e.data,e=>{if(e&&f){const t={...f.editorParams};t.uploadparams&&(t.uploadParams=JSON.parse(t.uploadparams));const l=ibiz.util.file.calcFileUpDownUrl(f.context,f.params,e,t);y.value=l.uploadUrl}},{immediate:!0,deep:!0});const B=n(),M=async(t,l)=>{const n=await ibiz.util.file.fileUpload(y.value,t,k.value),o=((e,t)=>{if(!f)return"";const l={...f.editorParams};return l.exportparams&&(l.exportParams=JSON.parse(l.exportparams)),t&&t.folder&&(l.osscat=t.folder),ibiz.util.file.calcFileUpDownUrl(f.context,f.params,e,l).downloadUrl})(e.data||{},n.fileid);let i=o.replace("%fileId%",n.fileid);if(ibiz.config.common.enableDownloadTicket&&f){const t=await ibiz.util.file.getDownloadTicket(f.context,f.params,e.data||{},{fileId:n.fileid},f.downloadTicketParams);t&&t.ticket&&(i=o.replace("%fileId%",t.ticket),l(i))}else l(i)},S=()=>null==v?void 0:v.getMarkdown(),I=e=>{P=!0,null==v||v.setMarkdown(e,!1)};o(()=>e.value,(e,t)=>{e!==t&&(b.value=e||"")},{immediate:!0}),o(b,(e,t)=>{const l=S();e!==t&&l!==e&&I(e)});const N=e=>{t("change",S(),null==f?void 0:f.model.id,P),P=!1},O=(e,t)=>({[e]:t}),V=(e,t="")=>{const l=document.createElement(e);return l.className=t,l},q=e=>V("i","ch-icon ch-icon-".concat(e)),R=d.e("fullscreen"),j=e=>{for(;e.firstChild;)e.removeChild(e.firstChild)},H=()=>{if(v&&B.value){const e=v.editor.options.editorDom.parentElement;if(!e)return{};const t=e.classList,l=B.value.querySelector(".".concat(R));return l?{parentElement:e,cherryClass:t,fullscreenNode:l}:{}}return{}},L=()=>{const{parentElement:e,cherryClass:t,fullscreenNode:l}=H();e&&t&&l&&(j(l),l.appendChild(q("fullscreen")),l.title=ibiz.i18n.t("editor.common.fullscreen"),t.remove("fullscreen"),null==e||e.blur(),e.setAttribute("tabindex","-1"))},A=()=>{const{cherryClass:e}=H();return null==e?void 0:e.contains("fullscreen")},F=()=>{v&&B.value&&(A()?L():(()=>{const{parentElement:e,cherryClass:t,fullscreenNode:l}=H();e&&t&&l&&(j(l),l.appendChild(q("minscreen")),t.add("fullscreen"),l.title=ibiz.i18n.t("editor.common.minimize"),e.setAttribute("tabindex","-1"),s(()=>null==e?void 0:e.focus()))})())},J=e=>{e.stopPropagation(),"Escape"===e.key&&A()&&L()};o(()=>x.theme,e=>{U.value=C||e,null==v||v.setTheme(U.value),null==v||v.setCodeBlockTheme(U.value)});return i(()=>{var t;(e.disabled||e.readonly)&&(z.value="previewOnly"),s(()=>{var t;v=new p({id:g,value:b.value,previewer:{enablePreviewerBubble:!(e.disabled||e.readonly)},themeSettings:{mainTheme:U.value,codeBlockTheme:U.value},fileUpload:M,emoji:{useUnicode:!0},header:{anchorStyle:"autonumber"},editor:{height:"100%",defaultModel:z.value,codemirror:{autofocus:!1}},toolbars:{toolbar:["bold","italic","underline","strikethrough","|","color","header","|","list","image",{insert:["link","hr","br","code","formula","toc","table","line-table","bar-table"]},"settings","togglePreview"],bubble:["bold","italic","underline","strikethrough","sub","sup","|","size","color"],float:["h1","h2","h3","|","checklist","quote","quickTable","code"],customMenu:[],sidebar:[]},callback:{afterChange:N,beforeImageMounted:O},engine:{syntax:{table:{enableChart:!1,externals:["echarts"]}}}}),v.setTheme(U.value),C&&(v.setTheme(C),v.setCodeBlockTheme(C));const l=V("span","".concat(R," cherry-toolbar-button"));l.title=ibiz.i18n.t("editor.common.fullscreen"),l.onclick=F,l.appendChild(q("fullscreen"));const n=e.disabled?v.editor.options.editorDom.parentElement:null==(t=v.editor.options.editorDom.parentElement)?void 0:t.querySelector(".cherry-toolbar>.toolbar-right");null==n||n.appendChild(l)}),(()=>{if(window.ResizeObserver&&B.value){const e={width:B.value.offsetWidth?"".concat(B.value.offsetWidth,"px"):"100%"};f&&"number"==typeof f.parent.model.height&&Object.assign(e,{height:"".concat(f.parent.model.height,"px")}),E.value=d.cssVarBlock(e),T=new ResizeObserver(e=>{const t=e[0].contentRect.width;if(t!==D){const l={width:"".concat(e[0].contentRect.width,"px")};f&&"number"==typeof f.parent.model.height&&Object.assign(l,{height:"".concat(f.parent.model.height,"px")}),E.value=d.cssVarBlock(l),D=t}}),T.observe(B.value)}})(),null==(t=B.value)||t.addEventListener("keydown",J.bind(this))}),r(()=>{var e;null==(e=B.value)||e.removeEventListener("keydown",J.bind(this))}),a(()=>{v=null,T&&T.disconnect()}),{ns:d,currentVal:b,id:g,editor:v,markDownBox:B,headers:k,theme:U,defaultModel:z,cssVars:E,getCherryHtml:()=>null==v?void 0:v.getHtml(),getCherryContent:S,setCherryContent:I}},render(){return l("div",{ref:"markDownBox",class:[this.ns.b(),this.ns.is("disabled",this.disabled)]},[l("div",{id:this.id,style:this.cssVars,class:this.ns.b("cherry")},null)])}}))}}});