@adminforth/rich-editor 1.6.16 → 2.0.1
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/build.log +2 -2
- package/custom/quillEditor.vue +34 -8
- package/dist/custom/quillEditor.vue +34 -8
- package/dist/index.js +5 -6
- package/index.ts +4 -10
- package/package.json +1 -1
- package/types.ts +0 -5
package/build.log
CHANGED
|
@@ -10,5 +10,5 @@ custom/package.json
|
|
|
10
10
|
custom/quillEditor.vue
|
|
11
11
|
custom/tsconfig.json
|
|
12
12
|
|
|
13
|
-
sent
|
|
14
|
-
total size is
|
|
13
|
+
sent 35,511 bytes received 115 bytes 71,252.00 bytes/sec
|
|
14
|
+
total size is 35,088 speedup is 0.98
|
package/custom/quillEditor.vue
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
v-if="wasQuillInitializedSuccessfully"
|
|
3
4
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500
|
|
4
5
|
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
|
|
5
6
|
dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 whitespace-normal af-quill-editor"
|
|
@@ -15,6 +16,13 @@
|
|
|
15
16
|
|
|
16
17
|
</div>
|
|
17
18
|
</div>
|
|
19
|
+
<Textarea
|
|
20
|
+
v-else
|
|
21
|
+
:modelValue="currentValue"
|
|
22
|
+
@update:modelValue="emit('update:value', $event);"
|
|
23
|
+
placeholder="Enter some text..."
|
|
24
|
+
class="w-64"
|
|
25
|
+
/>
|
|
18
26
|
|
|
19
27
|
|
|
20
28
|
</template>
|
|
@@ -30,8 +38,10 @@ import Quill from "quill";
|
|
|
30
38
|
import "quill/dist/quill.snow.css";
|
|
31
39
|
import QuillTableBetter from 'quill-table-better-yaroslav8765';
|
|
32
40
|
import 'quill-table-better-yaroslav8765/dist/quill-table-better.css';
|
|
41
|
+
import { Textarea } from '@/afcl'
|
|
33
42
|
|
|
34
43
|
import { useI18n } from 'vue-i18n';
|
|
44
|
+
import { ok } from "assert";
|
|
35
45
|
|
|
36
46
|
const { t } = useI18n();
|
|
37
47
|
function dbg(title: string,...args: any[]) {
|
|
@@ -144,6 +154,7 @@ const editorFocused = ref(false);
|
|
|
144
154
|
let lastText: string | null = null;
|
|
145
155
|
|
|
146
156
|
const imageProgress = ref(0);
|
|
157
|
+
const wasQuillInitializedSuccessfully = ref(true);
|
|
147
158
|
|
|
148
159
|
const selectedSymbolsCount = ref(0);
|
|
149
160
|
|
|
@@ -303,18 +314,33 @@ const quillOptions = {
|
|
|
303
314
|
const html = props.record[props.column.name] || '';
|
|
304
315
|
const delta = quill.clipboard.convert({ html });
|
|
305
316
|
const [range] = quill.selection.getRange();
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
try {
|
|
318
|
+
quill.updateContents(delta, Quill.sources.USER);
|
|
319
|
+
quill.setSelection(
|
|
320
|
+
delta.length() - (range?.length || 0),
|
|
321
|
+
Quill.sources.SILENT
|
|
322
|
+
);
|
|
323
|
+
quill.scrollSelectionIntoView();
|
|
324
|
+
} catch (e) {
|
|
325
|
+
console.error('Error while setting initial quill content', e);
|
|
326
|
+
return {ok: false, error: "Invalid initial content"};
|
|
327
|
+
}
|
|
328
|
+
return {ok: true};
|
|
312
329
|
}
|
|
313
330
|
|
|
314
331
|
onMounted(() => {
|
|
315
332
|
currentValue.value = props.record[props.column.name] || '';
|
|
316
333
|
quill = new Quill(editor.value as HTMLElement, quillOptions);
|
|
317
|
-
initValue(quill);
|
|
334
|
+
const initResult = initValue(quill);
|
|
335
|
+
if (!initResult.ok) {
|
|
336
|
+
adminforth.alert({
|
|
337
|
+
message: `Error while initializing rich text editor: ${initResult.error}`,
|
|
338
|
+
variant: 'danger',
|
|
339
|
+
});
|
|
340
|
+
wasQuillInitializedSuccessfully.value = false;
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
wasQuillInitializedSuccessfully.value = true;
|
|
318
344
|
lastText = quill.getText();
|
|
319
345
|
const linkButton = document.querySelector('.ql-link');
|
|
320
346
|
if (linkButton) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
v-if="wasQuillInitializedSuccessfully"
|
|
3
4
|
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500
|
|
4
5
|
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
|
|
5
6
|
dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 whitespace-normal af-quill-editor"
|
|
@@ -15,6 +16,13 @@
|
|
|
15
16
|
|
|
16
17
|
</div>
|
|
17
18
|
</div>
|
|
19
|
+
<Textarea
|
|
20
|
+
v-else
|
|
21
|
+
:modelValue="currentValue"
|
|
22
|
+
@update:modelValue="emit('update:value', $event);"
|
|
23
|
+
placeholder="Enter some text..."
|
|
24
|
+
class="w-64"
|
|
25
|
+
/>
|
|
18
26
|
|
|
19
27
|
|
|
20
28
|
</template>
|
|
@@ -30,8 +38,10 @@ import Quill from "quill";
|
|
|
30
38
|
import "quill/dist/quill.snow.css";
|
|
31
39
|
import QuillTableBetter from 'quill-table-better-yaroslav8765';
|
|
32
40
|
import 'quill-table-better-yaroslav8765/dist/quill-table-better.css';
|
|
41
|
+
import { Textarea } from '@/afcl'
|
|
33
42
|
|
|
34
43
|
import { useI18n } from 'vue-i18n';
|
|
44
|
+
import { ok } from "assert";
|
|
35
45
|
|
|
36
46
|
const { t } = useI18n();
|
|
37
47
|
function dbg(title: string,...args: any[]) {
|
|
@@ -144,6 +154,7 @@ const editorFocused = ref(false);
|
|
|
144
154
|
let lastText: string | null = null;
|
|
145
155
|
|
|
146
156
|
const imageProgress = ref(0);
|
|
157
|
+
const wasQuillInitializedSuccessfully = ref(true);
|
|
147
158
|
|
|
148
159
|
const selectedSymbolsCount = ref(0);
|
|
149
160
|
|
|
@@ -303,18 +314,33 @@ const quillOptions = {
|
|
|
303
314
|
const html = props.record[props.column.name] || '';
|
|
304
315
|
const delta = quill.clipboard.convert({ html });
|
|
305
316
|
const [range] = quill.selection.getRange();
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
try {
|
|
318
|
+
quill.updateContents(delta, Quill.sources.USER);
|
|
319
|
+
quill.setSelection(
|
|
320
|
+
delta.length() - (range?.length || 0),
|
|
321
|
+
Quill.sources.SILENT
|
|
322
|
+
);
|
|
323
|
+
quill.scrollSelectionIntoView();
|
|
324
|
+
} catch (e) {
|
|
325
|
+
console.error('Error while setting initial quill content', e);
|
|
326
|
+
return {ok: false, error: "Invalid initial content"};
|
|
327
|
+
}
|
|
328
|
+
return {ok: true};
|
|
312
329
|
}
|
|
313
330
|
|
|
314
331
|
onMounted(() => {
|
|
315
332
|
currentValue.value = props.record[props.column.name] || '';
|
|
316
333
|
quill = new Quill(editor.value as HTMLElement, quillOptions);
|
|
317
|
-
initValue(quill);
|
|
334
|
+
const initResult = initValue(quill);
|
|
335
|
+
if (!initResult.ok) {
|
|
336
|
+
adminforth.alert({
|
|
337
|
+
message: `Error while initializing rich text editor: ${initResult.error}`,
|
|
338
|
+
variant: 'danger',
|
|
339
|
+
});
|
|
340
|
+
wasQuillInitializedSuccessfully.value = false;
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
wasQuillInitializedSuccessfully.value = true;
|
|
318
344
|
lastText = quill.getText();
|
|
319
345
|
const linkButton = document.querySelector('.ql-link');
|
|
320
346
|
if (linkButton) {
|
package/dist/index.js
CHANGED
|
@@ -219,7 +219,7 @@ export default class RichEditorPlugin extends AdminForthPlugin {
|
|
|
219
219
|
method: 'POST',
|
|
220
220
|
path: `/plugin/${this.pluginInstanceId}/doComplete`,
|
|
221
221
|
handler: (_a) => __awaiter(this, [_a], void 0, function* ({ body, headers }) {
|
|
222
|
-
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m
|
|
222
|
+
var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
223
223
|
const { record } = body;
|
|
224
224
|
if (this.rateLimiter) {
|
|
225
225
|
// rate limit
|
|
@@ -249,17 +249,16 @@ export default class RichEditorPlugin extends AdminForthPlugin {
|
|
|
249
249
|
content = `Continue writing for text/string field "${fieldLabel}" in the table "${resLabel}"\n` +
|
|
250
250
|
(Object.keys(recordNoField).length > 0 ? `Record has values for the context: ${inputContext}\n` : '') +
|
|
251
251
|
`Current field value: ${currentVal}\n` +
|
|
252
|
-
"Don't talk to me. Just write text. No quotes. Don't repeat current field value, just write completion\n";
|
|
252
|
+
"Don't talk to me. Just write text. No quotes. Don't repeat current field value, just write completion. Stop generating when you finish the sentence. DO NOT GENERATE AFTER YOU GENERATED FIRST\".\" \n";
|
|
253
253
|
}
|
|
254
254
|
else {
|
|
255
255
|
content = `Fill text/string field "${fieldLabel}" in the table "${resLabel}"\n` +
|
|
256
256
|
(Object.keys(recordNoField).length > 0 ? `Record has values for the context: ${inputContext}\n` : '') +
|
|
257
|
-
"Be short, clear and precise. No quotes. Don't talk to me. Just write text\n";
|
|
257
|
+
"Be short, clear and precise. No quotes. Don't talk to me. Just write text. Stop generating when you finish the sentence. DO NOT GENERATE AFTER YOU GENERATED FIRST\".\" \n";
|
|
258
258
|
}
|
|
259
259
|
process.env.HEAVY_DEBUG && console.log('🪲 OpenAI Prompt 🧠', content);
|
|
260
|
-
const { content: respContent
|
|
261
|
-
|
|
262
|
-
let suggestion = respContent + (finishReason === 'stop' ? (stop[0] === '.' && stop.length === 1 ? '. ' : '') : '');
|
|
260
|
+
const { content: respContent } = yield this.options.completion.adapter.complete(content, [], (_m = (_l = this.options.completion) === null || _l === void 0 ? void 0 : _l.expert) === null || _m === void 0 ? void 0 : _m.maxTokens);
|
|
261
|
+
let suggestion = respContent;
|
|
263
262
|
if (suggestion.startsWith(currentVal)) {
|
|
264
263
|
suggestion = suggestion.slice(currentVal.length);
|
|
265
264
|
}
|
package/index.ts
CHANGED
|
@@ -315,23 +315,17 @@ export default class RichEditorPlugin extends AdminForthPlugin {
|
|
|
315
315
|
content = `Continue writing for text/string field "${fieldLabel}" in the table "${resLabel}"\n` +
|
|
316
316
|
(Object.keys(recordNoField).length > 0 ? `Record has values for the context: ${inputContext}\n` : '') +
|
|
317
317
|
`Current field value: ${currentVal}\n` +
|
|
318
|
-
"Don't talk to me. Just write text. No quotes. Don't repeat current field value, just write completion\n";
|
|
318
|
+
"Don't talk to me. Just write text. No quotes. Don't repeat current field value, just write completion. Stop generating when you finish the sentence. DO NOT GENERATE AFTER YOU GENERATED FIRST\".\" \n";
|
|
319
319
|
|
|
320
320
|
} else {
|
|
321
321
|
content = `Fill text/string field "${fieldLabel}" in the table "${resLabel}"\n` +
|
|
322
322
|
(Object.keys(recordNoField).length > 0 ? `Record has values for the context: ${inputContext}\n` : '') +
|
|
323
|
-
"Be short, clear and precise. No quotes. Don't talk to me. Just write text\n";
|
|
323
|
+
"Be short, clear and precise. No quotes. Don't talk to me. Just write text. Stop generating when you finish the sentence. DO NOT GENERATE AFTER YOU GENERATED FIRST\".\" \n";
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
process.env.HEAVY_DEBUG && console.log('🪲 OpenAI Prompt 🧠', content);
|
|
327
|
-
const { content: respContent
|
|
328
|
-
|
|
329
|
-
let suggestion = respContent + (
|
|
330
|
-
finishReason === 'stop' ? (
|
|
331
|
-
stop[0] === '.' && stop.length === 1 ? '. ' : ''
|
|
332
|
-
) : ''
|
|
333
|
-
);
|
|
334
|
-
|
|
327
|
+
const { content: respContent } = await this.options.completion.adapter.complete(content, [], this.options.completion?.expert?.maxTokens);
|
|
328
|
+
let suggestion = respContent
|
|
335
329
|
if (suggestion.startsWith(currentVal)) {
|
|
336
330
|
suggestion = suggestion.slice(currentVal.length);
|
|
337
331
|
}
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -79,11 +79,6 @@ export interface PluginOptions {
|
|
|
79
79
|
*/
|
|
80
80
|
debounceTime?: number;
|
|
81
81
|
|
|
82
|
-
/**
|
|
83
|
-
* Stop completion on these characters. Default is ['.']
|
|
84
|
-
*/
|
|
85
|
-
stop?: string[];
|
|
86
|
-
|
|
87
82
|
/**
|
|
88
83
|
* When completion is made, this plugin passes non-empty fields of the record to the LLM model for record context understanding.
|
|
89
84
|
*/
|