Compare commits

...
Author SHA1 Message Date
Shivam Mishra 0eaab0a9ae feat(ux): accept and send action 2026-01-22 18:00:19 +05:30
4 changed files with 105 additions and 13 deletions
@@ -1,8 +1,14 @@
<script setup>
import { computed } from 'vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useToggle } from '@vueuse/core';
import { useKbd } from 'dashboard/composables/utils/useKbd';
import { LocalStorage } from 'shared/helpers/localStorage';
import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage';
import NextButton from 'dashboard/components-next/button/Button.vue';
import ButtonGroup from 'dashboard/components-next/buttonGroup/ButtonGroup.vue';
import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.vue';
defineProps({
isGeneratingContent: {
@@ -11,8 +17,22 @@ defineProps({
},
});
const emit = defineEmits(['submit', 'cancel']);
const emit = defineEmits(['submit', 'cancel', 'acceptAndSend']);
const ACCEPT_ACTIONS = {
ACCEPT: 'accept',
ACCEPT_AND_SEND: 'accept_and_send',
};
const { t } = useI18n();
const selectedAction = ref(ACCEPT_ACTIONS.ACCEPT);
const arrowDownButtonRef = ref(null);
const [showActionsDropdown, toggleDropdown] = useToggle();
const closeDropdown = () => toggleDropdown(false);
const openDropdown = () => toggleDropdown(true);
const handleCancel = () => {
emit('cancel');
};
@@ -20,12 +40,50 @@ const handleCancel = () => {
const shortcutKey = useKbd(['$mod', '+', 'enter']);
const acceptLabel = computed(() => {
return `${t('GENERAL.ACCEPT')} (${shortcutKey.value})`;
const label =
selectedAction.value === ACCEPT_ACTIONS.ACCEPT
? t('GENERAL.ACCEPT')
: t('GENERAL.ACCEPT_AND_SEND');
return `${label} (${shortcutKey.value})`;
});
const handleSubmit = () => {
emit('submit');
if (selectedAction.value === ACCEPT_ACTIONS.ACCEPT_AND_SEND) {
emit('acceptAndSend');
} else {
emit('submit');
}
};
const menuItems = computed(() => [
{
label: t('GENERAL.ACCEPT_SUGGESTION'),
action: ACCEPT_ACTIONS.ACCEPT,
value: ACCEPT_ACTIONS.ACCEPT,
disabled: selectedAction.value === ACCEPT_ACTIONS.ACCEPT,
},
{
label: t('GENERAL.ACCEPT_AND_SEND'),
action: ACCEPT_ACTIONS.ACCEPT_AND_SEND,
value: ACCEPT_ACTIONS.ACCEPT_AND_SEND,
disabled: selectedAction.value === ACCEPT_ACTIONS.ACCEPT_AND_SEND,
},
]);
const handleAction = ({ action }) => {
selectedAction.value = action;
LocalStorage.set(LOCAL_STORAGE_KEYS.COPILOT_ACCEPT_ACTION, action);
closeDropdown();
};
onMounted(() => {
const savedAction = LocalStorage.get(
LOCAL_STORAGE_KEYS.COPILOT_ACCEPT_ACTION
);
if (savedAction && Object.values(ACCEPT_ACTIONS).includes(savedAction)) {
selectedAction.value = savedAction;
}
});
</script>
<template>
@@ -39,13 +97,37 @@ const handleSubmit = () => {
:disabled="isGeneratingContent"
@click="handleCancel"
/>
<NextButton
:label="acceptLabel"
class="bg-n-iris-9 text-white"
solid
sm
:disabled="isGeneratingContent"
@click="handleSubmit"
/>
<div class="relative flex items-center justify-end">
<ButtonGroup
class="rounded-lg shadow outline-1 outline flex-shrink-0 outline-n-container"
>
<NextButton
:label="acceptLabel"
class="bg-n-iris-9 text-white ltr:rounded-r-none rtl:rounded-l-none !outline-0"
solid
sm
no-animation
:disabled="isGeneratingContent"
@click="handleSubmit"
/>
<NextButton
ref="arrowDownButtonRef"
icon="i-lucide-chevron-down"
:disabled="isGeneratingContent"
size="sm"
no-animation
class="bg-n-iris-9 text-white ltr:rounded-l-none rtl:rounded-r-none !outline-0"
trailing-icon
@click="openDropdown"
/>
</ButtonGroup>
<DropdownMenu
v-if="showActionsDropdown"
v-on-clickaway="closeDropdown"
:menu-items="menuItems"
class="bottom-full mb-0.5 start-0 xl:start-auto xl:end-0"
@action="handleAction"
/>
</div>
</div>
</template>
@@ -1121,6 +1121,12 @@ export default {
onSubmitCopilotReply() {
this.message = this.copilot.accept();
},
onAcceptAndSendCopilotReply() {
this.message = this.copilot.accept();
this.$nextTick(() => {
this.onSendReply();
});
},
},
};
</script>
@@ -1271,6 +1277,7 @@ export default {
key="copilot-bottom-panel"
:is-generating-content="copilot.isButtonDisabled.value"
@submit="onSubmitCopilotReply"
@accept-and-send="onAcceptAndSendCopilotReply"
@cancel="copilot.toggleEditor"
/>
<ReplyBottomPanel
@@ -6,4 +6,5 @@ export const LOCAL_STORAGE_KEYS = {
DISMISSED_LABEL_SUGGESTIONS: 'labelSuggestionsDismissed',
MESSAGE_REPLY_TO: 'messageReplyTo',
RECENT_SEARCHES: 'recentSearches',
COPILOT_ACCEPT_ACTION: 'copilotAcceptAction',
};
@@ -9,6 +9,8 @@
"BETA": "Beta",
"BETA_DESCRIPTION": "This feature is in beta and may change as we improve it.",
"ACCEPT": "Accept",
"ACCEPT_SUGGESTION": "Accept Suggestion",
"ACCEPT_AND_SEND": "Accept and Send",
"DISCARD": "Discard",
"PREFERRED": "Preferred"
}