Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d61eed7169 | ||
|
|
464e0a5d35 | ||
|
|
146bdd2f83 |
@@ -1,7 +1,25 @@
|
||||
<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"
|
||||
/>
|
||||
|
||||
<!-- <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="!message">
|
||||
<woot-button
|
||||
<!-- <woot-button
|
||||
v-if="isPrivateNote"
|
||||
v-tooltip.top-end="$t('INTEGRATION_SETTINGS.OPEN_AI.SUMMARY_TITLE')"
|
||||
icon="book-pulse"
|
||||
@@ -20,53 +38,62 @@
|
||||
size="small"
|
||||
:is-loading="uiFlags.reply_suggestion"
|
||||
@click="processEvent('reply_suggestion')"
|
||||
/>
|
||||
/> -->
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<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"
|
||||
class="dropdown-pane dropdown-pane--open ai-modal"
|
||||
>
|
||||
<h4 class="sub-block-title margin-top-1">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.TITLE') }}
|
||||
</h4>
|
||||
<p>
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.SUBTITLE') }}
|
||||
</p>
|
||||
<label>
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.TONE.TITLE') }}
|
||||
</label>
|
||||
<div class="tone__item">
|
||||
<select v-model="activeTone" class="status--filter small">
|
||||
<option v-for="tone in tones" :key="tone.key" :value="tone.key">
|
||||
{{ tone.value }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-footer flex-container align-right">
|
||||
<woot-button variant="clear" size="small" @click="closeDropdown">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.BUTTONS.CANCEL') }}
|
||||
</woot-button>
|
||||
<woot-button
|
||||
:is-loading="uiFlags.rephrase"
|
||||
size="small"
|
||||
@click="processEvent('rephrase')"
|
||||
>
|
||||
{{ buttonText }}
|
||||
</woot-button>
|
||||
</div>
|
||||
<div
|
||||
v-if="showDropdown"
|
||||
v-on-clickaway="closeDropdown"
|
||||
class="dropdown-pane dropdown-pane--open ai-modal"
|
||||
>
|
||||
<h4 class="sub-block-title margin-top-1">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.TITLE') }}
|
||||
</h4>
|
||||
<p>
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.SUBTITLE') }}
|
||||
</p>
|
||||
<label>
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.TONE.TITLE') }}
|
||||
</label>
|
||||
<div class="tone__item">
|
||||
<select v-model="activeTone" class="status--filter small">
|
||||
<option v-for="tone in tones" :key="tone.key" :value="tone.key">
|
||||
{{ tone.value }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="modal-footer flex-container align-right">
|
||||
<woot-button variant="clear" size="small" @click="closeDropdown">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.BUTTONS.CANCEL') }}
|
||||
</woot-button>
|
||||
<woot-button
|
||||
:is-loading="uiFlags.rephrase"
|
||||
size="small"
|
||||
@click="processEvent('rephrase')"
|
||||
>
|
||||
{{ buttonText }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<woot-modal
|
||||
:show.sync="showAIAssistanceModal"
|
||||
:on-close="hideAIAssistanceModal"
|
||||
>
|
||||
<AIAssistanceModal
|
||||
@apply-text="insertText"
|
||||
@close="hideAIAssistanceModal"
|
||||
/>
|
||||
</woot-modal>
|
||||
<woot-modal
|
||||
:show.sync="showAIAssistanceReply"
|
||||
:on-close="hideAIAssistanceReplyModal"
|
||||
>
|
||||
<AIAssistanceReply
|
||||
@apply-text="insertText"
|
||||
@close="hideAIAssistanceReplyModal"
|
||||
/>
|
||||
</woot-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -75,8 +102,15 @@ 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';
|
||||
import AIAssistanceModal from './AIAssistanceModal.vue';
|
||||
import AIAssistanceReply from './AIAssistanceReply.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AIAssistanceModal,
|
||||
AIAssistanceReply,
|
||||
},
|
||||
mixins: [alertMixin, clickaway],
|
||||
props: {
|
||||
conversationId: {
|
||||
@@ -94,6 +128,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAIAssistanceModal: false,
|
||||
showAIAssistanceReply: false,
|
||||
uiFlags: {
|
||||
rephrase: false,
|
||||
reply_suggestion: false,
|
||||
@@ -134,11 +170,29 @@ 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: {
|
||||
hideAIAssistanceReplyModal() {
|
||||
this.showAIAssistanceReply = false;
|
||||
},
|
||||
hideAIAssistanceModal() {
|
||||
this.showAIAssistanceModal = false;
|
||||
},
|
||||
openAIAssist() {
|
||||
const ninja = document.querySelector('ninja-keys');
|
||||
ninja.open({ parent: 'ai_assist' });
|
||||
},
|
||||
onAIAssist() {
|
||||
// this.showAIAssistanceModal = true;
|
||||
this.showAIAssistanceReply = true;
|
||||
},
|
||||
toggleDropdown() {
|
||||
this.showDropdown = !this.showDropdown;
|
||||
},
|
||||
@@ -154,6 +208,11 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
insertText(message) {
|
||||
console.log('message', message);
|
||||
|
||||
this.$emit('replace-text', message);
|
||||
},
|
||||
async processEvent(type = 'rephrase') {
|
||||
this.uiFlags[type] = true;
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div class="column">
|
||||
<woot-modal-header header-title="Rephrase the content" />
|
||||
<form class="row modal-content" @submit.prevent="chooseTime">
|
||||
<div>
|
||||
<h4 class="sub-block-title margin-top-1">
|
||||
Draft content
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{{ draftContent }}
|
||||
</p>
|
||||
<div class="container">
|
||||
<h4 class="sub-block-title margin-top-1">
|
||||
AI generated content
|
||||
</h4>
|
||||
</div>
|
||||
<div class="animation-container margin-top-1">
|
||||
<div class="ai-typing--wrap ">
|
||||
<fluent-icon icon="wand" size="14" class="ai-typing--icon" />
|
||||
<label>AI is writing</label>
|
||||
</div>
|
||||
<span class="loader" />
|
||||
<span class="loader" />
|
||||
<span class="loader" />
|
||||
</div>
|
||||
|
||||
<div class="modal-footer justify-content-end w-full">
|
||||
<!-- <woot-button
|
||||
icon="delete-outline"
|
||||
variant="clear"
|
||||
@click.prevent="onClose"
|
||||
>
|
||||
Discard
|
||||
</woot-button> -->
|
||||
<woot-button variant="clear" @click.prevent="onClose">
|
||||
Discard
|
||||
</woot-button>
|
||||
<!-- <woot-button
|
||||
v-tooltip.top-end="$t('CONVERSATION.TRY_AGAIN')"
|
||||
color-scheme="alert"
|
||||
variant="clear"
|
||||
icon="arrow-clockwise"
|
||||
:disabled="!enableButtons"
|
||||
>Retry
|
||||
</woot-button> -->
|
||||
<woot-button :disabled="!enableButtons">
|
||||
Apply
|
||||
</woot-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
draftContent:
|
||||
'I am closing this thread as there is no response. Please feel to create a new one if the issue/query is not resolved.',
|
||||
generatedContent: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
aiContent() {
|
||||
return this.generatedContent.length > 0
|
||||
? this.generatedContent
|
||||
: 'Generating content...';
|
||||
},
|
||||
enableButtons() {
|
||||
return this.generatedContent.length > 0;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.generatedContent =
|
||||
'I am closing this thread as there has been no response. Please feel free to create a new thread if the issue or query remains unresolved.';
|
||||
}, 6000);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClose() {
|
||||
this.$emit('close');
|
||||
},
|
||||
chooseTime() {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal-content {
|
||||
padding-top: var(--space-small);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ai-typing--wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
.ai-typing--icon {
|
||||
color: var(--v-500);
|
||||
}
|
||||
}
|
||||
|
||||
.animation-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.animation-container label {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
color: var(--v-400);
|
||||
}
|
||||
|
||||
.loader {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 4px;
|
||||
margin-top: 12px;
|
||||
background-color: var(--v-300);
|
||||
border-radius: 50%;
|
||||
animation: bubble-scale 1.2s infinite;
|
||||
}
|
||||
|
||||
.loader:nth-child(2) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.loader:nth-child(3) {
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
@keyframes bubble-scale {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
25% {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div class="column">
|
||||
<woot-modal-header header-title="Reply suggestion with AI" />
|
||||
<form class="row modal-content" @submit.prevent="chooseTime">
|
||||
<div v-if="!generatedContent" class="animation-container margin-top-1">
|
||||
<div class="ai-typing--wrap ">
|
||||
<fluent-icon icon="wand" size="14" class="ai-typing--icon" />
|
||||
<label>AI is writing</label>
|
||||
</div>
|
||||
<span class="loader" />
|
||||
<span class="loader" />
|
||||
<span class="loader" />
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<p>
|
||||
{{ aiContent }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer justify-content-end w-full">
|
||||
<!-- <woot-button
|
||||
icon="delete-outline"
|
||||
variant="clear"
|
||||
@click.prevent="onClose"
|
||||
>
|
||||
Discard
|
||||
</woot-button> -->
|
||||
<woot-button variant="clear" @click.prevent="onClose">
|
||||
Discard
|
||||
</woot-button>
|
||||
<!-- <woot-button
|
||||
v-tooltip.top-end="$t('CONVERSATION.TRY_AGAIN')"
|
||||
color-scheme="alert"
|
||||
variant="clear"
|
||||
icon="arrow-clockwise"
|
||||
:disabled="!enableButtons"
|
||||
>Retry
|
||||
</woot-button> -->
|
||||
<woot-button :disabled="!enableButtons" @click="applyContent">
|
||||
Apply
|
||||
</woot-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
draftContent:
|
||||
'I am closing this thread as there is no response. Please feel to create a new one if the issue/query is not resolved.',
|
||||
generatedContent: '',
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
aiContent() {
|
||||
return this.generatedContent.length > 0
|
||||
? this.generatedContent
|
||||
: 'Generating content...';
|
||||
},
|
||||
enableButtons() {
|
||||
return this.generatedContent.length > 0;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
setTimeout(() => {
|
||||
this.generatedContent =
|
||||
'Hi there! Its great to see you here. How can I be of assistance to you today? Whether you need help with a specific task or have a general question, I am here to lend a hand. Let me know what you need, and I will do my best to provide you with the information or guidance you are looking for.';
|
||||
}, 5000);
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClose() {
|
||||
this.$emit('close');
|
||||
},
|
||||
chooseTime() {},
|
||||
applyContent() {
|
||||
this.$emit('apply-text', this.generatedContent);
|
||||
this.$emit('close');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal-content {
|
||||
padding-top: var(--space-small);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ai-typing--wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
.ai-typing--icon {
|
||||
color: var(--v-500);
|
||||
}
|
||||
}
|
||||
|
||||
.animation-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.animation-container label {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
color: var(--v-400);
|
||||
}
|
||||
|
||||
.loader {
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 4px;
|
||||
margin-top: 12px;
|
||||
background-color: var(--v-300);
|
||||
border-radius: 50%;
|
||||
animation: bubble-scale 1.2s infinite;
|
||||
}
|
||||
|
||||
.loader:nth-child(2) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.loader:nth-child(3) {
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
@keyframes bubble-scale {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
25% {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
// .typewriter p {
|
||||
// overflow: hidden; /* Ensures the content is not revealed until the animation */
|
||||
// border-right: 0.15em solid orange; /* The typwriter cursor */
|
||||
// margin: 0 auto; /* Gives that scrolling effect as the typing happens */
|
||||
// animation: typing 3.5s steps(30, end), blink-caret 0.5s step-end infinite;
|
||||
// }
|
||||
|
||||
// /* The typing effect */
|
||||
// @keyframes typing {
|
||||
// from {
|
||||
// width: 0;
|
||||
// }
|
||||
// to {
|
||||
// width: 100%;
|
||||
// }
|
||||
// }
|
||||
|
||||
// @keyframes blink-caret {
|
||||
// from,
|
||||
// to {
|
||||
// border-color: transparent;
|
||||
// }
|
||||
// 50% {
|
||||
// border-color: orange;
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="typing-indicator">
|
||||
<label>AI is typing</label>
|
||||
<div class="typing">
|
||||
<span class="circle scaling" />
|
||||
<span class="circle scaling" />
|
||||
<span class="circle scaling" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.typing-indicator {
|
||||
color: #282d3e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
width: fit-content;
|
||||
|
||||
.typing {
|
||||
display: block;
|
||||
width: 36px;
|
||||
height: 16px;
|
||||
border-radius: 20px;
|
||||
margin: 0 4px 0 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.circle {
|
||||
display: block;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 50%;
|
||||
background-color: #000;
|
||||
margin: 3px;
|
||||
|
||||
&.scaling {
|
||||
animation: typing 1000ms ease-in-out infinite;
|
||||
animation-delay: 3600ms;
|
||||
}
|
||||
|
||||
&.bouncing {
|
||||
animation: bounce 1000ms ease-in-out infinite;
|
||||
animation-delay: 3600ms;
|
||||
}
|
||||
.circle:nth-child(1) {
|
||||
animation-delay: 0ms;
|
||||
}
|
||||
|
||||
.circle:nth-child(2) {
|
||||
animation-delay: 333ms;
|
||||
}
|
||||
|
||||
.circle:nth-child(3) {
|
||||
animation-delay: 666ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes typing {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
33% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</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,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user