Skip to content

Commit 1ac2484

Browse files
committed
feat: enhance completion input with loading state and approval functionality
1 parent 7761fd7 commit 1ac2484

File tree

3 files changed

+194
-148
lines changed

3 files changed

+194
-148
lines changed

custom/completionInput.vue

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,57 @@
11
<template>
2-
3-
<SuggestionInput
4-
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500
5-
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
6-
dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 whitespace-normal"
2+
<div class="flex bg-gray-50 border border-gray-300 rounded-lg focus:ring-blue-500
3+
focus:border-blue-500 w-full p-2.5 dark:bg-gray-700 dark:border-gray-600
4+
dark:focus:ring-blue-500 dark:focus:border-blue-500 relative max-w-full">
5+
<SuggestionInput
6+
ref="suggestionInputRef"
7+
class="w-full !border-none text-gray-900 text-sm dark:placeholder-gray-400 dark:text-white whitespace-normal mr-14"
78
v-model="currentValue"
89
:type="column.type"
910
:completionRequest="complete"
1011
:debounceTime="meta.debounceTime"
1112
/>
13+
<div class="absolute right-2 bottom-1">
14+
<Tooltip v-if="isUntouched">
15+
<button
16+
@click.stop="handleFocus"
17+
@mousedown.prevent
18+
class="text-white bg-gradient-to-r from-purple-500 via-purple-600 to-purple-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-purple-300 dark:focus:ring-purple-800
19+
font-medium rounded-lg text-sm w-6 h-6 flex items-center justify-center">
20+
<IconMagic class="w-4 h-4"/>
21+
</button>
22+
<template #tooltip>
23+
Start completion
24+
</template>
25+
</Tooltip>
26+
27+
<Spinner v-else-if="isLoading" class="w-6 h-6" lightFill="#000000" darkFill="#ffffff" />
28+
<Tooltip v-else>
29+
<button
30+
@click.stop="approveCompletion"
31+
@mousedown.prevent
32+
class="text-white bg-gradient-to-r from-purple-500 via-purple-600 to-purple-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-purple-300 dark:focus:ring-purple-800
33+
font-medium rounded-lg text-xs w-14 h-6 flex items-center justify-center">
34+
<IconArrowRightThin class="w-5 h-5"/>
35+
<span class="scale-75 border border-white rounded-sm px-0.5 bg-white/25">TAB</span>
36+
</button>
37+
<template #tooltip>
38+
Approve completion
39+
</template>
40+
</Tooltip>
41+
42+
</div>
43+
</div>
1244
</template>
1345

1446
<script setup lang="ts">
1547
import { ref, onMounted, watch, Ref } from 'vue';
1648
import { callAdminForthApi } from '@/utils';
1749
import { AdminForthColumnCommon } from '@/types/Common';
50+
import { Spinner, Tooltip } from '@/afcl';
51+
import { IconMagic, IconCheck, IconArrowRightThin } from '@iconify-prerendered/vue-mdi';
1852
import SuggestionInput from 'vue-suggestion-input';
1953
import 'vue-suggestion-input/dist/style.css';
2054
21-
2255
const props = defineProps<{
2356
column: AdminForthColumnCommon,
2457
record: any,
@@ -29,7 +62,10 @@ const emit = defineEmits([
2962
'update:value',
3063
]);
3164
65+
const isLoading = ref<boolean>(false);
66+
const isUntouched = ref<boolean>(true);
3267
const currentValue: Ref<string> = ref('');
68+
const suggestionInputRef = ref<InstanceType<typeof SuggestionInput> | null>(null);
3369
3470
onMounted(() => {
3571
currentValue.value = props.record[props.column.name] || '';
@@ -44,6 +80,8 @@ watch(() => props.record, (value) => {
4480
});
4581
4682
async function complete(textBeforeCursor: string) {
83+
isLoading.value = true;
84+
isUntouched.value = false;
4785
const res = await callAdminForthApi({
4886
path: `/plugin/${props.meta.pluginInstanceId}/doComplete`,
4987
method: 'POST',
@@ -52,9 +90,27 @@ async function complete(textBeforeCursor: string) {
5290
},
5391
});
5492
93+
isLoading.value = false;
94+
5595
return res.completion;
5696
}
5797
98+
const approveCompletion = async () => {
99+
if (suggestionInputRef.value) {
100+
console.log('✋ approveCompletion', suggestionInputRef.value);
101+
await suggestionInputRef.value.approveCompletion('all');
102+
}
103+
}
104+
105+
function handleFocus() {
106+
if (suggestionInputRef.value) {
107+
const editor = suggestionInputRef.value.$el.querySelector('.ql-editor');
108+
if (editor) {
109+
editor.focus();
110+
}
111+
}
112+
}
113+
58114
</script>
59115

60116
<style>

0 commit comments

Comments
 (0)