44 dark:focus:ring-blue-500 dark:focus:border-blue-500 relative max-w-full" >
55 <SuggestionInput
66 ref =" suggestionInputRef"
7- class =" w-full !border-none text-gray-900 text-sm dark:placeholder-gray-400 dark:text-white whitespace-normal mr-14 "
7+ class =" w-full !border-none text-gray-900 text-sm dark:placeholder-gray-400 dark:text-white whitespace-normal mr-28 "
88 v-model =" currentValue"
99 :type =" column.type"
1010 :completionRequest =" complete"
1111 :debounceTime =" meta.debounceTime"
12+ @completion-approved =" handleCompletionApproved"
1213 />
1314 <div class =" absolute right-2 bottom-1" >
1415 <Tooltip v-if =" isUntouched || (!currentValue.trim() && !isFocused)" >
2930 <button
3031 @click.stop =" approveCompletion"
3132 @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 >
33+ :class =" [
34+ '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',
35+ 'font-medium rounded-lg text-xs flex items-center justify-center py-1 px-1 ',
36+ buttonText === approveCompletionValue ? 'w-16' : 'w-18'
37+ ]" >
38+ <div
39+ class =" flex items-center justify-center"
40+ v-if =" buttonText === approveCompletionValue"
41+ >
42+ <IconArrowRightThin class =" mt-0.5 w-5 h-5 text-white" />
43+ <span class =" ml-1 px-1 h-4 flex items-center justify-center rounded border bg-white text-black text-[10px] font-mono shadow-inner shadow-sm border-gray-300 dark:bg-gray-700 dark:text-white dark:border-gray-500" >
44+ <p class =" mt-0.5" >Tab</p >
45+ </span >
46+ </div >
47+ <div
48+ class =" flex items-center justify-center"
49+ v-else-if =" buttonText === approveNextWordValue"
50+ >
51+ <IconArrowRightThin class =" mt-0.5 w-5 h-5 text-white" />
52+ <span class =" ml-1 px-1 h-4 flex items-center justify-center rounded border bg-white text-black text-[10px] font-mono shadow-inner shadow-sm border-gray-300 dark:bg-gray-700 dark:text-white dark:border-gray-500" >
53+ <p class =" mt-0.5" >Ctrl</p >
54+ </span >
55+ <span class =" ml-1 text-white" >+</span >
56+ <span class =" ml-1 px-1 h-4 flex items-center justify-center rounded border bg-white text-black text-[10px] font-mono shadow-inner shadow-sm border-gray-300 dark:bg-gray-700 dark:text-white dark:border-gray-500" >
57+ <IconArrowRightThin class =" w-3.5 h-3.5" />
58+ </span >
59+ </div >
3660 </button >
3761 <template #tooltip >
38- {{ $t('Approve completion' ) }}
62+ {{ $t(tooltipText ) }}
3963 </template >
4064 </Tooltip >
4165
4468</template >
4569
4670<script setup lang="ts">
47- import { ref , onMounted , watch , Ref } from ' vue' ;
71+ import { ref , onMounted , watch , Ref , computed } from ' vue' ;
4872import { callAdminForthApi } from ' @/utils' ;
4973import { AdminForthColumnCommon } from ' @/types/Common' ;
5074import { Spinner , Tooltip } from ' @/afcl' ;
@@ -61,15 +85,33 @@ const props = defineProps<{
6185const emit = defineEmits ([
6286 ' update:value' ,
6387]);
64-
88+ const approveCompletionValue: string = ' TAB' ;
89+ const approveNextWordValue: string = ' CTRL + ->'
6590const isLoading = ref <boolean >(false );
6691const isUntouched = ref <boolean >(true );
6792const isFocused = ref <boolean >(false );
6893const currentValue: Ref <string > = ref (' ' );
6994const suggestionInputRef = ref <InstanceType <typeof SuggestionInput > | null >(null );
95+ const buttonText = ref <string >(approveCompletionValue );
96+
97+ const tooltipText = computed (() =>
98+ buttonText .value === approveCompletionValue ? ' Approve completion' : ' Approve next word'
99+ );
100+
101+ function handleCompletionApproved(type : ' all' | ' word' ) {
102+ if (buttonText .value === approveCompletionValue && type === ' all' ) {
103+ buttonText .value = approveNextWordValue ;
104+ } else if (buttonText .value === approveNextWordValue && type === ' word' ) {
105+ buttonText .value = approveCompletionValue ;
106+ }
107+ }
70108
71109onMounted (() => {
72- currentValue .value = props .record [props .column .name ] || ' ' ;
110+ const value = props .record [props .column .name ] || ' ' ;
111+ currentValue .value = value ;
112+ if (value .trim ()) {
113+ isUntouched .value = false ;
114+ }
73115 if (suggestionInputRef .value ) {
74116 const editor = suggestionInputRef .value .$el .querySelector (' .ql-editor' );
75117 if (editor ) {
@@ -84,7 +126,11 @@ watch(() => currentValue.value, (value) => {
84126});
85127
86128watch (() => props .record , (value ) => {
87- currentValue .value = value [props .column .name ] || ' ' ;
129+ const val = value [props .column .name ] || ' ' ;
130+ currentValue .value = val ;
131+ if (val .trim ()) {
132+ isUntouched .value = false ;
133+ }
88134});
89135
90136async function complete(textBeforeCursor : string ) {
@@ -105,8 +151,13 @@ async function complete(textBeforeCursor: string) {
105151
106152const approveCompletion = async () => {
107153 if (suggestionInputRef .value ) {
108- await suggestionInputRef .value .approveCompletion (' all' );
154+ if ( buttonText .value === approveCompletionValue ) {
155+ await suggestionInputRef .value .approveCompletion (' all' );
156+ } else {
157+ await suggestionInputRef .value .approveCompletion (' word' );
158+ }
109159 }
160+ buttonText .value === approveCompletionValue ? buttonText .value = approveNextWordValue : buttonText .value = approveCompletionValue ;
110161}
111162
112163function handleFocus() {
0 commit comments