Update command bar to accomdate more AI options

This commit is contained in:
Muhsin Keloth
2023-07-04 15:28:42 +05:30
parent 3c4514c9f7
commit 146bdd2f83
7 changed files with 189 additions and 5 deletions
@@ -1,7 +1,16 @@
<template>
<div v-if="isAIIntegrationEnabled" class="position-relative">
<woot-button
v-tooltip.top-end="$t('INTEGRATION_SETTINGS.OPEN_AI.AI_ASSIST')"
icon="wand"
color-scheme="secondary"
variant="smooth"
size="small"
@click="openAIAssist"
/>
<div v-if="!message">
<woot-button
<!-- <woot-button
v-if="isPrivateNote"
v-tooltip.top-end="$t('INTEGRATION_SETTINGS.OPEN_AI.SUMMARY_TITLE')"
icon="book-pulse"
@@ -20,18 +29,19 @@
size="small"
:is-loading="uiFlags.reply_suggestion"
@click="processEvent('reply_suggestion')"
/>
/> -->
</div>
<div v-else>
<woot-button
<!-- <woot-button
v-tooltip.top-end="$t('INTEGRATION_SETTINGS.OPEN_AI.TITLE')"
icon="text-grammar-wand"
color-scheme="secondary"
variant="smooth"
size="small"
@click="toggleDropdown"
/>
/> -->
<div
v-if="showDropdown"
v-on-clickaway="closeDropdown"
@@ -75,6 +85,7 @@ import { mixin as clickaway } from 'vue-clickaway';
import OpenAPI from 'dashboard/api/integrations/openapi';
import alertMixin from 'shared/mixins/alertMixin';
import { OPEN_AI_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
import { CMD_AI_ASSIST } from '../../routes/dashboard/commands/commandBarBusEvents';
export default {
mixins: [alertMixin, clickaway],
@@ -134,11 +145,24 @@ export default {
},
},
mounted() {
bus.$on(CMD_AI_ASSIST, this.onAIAssist);
if (!this.appIntegrations.length) {
this.$store.dispatch('integrations/get');
}
},
destroyed() {
bus.$off(CMD_AI_ASSIST, this.onAIAssist);
},
methods: {
openAIAssist() {
const ninja = document.querySelector('ninja-keys');
ninja.open({ parent: 'ai_assist' });
},
onAIAssist() {
// this.$track(OPEN_AI_EVENTS.AI_ASSIST);
// this.openAIAssist();
// console.log('onAIAssist', action);
},
toggleDropdown() {
this.showDropdown = !this.showDropdown;
},
@@ -0,0 +1,75 @@
<template>
<div class="column">
<woot-modal-header :header-title="$t('CONVERSATION.CUSTOM_SNOOZE.TITLE')" />
<form class="row modal-content" @submit.prevent="chooseTime">
<date-picker
v-model="snoozeTime"
type="datetime"
inline
:lang="lang"
:disabled-date="disabledDate"
:disabled-time="disabledTime"
:popup-style="{ width: '100%' }"
/>
<div class="modal-footer justify-content-end w-full">
<woot-button variant="clear" @click.prevent="onClose">
{{ this.$t('CONVERSATION.CUSTOM_SNOOZE.CANCEL') }}
</woot-button>
<woot-button>
{{ this.$t('CONVERSATION.CUSTOM_SNOOZE.APPLY') }}
</woot-button>
</div>
</form>
</div>
</template>
<script>
import DatePicker from 'vue2-datepicker';
export default {
components: {
DatePicker,
},
data() {
return {
snoozeTime: null,
lang: {
days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
yearFormat: 'YYYY',
monthFormat: 'MMMM',
},
};
},
methods: {
onClose() {
this.$emit('close');
},
chooseTime() {
this.$emit('choose-time', this.snoozeTime);
},
disabledDate(date) {
// Disable all the previous dates
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
return date < yesterday;
},
disabledTime(date) {
// Allow only time after 1 hour
const now = new Date();
now.setHours(now.getHours() + 1);
return date < now;
},
},
};
</script>
<style lang="scss" scoped>
.modal-footer {
padding: var(--space-two);
}
.modal-content {
padding: var(--space-small) var(--space-two) var(--space-zero);
}
</style>
@@ -110,7 +110,8 @@
"SNOOZE_CONVERSATION": "Snooze Conversation",
"ADD_LABEL": "Add label to the conversation",
"REMOVE_LABEL": "Remove label from the conversation",
"SETTINGS": "Settings"
"SETTINGS": "Settings",
"AI_ASSIST": "AI Assist"
},
"COMMANDS": {
"GO_TO_CONVERSATION_DASHBOARD": "Go to Conversation Dashboard",
@@ -132,6 +133,7 @@
"GO_TO_NOTIFICATIONS": "Go to Notifications",
"ADD_LABELS_TO_CONVERSATION": "Add label to the conversation",
"ASSIGN_AN_AGENT": "Assign an agent",
"AI_ASSIST": "AI Assist",
"ASSIGN_PRIORITY": "Assign priority",
"ASSIGN_A_TEAM": "Assign a team",
"MUTE_CONVERSATION": "Mute conversation",
@@ -83,6 +83,7 @@
"CREATE_ERROR": "There was an error creating a meeting link, please try again"
},
"OPEN_AI": {
"AI_ASSIST": "AI Assist",
"TITLE": "Improve With AI",
"SUMMARY_TITLE": "Summary with AI",
"REPLY_TITLE": "Reply suggestion with AI",
@@ -58,3 +58,6 @@ export const ICON_PRIORITY_NONE = `<svg role="img" class="ninja-icon ninja-icon-
<rect width="24" height="24" fill="#F1F5F8"/>
<path d="M13.5686 8L11.1579 16.9562H10L12.4107 8H13.5686Z" fill="#446888"/>
</svg>`;
export const ICON_AI_ASSIST = `<svg role="img" class="ninja-icon ninja-icon--fluent" width="18" height="18" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m13.314 7.565l-.136.126l-10.48 10.488a2.27 2.27 0 0 0 3.211 3.208L16.388 10.9a2.251 2.251 0 0 0-.001-3.182l-.157-.146a2.25 2.25 0 0 0-2.916-.007Zm-.848 2.961l1.088 1.088l-8.706 8.713a.77.77 0 1 1-1.089-1.088l8.707-8.713Zm4.386 4.48L16.75 15a.75.75 0 0 0-.743.648L16 15.75v.75h-.75a.75.75 0 0 0-.743.648l-.007.102c0 .38.282.694.648.743l.102.007H16v.75c0 .38.282.694.648.743l.102.007a.75.75 0 0 0 .743-.648l.007-.102V18h.75a.75.75 0 0 0 .743-.648L19 17.25a.75.75 0 0 0-.648-.743l-.102-.007h-.75v-.75a.75.75 0 0 0-.648-.743L16.75 15l.102.007Zm-1.553-6.254l.027.027a.751.751 0 0 1 0 1.061l-.711.713l-1.089-1.089l.73-.73a.75.75 0 0 1 1.043.018ZM6.852 5.007L6.75 5a.75.75 0 0 0-.743.648L6 5.75v.75h-.75a.75.75 0 0 0-.743.648L4.5 7.25c0 .38.282.693.648.743L5.25 8H6v.75c0 .38.282.693.648.743l.102.007a.75.75 0 0 0 .743-.648L7.5 8.75V8h.75a.75.75 0 0 0 .743-.648L9 7.25a.75.75 0 0 0-.648-.743L8.25 6.5H7.5v-.75a.75.75 0 0 0-.648-.743L6.75 5l.102.007Zm12-2L18.75 3a.75.75 0 0 0-.743.648L18 3.75v.75h-.75a.75.75 0 0 0-.743.648l-.007.102c0 .38.282.693.648.743L17.25 6H18v.75c0 .38.282.693.648.743l.102.007a.75.75 0 0 0 .743-.648l.007-.102V6h.75a.75.75 0 0 0 .743-.648L21 5.25a.75.75 0 0 0-.648-.743L20.25 4.5h-.75v-.75a.75.75 0 0 0-.648-.743L18.75 3l.102.007Z" fill="currentColor"/></svg>`;
export const ICON_AI_SUMMARY = `<svg role="img" class="ninja-icon ninja-icon--fluent" width="18" height="18" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M4 4.5A2.5 2.5 0 0 1 6.5 2H18a2.5 2.5 0 0 1 2.5 2.5v14.25a.75.75 0 0 1-.75.75H5.5a1 1 0 0 0 1 1h13.25a.75.75 0 0 1 0 1.5H6.5A2.5 2.5 0 0 1 4 19.5v-15ZM5.5 18H19V4.5a1 1 0 0 0-1-1H6.5a1 1 0 0 0-1 1V18Z" fill="currentColor"/></svg>`;
@@ -14,3 +14,4 @@ export const CMD_TOGGLE_CONTACT_SIDEBAR = 'CMD_TOGGLE_CONTACT_SIDEBAR';
export const CMD_REOPEN_CONVERSATION = 'CMD_REOPEN_CONVERSATION';
export const CMD_RESOLVE_CONVERSATION = 'CMD_RESOLVE_CONVERSATION';
export const CMD_SNOOZE_CONVERSATION = 'CMD_SNOOZE_CONVERSATION';
export const CMD_AI_ASSIST = 'CMD_AI_ASSIST';
@@ -1,6 +1,10 @@
import { mapGetters } from 'vuex';
import wootConstants from 'dashboard/constants/globals';
import { LocalStorage } from 'shared/helpers/localStorage';
import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage';
import {
CMD_AI_ASSIST,
CMD_MUTE_CONVERSATION,
CMD_REOPEN_CONVERSATION,
CMD_RESOLVE_CONVERSATION,
@@ -26,6 +30,8 @@ import {
ICON_PRIORITY_LOW,
ICON_PRIORITY_MEDIUM,
ICON_PRIORITY_NONE,
ICON_AI_ASSIST,
ICON_AI_SUMMARY,
} from './CommandBarIcons';
const SNOOZE_OPTIONS = wootConstants.SNOOZE_OPTIONS;
@@ -337,6 +343,77 @@ export default {
]);
},
AIAssistActions() {
const savedDraftMessages =
LocalStorage.get(LOCAL_STORAGE_KEYS.DRAFT_MESSAGES) || {};
const replyType = 'REPLY';
const key = `draft-${this.currentChat.id}-${replyType}`;
const message = `${savedDraftMessages[key] || ''}`;
let aiOptions = [];
if (!message) {
aiOptions = [
{
label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.REPLY_TITLE'),
key: 'reply_suggestion',
icon: ICON_AI_ASSIST,
},
{
label: this.$t('INTEGRATION_SETTINGS.OPEN_AI.SUMMARY_TITLE'),
key: 'summarize',
icon: ICON_AI_SUMMARY,
},
];
} else {
aiOptions = [
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.NONE'),
key: null,
icon: ICON_PRIORITY_NONE,
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.URGENT'),
key: 'urgent',
icon: ICON_PRIORITY_URGENT,
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.HIGH'),
key: 'high',
icon: ICON_PRIORITY_HIGH,
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.MEDIUM'),
key: 'medium',
icon: ICON_PRIORITY_MEDIUM,
},
{
label: this.$t('CONVERSATION.PRIORITY.OPTIONS.LOW'),
key: 'low',
icon: ICON_PRIORITY_LOW,
},
];
}
const options = aiOptions.map(item => ({
id: `ai-assist-${item.key}`,
title: item.label,
parent: 'ai_assist',
section: this.$t('COMMAND_BAR.SECTIONS.AI_ASSIST'),
priority: item,
icon: item.icon,
handler: () => bus.$emit(CMD_AI_ASSIST, item.key),
}));
return [
{
id: 'ai_assist',
title: this.$t('COMMAND_BAR.COMMANDS.AI_ASSIST'),
section: this.$t('COMMAND_BAR.SECTIONS.AI_ASSIST'),
icon: ICON_AI_ASSIST,
children: options.map(option => option.id),
},
...options,
];
},
conversationHotKeys() {
if (isAConversationRoute(this.$route.name)) {
return [
@@ -346,6 +423,7 @@ export default {
...this.assignTeamActions,
...this.labelActions,
...this.assignPriorityActions,
...this.AIAssistActions,
];
}