Compare commits

..
Author SHA1 Message Date
Tanmay Deep Sharma 4bb414727f test update for mintlify app 2025-05-08 13:25:22 +07:00
Tanmay Deep Sharma f4a77dabd9 add Open API v3 developer docs 2025-05-08 12:47:22 +07:00
Vishnu NarayananandGitHub bfddc4da24 chore: use housekeeping queue for remove_stale_contacts job (#11435)
- Use the housekeeping queue for the `remove_stale_contacts` job
- fix specs
2025-05-08 09:39:49 +05:30
Vishnu NarayananandGitHub 199f2fb86c fix: stale contacts job queue (#11434) 2025-05-08 08:43:34 +05:30
Shivam MishraandGitHub 1b23310e4b fix(ux): don't disable input for auto resolve (#11428) 2025-05-07 21:17:24 +05:30
b533980880 feat: Add support for minutes in auto resolve feature (#11269)
### Summary

- Converts conversation auto-resolution duration from days to minutes
for more
granular control
- Updates validation to allow values from 10 minutes (minimum) to 999
days (maximum)
- Implements smart messaging to show appropriate time units in activity
messages

###  Changes

- Created migration to convert existing durations from days to minutes
(x1440)
- Updated conversation resolver to use minutes instead of days
- Added dynamic translation key selection based on duration value
- Updated related specs and documentation
- Added support for displaying durations in days, hours, or minutes
based on value

###  Test plan

- Verify account validation accepts new minute-based ranges
- Confirm existing account settings are correctly migrated
- Test auto-resolution works properly with minute values
- Ensure proper time unit display in activity messages

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2025-05-07 00:36:15 -07:00
Chatwoot BotandGitHub e08436dde5 chore: Update translations (#11425) 2025-05-07 00:34:06 -07:00
Vishnu NarayananandGitHub 968aa39a9e chore: move stalecontacts job to different sidekiq queue (#11427)
- move stale contacts job to `housekeeping` queue below `low`
2025-05-07 00:31:58 -07:00
ea3ef9064b feat: handle rails turbo morphing (#11422)
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
2025-05-07 10:22:08 +05:30
c8daa6c1fe chore: Update translations (#11413)
Co-authored-by: Pranav <pranav@chatwoot.com>
2025-05-06 13:34:27 -07:00
Muhsin KelothandGitHub 164f4ec90e fix: Undefined local variable or method error for an instance of Instagram MessageText (#11421)
Fixes https://chatwoot-p3.sentry.io/issues/6557025930?project=6382945
2025-05-06 15:49:43 +05:30
945fa5fd16 chore: Update message bubble orientation (#11348)
# Pull Request Template

## Description

This PR includes,

### Changes

1. **Message Orientation**:  
- Updated the bubble orientation of Bot, Agent, and Private Note
messages to align from **left** to **right**.

2. **Activity Message bubble Styling**:  
- Adjusted **padding** and **border-radius** for activity message
bubbles for better alignment and appearance.

| **Before**  | **After** |
| ------------- | ------------- |
| <img width="559" alt="image"
src="https://github.com/user-attachments/assets/18258ae0-0d8e-4447-a005-9b6643b71f81"
/> | <img width="559" alt="image"
src="https://github.com/user-attachments/assets/425785d8-17f9-4629-8301-f19f23aef201"
/> |




---


Fixes
[CW-4263](https://linear.app/chatwoot/issue/CW-4263/v410-messages-history-incoming-and-outgoing-renders-in-one-line),
https://github.com/chatwoot/chatwoot/issues/11340

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

### Loom video

https://www.loom.com/share/117bbb1dda98451883c9bb17f7cf016b?sid=05eae4d4-af11-4a41-a1d6-dc4e7e2cb281


## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
2025-05-06 13:21:52 +05:30
6ced918549 feat: Update conversation basic filter (#11415)
# Pull Request Template

## Description

This PR updates the basic filter UI for conversations.

## Type of change

- [x] New feature (non-breaking change which adds functionality)

## How Has This Been Tested?

### Loom video

https://www.loom.com/share/df69a023a39c4dfca2c12b1ee42a0b2e?sid=977e802e-2865-46f1-ae8e-f89ab5eabc2a


## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules

---------

Co-authored-by: Pranav <pranav@chatwoot.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-05-06 12:44:23 +05:30
6e6912aa56 chore: Generate test data for bulk insertion (#11229)
Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: tds-1 <tanmay@qoala.id>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
2025-05-06 11:13:11 +05:30
PranavandGitHub cbdbf7900e fix: Update the character count for instructions (#11419)
- Increase the Captain instruction size to 20k instead of 2k
- Fix a display issue in the Captain playground and i18n issue in
Captain form.
2025-05-05 19:41:38 -07:00
PranavandGitHub 7cf051aba0 fix: Show campaigns only if the feature is enabled (#11420)
If the feature is disabled (manually or due to plan changes), the
customer cannot disable the existing campaigns. This PR would fix that.

Fixes
https://linear.app/chatwoot/issue/CW-3691/fix-disable-campaigns-on-plan-downgrade
2025-05-05 19:41:28 -07:00
Sivin VargheseandGitHub 6b42305f59 fix: Show agent bot name and avatar correctly in messages (#11394)
This PR fixes an issue where messages from the agent bot were incorrectly displayed as "BOT" with a missing avatar. It now correctly shows the agent bot’s name and avatar URL in the message list.
2025-05-05 16:26:30 -07:00
128 changed files with 2813 additions and 988 deletions
@@ -44,8 +44,9 @@ class Api::V1::AccountsController < Api::BaseController
end
def update
@account.assign_attributes(account_params.slice(:name, :locale, :domain, :support_email, :auto_resolve_duration))
@account.assign_attributes(account_params.slice(:name, :locale, :domain, :support_email))
@account.custom_attributes.merge!(custom_attributes_params)
@account.settings.merge!(settings_params)
@account.custom_attributes['onboarding_step'] = 'invite_team' if @account.custom_attributes['onboarding_step'] == 'account_update'
@account.save!
end
@@ -83,13 +84,17 @@ class Api::V1::AccountsController < Api::BaseController
end
def account_params
params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :auto_resolve_duration, :user_full_name)
params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :user_full_name)
end
def custom_attributes_params
params.permit(:industry, :company_size, :timezone)
end
def settings_params
params.permit(:auto_resolve_after, :auto_resolve_message)
end
def check_signup_enabled
raise ActionController::RoutingError, 'Not Found' if GlobalConfigService.load('ENABLE_ACCOUNT_SIGNUP', 'false') == 'false'
end
@@ -2,10 +2,15 @@ class Api::V1::Widget::CampaignsController < Api::V1::Widget::BaseController
skip_before_action :set_contact
def index
@campaigns = @web_widget
.inbox
.campaigns
.where(enabled: true, account_id: @web_widget.inbox.account_id)
.includes(:sender)
account = @web_widget.inbox.account
@campaigns = if account.feature_enabled?('campaigns')
@web_widget
.inbox
.campaigns
.where(enabled: true, account_id: account.id)
.includes(:sender)
else
[]
end
end
end
@@ -54,7 +54,7 @@ class Api::V2::AccountsController < Api::BaseController
end
def account_params
params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :auto_resolve_duration, :user_full_name)
params.permit(:account_name, :email, :name, :password, :locale, :domain, :support_email, :user_full_name)
end
def check_signup_enabled
@@ -412,7 +412,7 @@ const accountLabels = computed(() => [
<template>
<Story
title="Components/Conversation/ConversationCard"
title="Components/ConversationCard"
:layout="{ type: 'grid', width: '600px' }"
>
<Variant title="Conversation without meta">
@@ -1,52 +0,0 @@
<script setup>
import Button from 'dashboard/components-next/button/Button.vue';
import ConversationSortMenu from './ConversationSortMenu.vue';
defineProps({
title: {
type: String,
default: '',
},
activeStatus: {
type: String,
default: 'open',
},
activeOrdering: {
type: String,
default: 'last_activity_at_desc',
},
});
const emit = defineEmits([
'filter',
'update:activeStatus',
'update:activeOrdering',
]);
</script>
<template>
<div
class="flex items-center justify-between gap-2 pt-4 pb-4 ltr:pl-6 rtl:pr-6 ltr:pr-5 rtl:pl-5"
>
<h4
class="min-w-0 text-base font-semibold leading-5 truncate text-n-slate-12"
>
{{ title }}
</h4>
<div class="flex items-center gap-2">
<Button
icon="i-lucide-list-filter"
color="slate"
size="sm"
variant="ghost"
@click="emit('filter')"
/>
<ConversationSortMenu
:active-status="activeStatus"
:active-ordering="activeOrdering"
@update:active-status="emit('update:activeStatus', $event)"
@update:active-ordering="emit('update:activeOrdering', $event)"
/>
</div>
</div>
</template>
@@ -1,123 +0,0 @@
<script setup>
import { ref, computed, toRef } from 'vue';
import { useI18n } from 'vue-i18n';
import { vOnClickOutside } from '@vueuse/components';
import Button from 'dashboard/components-next/button/Button.vue';
import SelectMenu from 'dashboard/components-next/selectmenu/SelectMenu.vue';
const props = defineProps({
activeStatus: {
type: String,
default: 'open',
},
activeOrdering: {
type: String,
default: 'last_activity_at_desc',
},
});
const emit = defineEmits(['update:activeStatus', 'update:activeOrdering']);
const { t } = useI18n();
const CHAT_STATUS_FILTER_ITEMS = Object.freeze([
'open',
'resolved',
'pending',
'snoozed',
'all',
]);
const SORT_ORDER_ITEMS = Object.freeze([
'last_activity_at_asc',
'last_activity_at_desc',
'created_at_desc',
'created_at_asc',
'priority_desc',
'priority_asc',
'waiting_since_asc',
'waiting_since_desc',
]);
// Converted to ref to avoid reactivity issues
const activeStatus = toRef(props, 'activeStatus');
const activeOrdering = toRef(props, 'activeOrdering');
const statusMenus = computed(() => {
return CHAT_STATUS_FILTER_ITEMS.map(item => ({
label: t(`CONVERSATION_LIST.CHAT_STATUS.OPTIONS.${item.toUpperCase()}`),
value: item,
}));
});
const orderingMenus = computed(() => {
return SORT_ORDER_ITEMS.map(item => ({
label: t(`CONVERSATION_LIST.CHAT_SORT_ORDER.OPTIONS.${item.toUpperCase()}`),
value: item,
}));
});
const activeStatusLabel = computed(() => {
return t(
`CONVERSATION_LIST.CHAT_STATUS.OPTIONS.${activeStatus.value.toUpperCase()}`
);
});
const activeOrderingLabel = computed(() => {
return t(
`CONVERSATION_LIST.CHAT_SORT_ORDER.OPTIONS.${activeOrdering.value.toUpperCase()}`
);
});
const isMenuOpen = ref(false);
const handleStatusChange = value => {
emit('update:activeStatus', value);
};
const handleOrderChange = value => {
emit('update:activeOrdering', value);
};
</script>
<template>
<div class="relative">
<Button
icon="i-lucide-arrow-down-up"
color="slate"
size="sm"
variant="ghost"
:class="isMenuOpen ? 'bg-n-alpha-2' : ''"
@click="isMenuOpen = !isMenuOpen"
/>
<div
v-if="isMenuOpen"
v-on-click-outside="() => (isMenuOpen = false)"
class="absolute top-full mt-1 ltr:right-0 rtl:left-0 flex flex-col gap-4 bg-n-alpha-3 backdrop-blur-[100px] border border-n-weak w-72 rounded-xl p-4"
>
<div class="flex items-center justify-between gap-2">
<span class="text-sm text-n-slate-12">
{{ t('CONVERSATION_LIST.CHAT_STATUS.LABEL') }}
</span>
<SelectMenu
:model-value="activeStatus"
:options="statusMenus"
:label="activeStatusLabel"
@update:model-value="handleStatusChange"
/>
</div>
<div class="flex items-center justify-between gap-2">
<span class="text-sm text-n-slate-12">
{{ t('CONVERSATION_LIST.CHAT_SORT_ORDER.LABEL') }}
</span>
<SelectMenu
:model-value="activeOrdering"
:options="orderingMenus"
:label="activeOrderingLabel"
@update:model-value="handleOrderChange"
/>
</div>
</div>
</div>
</template>
@@ -1,42 +0,0 @@
<script setup>
import ConversationListHeader from '../ConversationListHeader.vue';
import { ref } from 'vue';
// Story state
const activeStatus = ref('open');
const activeOrdering = ref('last_activity_at_desc');
const filter = () => {
console.log('filter');
};
const updateActiveStatus = newStatus => {
activeStatus.value = newStatus;
console.log('updateActiveStatus', newStatus);
};
const updateActiveOrdering = newOrdering => {
activeOrdering.value = newOrdering;
console.log('updateActiveOrdering', newOrdering);
};
</script>
<template>
<Story title="Components/Conversation/ConversationListHeader">
<Variant title="Default">
<div
class="flex justify-center items-start w-full h-[500px] bg-n-solid-1"
>
<ConversationListHeader
title="Conversations"
:active-status="activeStatus"
:active-ordering="activeOrdering"
class="max-w-[400px] w-full"
@filter="filter"
@update:active-status="updateActiveStatus"
@update:active-ordering="updateActiveOrdering"
/>
</div>
</Variant>
</Story>
</template>
@@ -65,7 +65,7 @@ watch(() => props.messages.length, scrollToBottom);
class="max-w-[80%] rounded-lg p-3 text-sm"
:class="getMessageStyle(message.sender)"
>
<div v-html="formatMessage(message.content)" />
<div class="break-words" v-html="formatMessage(message.content)" />
</div>
</div>
</div>
@@ -214,7 +214,7 @@ watch(
v-model="state.instructions"
:placeholder="t('CAPTAIN.ASSISTANTS.FORM.INSTRUCTIONS.PLACEHOLDER')"
:message="formErrors.instructions"
:max-length="2000"
:max-length="20000"
:message-type="formErrors.instructions ? 'error' : 'info'"
/>
@@ -0,0 +1,66 @@
<script setup>
import { computed, ref } from 'vue';
import Input from './Input.vue';
import { useI18n } from 'vue-i18n';
const props = defineProps({
min: { type: Number, default: 0 },
max: { type: Number, default: Infinity },
disabled: { type: Boolean, default: false },
});
const { t } = useI18n();
const duration = defineModel('modelValue', { type: Number, default: null });
const UNIT_TYPES = {
MINUTES: 'minutes',
HOURS: 'hours',
DAYS: 'days',
};
const unit = ref(UNIT_TYPES.MINUTES);
const transformedValue = computed({
get() {
if (unit.value === UNIT_TYPES.MINUTES) return duration.value;
if (unit.value === UNIT_TYPES.HOURS) return Math.floor(duration.value / 60);
if (unit.value === UNIT_TYPES.DAYS)
return Math.floor(duration.value / 24 / 60);
return 0;
},
set(newValue) {
let minuteValue;
if (unit.value === UNIT_TYPES.MINUTES) {
minuteValue = Math.floor(newValue);
} else if (unit.value === UNIT_TYPES.HOURS) {
minuteValue = Math.floor(newValue * 60);
} else if (unit.value === UNIT_TYPES.DAYS) {
minuteValue = Math.floor(newValue * 24 * 60);
}
duration.value = Math.min(Math.max(minuteValue, props.min), props.max);
},
});
</script>
<template>
<Input
v-model="transformedValue"
type="number"
autocomplete="off"
:disabled="disabled"
:placeholder="t('DURATION_INPUT.PLACEHOLDER')"
class="flex-grow w-full disabled:"
/>
<select
v-model="unit"
:disabled="disabled"
class="mb-0 text-sm disabled:outline-n-weak disabled:opacity-40"
>
<option :value="UNIT_TYPES.MINUTES">
{{ t('DURATION_INPUT.MINUTES') }}
</option>
<option :value="UNIT_TYPES.HOURS">{{ t('DURATION_INPUT.HOURS') }}</option>
<option :value="UNIT_TYPES.DAYS">{{ t('DURATION_INPUT.DAYS') }}</option>
</select>
</template>
@@ -117,7 +117,7 @@ const props = defineProps({
},
conversationId: { type: Number, required: true },
createdAt: { type: Number, required: true }, // eslint-disable-line vue/no-unused-properties
currentUserId: { type: Number, required: true },
currentUserId: { type: Number, required: true }, // eslint-disable-line vue/no-unused-properties
groupWithNext: { type: Boolean, default: false },
inboxId: { type: Number, default: null }, // eslint-disable-line vue/no-unused-properties
inboxSupportsReplyTo: { type: Object, default: () => ({}) },
@@ -173,7 +173,10 @@ const variant = computed(() => {
return variants[props.messageType] || MESSAGE_VARIANTS.USER;
});
const isMyMessage = computed(() => {
const isBotOrAgentMessage = computed(() => {
if (props.messageType === MESSAGE_TYPES.ACTIVITY) {
return false;
}
// if an outgoing message is still processing, then it's definitely a
// message sent by the current user
if (
@@ -186,13 +189,10 @@ const isMyMessage = computed(() => {
const senderType = props.senderType ?? props.sender?.type;
if (!senderType || !senderId) {
return false;
return true;
}
return (
senderType.toLowerCase() === SENDER_TYPES.USER.toLowerCase() &&
props.currentUserId === senderId
);
return senderType.toLowerCase() === SENDER_TYPES.USER.toLowerCase();
});
/**
@@ -200,7 +200,7 @@ const isMyMessage = computed(() => {
* @returns {import('vue').ComputedRef<'left'|'right'|'center'>} The computed orientation
*/
const orientation = computed(() => {
if (isMyMessage.value) {
if (isBotOrAgentMessage.value) {
return ORIENTATION.RIGHT;
}
@@ -221,8 +221,8 @@ const flexOrientationClass = computed(() => {
const gridClass = computed(() => {
const map = {
[ORIENTATION.LEFT]: 'grid grid-cols-[24px_1fr]',
[ORIENTATION.RIGHT]: 'grid grid-cols-1fr',
[ORIENTATION.LEFT]: 'grid grid-cols-1fr',
[ORIENTATION.RIGHT]: 'grid grid-cols-[1fr_24px]',
};
return map[orientation.value];
@@ -231,13 +231,13 @@ const gridClass = computed(() => {
const gridTemplate = computed(() => {
const map = {
[ORIENTATION.LEFT]: `
"avatar bubble"
"spacer meta"
`,
[ORIENTATION.RIGHT]: `
"bubble"
"meta"
`,
[ORIENTATION.RIGHT]: `
"bubble avatar"
"meta spacer"
`,
};
return map[orientation.value];
@@ -251,7 +251,7 @@ const shouldGroupWithNext = computed(() => {
const shouldShowAvatar = computed(() => {
if (props.messageType === MESSAGE_TYPES.ACTIVITY) return false;
if (orientation.value === ORIENTATION.RIGHT) return false;
if (orientation.value === ORIENTATION.LEFT) return false;
return true;
});
@@ -394,23 +394,29 @@ function handleReplyTo() {
}
const avatarInfo = computed(() => {
if (!props.sender || props.sender.type === SENDER_TYPES.AGENT_BOT) {
// If no sender, return bot info
if (!props.sender) {
return {
name: t('CONVERSATION.BOT'),
src: '',
};
}
if (props.sender) {
const { sender } = props;
const { name, type, avatarUrl, thumbnail } = sender || {};
// If sender type is agent bot, use avatarUrl
if (type === SENDER_TYPES.AGENT_BOT) {
return {
name: props.sender.name,
src: props.sender?.thumbnail,
name: name ?? '',
src: avatarUrl ?? '',
};
}
// For all other senders, use thumbnail
return {
name: '',
src: '',
name: name ?? '',
src: thumbnail ?? '',
};
});
@@ -438,7 +444,7 @@ provideMessageContext({
isPrivate: computed(() => props.private),
variant,
orientation,
isMyMessage,
isBotOrAgentMessage,
shouldGroupWithNext,
});
</script>
@@ -470,14 +476,14 @@ provideMessageContext({
'w-full': variant === MESSAGE_VARIANTS.EMAIL,
},
]"
class="gap-x-3"
class="gap-x-2"
:style="{
gridTemplateAreas: gridTemplate,
}"
>
<div
v-if="!shouldGroupWithNext && shouldShowAvatar"
v-tooltip.right-end="avatarTooltip"
v-tooltip.left-end="avatarTooltip"
class="[grid-area:avatar] flex items-end"
>
<Avatar v-bind="avatarInfo" :size="24" />
@@ -485,7 +491,8 @@ provideMessageContext({
<div
class="[grid-area:bubble] flex"
:class="{
'ltr:pl-9 rtl:pl-0 justify-end': orientation === ORIENTATION.RIGHT,
'ltr:pl-8 rtl:pr-8 justify-end': orientation === ORIENTATION.RIGHT,
'ltr:pr-8 rtl:pl-8': orientation === ORIENTATION.LEFT,
'min-w-0': variant === MESSAGE_VARIANTS.EMAIL,
}"
@contextmenu="openContextMenu($event)"
@@ -14,7 +14,7 @@ const readableTime = computed(() =>
<template>
<BaseBubble
v-tooltip.top="readableTime"
class="px-2 py-0.5 !rounded-full flex min-w-0 items-center gap-2"
class="px-3 py-1 !rounded-xl flex min-w-0 items-center gap-2"
data-bubble-name="activity"
>
<span v-dompurify-html="content" :title="content" />
@@ -98,7 +98,7 @@ const MessageControl = Symbol('MessageControl');
* @property {import('vue').Ref<Sender|null>} [sender=null] - The sender information
* @property {import('vue').ComputedRef<MessageOrientation>} orientation - The visual variant of the message
* @property {import('vue').ComputedRef<MessageVariant>} variant - The visual variant of the message
* @property {import('vue').ComputedRef<boolean>} isMyMessage - Does the message belong to the current user
* @property {import('vue').ComputedRef<boolean>} isBotOrAgentMessage - Does the message belong to the current user
* @property {import('vue').ComputedRef<boolean>} isPrivate - Proxy computed value for private
* @property {import('vue').ComputedRef<boolean>} shouldGroupWithNext - Should group with the next message or not, it is differnt from groupWithNext, this has a bypass for a failed message
*/
@@ -1,7 +1,5 @@
<script setup>
import { ref, computed } from 'vue';
import { vOnClickOutside } from '@vueuse/components';
import Button from 'dashboard/components-next/button/Button.vue';
const props = defineProps({
@@ -17,6 +15,13 @@ const props = defineProps({
type: String,
required: true,
},
subMenuPosition: {
type: String,
default: 'right',
validator: value => {
return ['right', 'left', 'bottom'].includes(value);
},
},
});
const emit = defineEmits(['update:modelValue']);
@@ -37,7 +42,7 @@ const handleSelect = value => {
<template>
<div
v-on-click-outside="() => (isOpen = false)"
v-on-clickaway="() => (isOpen = false)"
class="relative flex flex-col gap-1 w-fit"
>
<Button
@@ -53,7 +58,14 @@ const handleSelect = value => {
/>
<div
v-if="isOpen"
class="absolute ltr:left-full rtl:right-full select-none max-w-48 ltr:ml-1 rtl:mr-1 flex flex-col gap-1 bg-n-alpha-3 backdrop-blur-[100px] p-1 top-0 shadow-lg rounded-lg border border-n-weak"
class="absolute select-none max-w-64 flex flex-col gap-1 bg-n-alpha-3 backdrop-blur-[100px] p-1 top-0 shadow-lg z-40 rounded-lg border border-n-weak dark:border-n-strong/50"
:class="{
'ltr:left-full rtl:right-full ltr:ml-1 rtl:mr-1':
subMenuPosition === 'right',
'ltr:right-full rtl:left-full ltr:mr-1 rtl:ml-1':
subMenuPosition === 'left',
'top-full mt-1 ltr:right-0 rtl:left-0': subMenuPosition === 'bottom',
}"
>
<Button
v-for="option in options"
@@ -27,10 +27,10 @@ const updateValue = () => {
>
<span class="sr-only">{{ t('SWITCH.TOGGLE') }}</span>
<span
class="absolute top-[0.07rem] left-0.5 h-3 w-3 transform rounded-full shadow-sm transition-transform duration-200 ease-in-out"
class="absolute top-0.5 left-0.5 h-3 w-3 transform rounded-full shadow-sm transition-transform duration-200 ease-in-out"
:class="
modelValue
? 'translate-x-2.5 bg-white'
? 'translate-x-3 bg-white'
: 'translate-x-0 bg-white dark:bg-n-black'
"
/>
@@ -1,93 +1,129 @@
<script>
import wootConstants from 'dashboard/constants/globals';
import { mapGetters } from 'vuex';
import FilterItem from './FilterItem.vue';
<script setup>
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useToggle } from '@vueuse/core';
import { vOnClickOutside } from '@vueuse/components';
import { useUISettings } from 'dashboard/composables/useUISettings';
import { useMapGetter, useStore } from 'dashboard/composables/store.js';
import wootConstants from 'dashboard/constants/globals';
import SelectMenu from 'dashboard/components-next/selectmenu/SelectMenu.vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
const CHAT_STATUS_FILTER_ITEMS = Object.freeze([
'open',
'resolved',
'pending',
'snoozed',
'all',
]);
defineProps({
isOnExpandedLayout: {
type: Boolean,
required: true,
},
});
const SORT_ORDER_ITEMS = Object.freeze([
'last_activity_at_asc',
'last_activity_at_desc',
'created_at_desc',
'created_at_asc',
'priority_desc',
'priority_asc',
'waiting_since_asc',
'waiting_since_desc',
]);
const emit = defineEmits(['changeFilter']);
export default {
components: {
FilterItem,
NextButton,
},
props: {
isOnExpandedLayout: {
type: Boolean,
required: true,
},
},
emits: ['changeFilter'],
setup() {
const { updateUISettings } = useUISettings();
const store = useStore();
const { t } = useI18n();
return {
updateUISettings,
};
const { updateUISettings } = useUISettings();
const chatStatusFilter = useMapGetter('getChatStatusFilter');
const chatSortFilter = useMapGetter('getChatSortFilter');
const [showActionsDropdown, toggleDropdown] = useToggle();
const currentStatusFilter = computed(() => {
return chatStatusFilter.value || wootConstants.STATUS_TYPE.OPEN;
});
const currentSortBy = computed(() => {
return (
chatSortFilter.value || wootConstants.SORT_BY_TYPE.LAST_ACTIVITY_AT_DESC
);
});
const chatStatusOptions = [
{
label: t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.open.TEXT'),
value: 'open',
},
data() {
return {
showActionsDropdown: false,
chatStatusItems: CHAT_STATUS_FILTER_ITEMS,
chatSortItems: SORT_ORDER_ITEMS,
};
{
label: t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.resolved.TEXT'),
value: 'resolved',
},
computed: {
...mapGetters({
chatStatusFilter: 'getChatStatusFilter',
chatSortFilter: 'getChatSortFilter',
}),
chatStatus() {
return this.chatStatusFilter || wootConstants.STATUS_TYPE.OPEN;
},
sortFilter() {
return (
this.chatSortFilter || wootConstants.SORT_BY_TYPE.LAST_ACTIVITY_AT_DESC
);
},
{
label: t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.pending.TEXT'),
value: 'pending',
},
methods: {
onTabChange(value) {
this.$emit('changeFilter', value);
this.closeDropdown();
},
toggleDropdown() {
this.showActionsDropdown = !this.showActionsDropdown;
},
closeDropdown() {
this.showActionsDropdown = false;
},
onChangeFilter(value, type) {
this.$emit('changeFilter', value, type);
this.saveSelectedFilter(type, value);
},
saveSelectedFilter(type, value) {
this.updateUISettings({
conversations_filter_by: {
status: type === 'status' ? value : this.chatStatus,
order_by: type === 'sort' ? value : this.sortFilter,
},
});
},
{
label: t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.snoozed.TEXT'),
value: 'snoozed',
},
{
label: t('CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.all.TEXT'),
value: 'all',
},
];
const chatSortOptions = [
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.last_activity_at_asc.TEXT'),
value: 'last_activity_at_asc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.last_activity_at_desc.TEXT'),
value: 'last_activity_at_desc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.created_at_desc.TEXT'),
value: 'created_at_desc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.created_at_asc.TEXT'),
value: 'created_at_asc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.priority_desc.TEXT'),
value: 'priority_desc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.priority_asc.TEXT'),
value: 'priority_asc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.waiting_since_asc.TEXT'),
value: 'waiting_since_asc',
},
{
label: t('CHAT_LIST.SORT_ORDER_ITEMS.waiting_since_desc.TEXT'),
value: 'waiting_since_desc',
},
];
const activeChatStatusLabel = computed(
() =>
chatStatusOptions.find(m => m.value === chatStatusFilter.value)?.label || ''
);
const activeChatSortLabel = computed(
() => chatSortOptions.find(m => m.value === chatSortFilter.value)?.label || ''
);
const saveSelectedFilter = (type, value) => {
updateUISettings({
conversations_filter_by: {
status: type === 'status' ? value : currentStatusFilter.value,
order_by: type === 'sort' ? value : currentSortBy.value,
},
});
};
const handleStatusChange = value => {
emit('changeFilter', value, 'status');
store.dispatch('setChatStatusFilter', value);
saveSelectedFilter('status', value);
};
const handleSortChange = value => {
emit('changeFilter', value, 'sort');
store.dispatch('setChatSortFilter', value);
saveSelectedFilter('sort', value);
};
</script>
@@ -99,39 +135,39 @@ export default {
slate
faded
xs
@click="toggleDropdown"
@click="toggleDropdown()"
/>
<div
v-if="showActionsDropdown"
v-on-clickaway="closeDropdown"
class="mt-1 dropdown-pane dropdown-pane--open !w-52 !p-4 top-6 border !border-n-weak dark:!border-n-weak !bg-n-alpha-3 dark:!bg-n-alpha-3 backdrop-blur-[100px]"
v-on-click-outside="() => toggleDropdown()"
class="mt-1 bg-n-alpha-3 backdrop-blur-[100px] border border-n-weak w-72 rounded-xl p-4 absolute z-40 top-full"
:class="{
'ltr:left-0 rtl:right-0': !isOnExpandedLayout,
'ltr:right-0 rtl:left-0': isOnExpandedLayout,
}"
>
<div class="flex items-center justify-between last:mt-4">
<span class="text-xs font-medium text-n-slate-12">{{
$t('CHAT_LIST.CHAT_SORT.STATUS')
}}</span>
<FilterItem
type="status"
:selected-value="chatStatus"
:items="chatStatusItems"
path-prefix="CHAT_LIST.CHAT_STATUS_FILTER_ITEMS"
@on-change-filter="onChangeFilter"
<div class="flex items-center justify-between last:mt-4 gap-2">
<span class="text-sm truncate text-n-slate-12">
{{ $t('CHAT_LIST.CHAT_SORT.STATUS') }}
</span>
<SelectMenu
:model-value="chatStatusFilter"
:options="chatStatusOptions"
:label="activeChatStatusLabel"
:sub-menu-position="isOnExpandedLayout ? 'left' : 'right'"
@update:model-value="handleStatusChange"
/>
</div>
<div class="flex items-center justify-between last:mt-4">
<span class="text-xs font-medium text-n-slate-12">{{
$t('CHAT_LIST.CHAT_SORT.ORDER_BY')
}}</span>
<FilterItem
type="sort"
:selected-value="sortFilter"
:items="chatSortItems"
path-prefix="CHAT_LIST.SORT_ORDER_ITEMS"
@on-change-filter="onChangeFilter"
<div class="flex items-center justify-between last:mt-4 gap-2">
<span class="text-sm truncate text-n-slate-12">
{{ $t('CHAT_LIST.CHAT_SORT.ORDER_BY') }}
</span>
<SelectMenu
:model-value="chatSortFilter"
:options="chatSortOptions"
:label="activeChatSortLabel"
:sub-menu-position="isOnExpandedLayout ? 'left' : 'right'"
@update:model-value="handleSortChange"
/>
</div>
</div>
@@ -1,6 +1,6 @@
import { computed } from 'vue';
import { useRoute } from 'vue-router';
import { useMapGetter } from './store';
import { useMapGetter, useStore } from './store';
/**
* Composable for account-related operations.
@@ -12,6 +12,7 @@ export function useAccount() {
* @type {import('vue').ComputedRef<number>}
*/
const route = useRoute();
const store = useStore();
const getAccountFn = useMapGetter('accounts/getAccount');
const isOnChatwootCloud = useMapGetter('globalConfig/isOnChatwootCloud');
const isFeatureEnabledonAccount = useMapGetter(
@@ -44,6 +45,12 @@ export function useAccount() {
};
};
const updateAccount = async data => {
await store.dispatch('accounts/update', {
...data,
});
};
return {
accountId,
route,
@@ -52,5 +59,6 @@ export function useAccount() {
accountScopedRoute,
isCloudFeatureEnabled,
isOnChatwootCloud,
updateAccount,
};
}
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "أنت",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "أنت",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "الاسم",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "الوصف",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Име",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Описание",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Tu",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Tu",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nom",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Descripció",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Vy",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Vy",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Název",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Dig",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Dig",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Navn",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Beskrivelse",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Sie",
"USE": "Verwenden",
"RESET": "Zurücksetzen",
"SELECT_ASSISTANT": "Assistent auswählen"
"SELECT_ASSISTANT": "Assistent auswählen",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Sie",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Beschreibung",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Όνομα",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Περιγραφή",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -135,32 +135,5 @@
"SHOW_QUOTED_TEXT": "Show Quoted Text",
"MESSAGE_READ": "Read",
"SENDING": "Sending"
},
"CONVERSATION_LIST": {
"CHAT_STATUS": {
"LABEL": "Status",
"OPTIONS": {
"OPEN": "Open",
"RESOLVED": "Resolved",
"PENDING": "Pending",
"SNOOZED": "Snoozed",
"ALL": "All"
}
},
"CHAT_SORT_ORDER": {
"LABEL": "Order by",
"OPTIONS": {
"LAST_ACTIVITY_AT_ASC": "Last activity: Oldest first",
"LAST_ACTIVITY_AT_DESC": "Last activity: Newest first",
"CREATED_AT_DESC": "Created at: Newest first",
"CREATED_AT_ASC": "Created at: Oldest first",
"PRIORITY_DESC": "Priority: Highest first",
"PRIORITY_ASC": "Priority: Lowest first",
"WAITING_SINCE_ASC": "Pending Response: Longest first",
"WAITING_SINCE_DESC": "Pending Response: Shortest first"
}
}
}
}
@@ -43,5 +43,11 @@
"FEATURE_SPOTLIGHT": {
"LEARN_MORE": "Learn more",
"WATCH_VIDEO": "Watch video"
},
"DURATION_INPUT": {
"MINUTES": "Minutes",
"HOURS": "Hours",
"DAYS": "Days",
"PLACEHOLDER": "Enter duration"
}
}
@@ -44,6 +44,10 @@
"TITLE": "Account ID",
"NOTE": "This ID is required if you are building an API based integration"
},
"AUTO_RESOLVE": {
"TITLE": "Auto-resolve conversations",
"NOTE": "This configuration would allow you to automatically end the conversation after a certain period. Set the duration and customize the message to the user below."
},
"NAME": {
"LABEL": "Account name",
"PLACEHOLDER": "Your account name",
@@ -65,9 +69,18 @@
"ERROR": ""
},
"AUTO_RESOLVE_DURATION": {
"LABEL": "Number of days after a ticket should auto resolve if there is no activity",
"LABEL": "Inactivity duration for resolution",
"HELP": "Duration after a conversation should auto resolve if there is no activity",
"PLACEHOLDER": "30",
"ERROR": "Please enter a valid auto resolve duration (minimum 1 day and maximum 999 days)"
"ERROR": "Please enter a valid auto resolve duration (minimum 1 day and maximum 999 days)",
"API": {
"SUCCESS": "Auto resolve settings updated successfully",
"ERROR": "Failed to update auto resolve settings"
},
"UPDATE_BUTTON": "Update Auto-resolve",
"MESSAGE_LABEL": "Custom resolution message",
"MESSAGE_PLACEHOLDER": "Conversation was marked resolved by system due to 15 days of inactivity",
"MESSAGE_HELP": "This message is sent to the customer when a conversation is automatically resolved by the system due to inactivity."
},
"FEATURES": {
"INBOUND_EMAIL_ENABLED": "Conversation continuity with emails is enabled for your account.",
@@ -403,15 +403,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Tú",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Tú",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nombre",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Descripción",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "شما",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "شما",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "نام",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "توضیحات",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Sinä",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Sinä",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nimi",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Kuvaus",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Vous",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Vous",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nom",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "שם",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "תיאור",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Vi",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Vi",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Ime",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Ön",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Ön",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Név",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Leírás",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Anda",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Anda",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nama",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Deskripsi",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nafn",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nome",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Descrizione",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "あなた",
"USE": "これを使用",
"RESET": "リセット",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "あなた",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "名前",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "説明",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "製品名",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "製品名が必要です"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "나",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "나",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "이름",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "내용",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Jūs",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Jūs",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Vardas",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Aprašymas",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Jūs",
"USE": "Izmantot šo",
"RESET": "Atiestatīt",
"SELECT_ASSISTANT": "Izvēlēties Asistentu"
"SELECT_ASSISTANT": "Izvēlēties Asistentu",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Jūs",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nosaukums",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Apraksts",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Produkta Nosaukums",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "Nepieciešams produkta nosaukums"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -337,16 +337,16 @@
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "ഈ സംവാദം സംക്ഷേപിക്കുക",
"CONTENT": "ഉപഭോക്താവും സഹായ ഏജന്റും തമ്മിലുള്ള സംവാദത്തിലെ പ്രധാന വിഷയങ്ങൾ സംക്ഷേപിക്കുക. ഉപഭോക്താവിന്റെ ആശങ്കകൾ, ചോദ്യങ്ങൾ, ഏജന്റിന്റെ മറുപടികൾ എന്നിവ ഉൾപ്പെടണം."
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "ഒരു മറുപടി നിർദ്ദേശിക്കുക",
"CONTENT": "ഉപഭോക്താവിന്റെ ചോദ്യങ്ങൾ വിശകലനം ചെയ്ത്, അവരുടെ ആശങ്കകൾക്കും ചോദ്യങ്ങൾക്കും യോജിച്ചുള്ള ഒരു വ്യക്തവും ഉപകാരപ്രദവുമായ മറുപടി രൂപപ്പെടുത്തുക."
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "ഈ സംവാദം റേറ്റുചെയ്യുക",
"CONTENT": "ഉപഭോക്താവിന്റെ ആവശ്യങ്ങൾ എത്രമാത്രം നല്ല രീതിയിൽ നിറവേറ്റിയെന്ന് വിലയിരുത്തുക. സംഭാഷണത്തിന്റെ സ്വരം, വ്യക്തത, കാര്യക്ഷമത എന്നിവയുടെ അടിസ്ഥാനത്തിൽ 5ൽ എത്രയാണെന്ന് റേറ്റുചെയ്യുക."
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
@@ -406,15 +406,18 @@
},
"NAME": {
"LABEL": "പേര്",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "വിവരണം",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nama",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Jij",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Jij",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Naam",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Beschrijving",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Du",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Du",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Navn",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Beskrivelse",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Imię",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Opis",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Você",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Você",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nome:",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Descrição",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -242,8 +242,8 @@
"ERROR": "Por favor, insira um valor válido."
},
"BUSINESS_ACCOUNT_ID": {
"LABEL": "ID da Conta de Negócios",
"PLACEHOLDER": "Por favor, insira o ID da Conta de Negócios obtido do painel do desenvolvedor do Facebook.",
"LABEL": "ID da conta do WhatsApp Business",
"PLACEHOLDER": "Por favor, insira o ID da conta do WhatsApp Business obtido do painel do desenvolvedor do Facebook.",
"ERROR": "Por favor, insira um valor válido."
},
"WEBHOOK_VERIFY_TOKEN": {
@@ -334,7 +334,21 @@
"YOU": "Você",
"USE": "Use isto",
"RESET": "Reiniciar",
"SELECT_ASSISTANT": "Selecione o Assistente"
"SELECT_ASSISTANT": "Selecione o Assistente",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Resumir esta conversa",
"CONTENT": "Resuma os pontos-chave discutidos entre o cliente e o agente de suporte, incluindo as preocupações do cliente, as questões e as soluções ou respostas dadas pelo agente de suporte"
},
"SUGGEST": {
"LABEL": "Sugerir uma resposta",
"CONTENT": "Analise a pergunta do cliente e elabore uma resposta que responda efetivamente às suas preocupações ou perguntas. Certifique-se de que a resposta seja clara, concisa e forneça informações úteis."
},
"RATE": {
"LABEL": "Avaliar esta conversa",
"CONTENT": "Revise a conversa para ver o quanto ela atende às necessidades do cliente. Compartilhe uma classificação de 0 a 5 com base em tom, clareza e eficácia."
}
}
},
"PLAYGROUND": {
"USER": "Você",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nome",
"PLACEHOLDER": "Digite o nome do assistente"
"PLACEHOLDER": "Digite o nome do assistente",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Descrição",
"PLACEHOLDER": "Digite a descrição do assistente"
"PLACEHOLDER": "Digite a descrição do assistente",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Nome do Produto",
"PLACEHOLDER": "Digite o nome do produto"
"PLACEHOLDER": "Digite o nome do produto",
"ERROR": "O nome do produto é obrigatório"
},
"WELCOME_MESSAGE": {
"LABEL": "Mensagem de boas-vindas",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Nume",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Descriere",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Вы",
"USE": "Использовать это",
"RESET": "Сброс",
"SELECT_ASSISTANT": "Выбрать ассистента"
"SELECT_ASSISTANT": "Выбрать ассистента",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Вы",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Имя",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Описание",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Название продукта",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "Требуется название продукта"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Vy",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Vy",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Meno",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Vi",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Vi",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Ju",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Ju",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Ime",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Opis",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Du",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Du",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Namn",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Beskrivning",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "பெயர்",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "ชื่อ",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "คำอธิบาย",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Sen",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Sen",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "İsim",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Açıklama",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "Ви",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "Ви",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Ім'я",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Опис",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "نام",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Name",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Description",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "Tên",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "Mô tả",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "您",
"USE": "使用此",
"RESET": "重置",
"SELECT_ASSISTANT": "选择助手"
"SELECT_ASSISTANT": "选择助手",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "您",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "姓名:",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "描述信息",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "产品名称",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "产品名称是必需的"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -334,7 +334,21 @@
"YOU": "You",
"USE": "Use this",
"RESET": "Reset",
"SELECT_ASSISTANT": "Select Assistant"
"SELECT_ASSISTANT": "Select Assistant",
"PROMPTS": {
"SUMMARIZE": {
"LABEL": "Summarize this conversation",
"CONTENT": "Summarize the key points discussed between the customer and the support agent, including the customer's concerns, questions, and the solutions or responses provided by the support agent"
},
"SUGGEST": {
"LABEL": "Suggest an answer",
"CONTENT": "Analyze the customer's inquiry, and draft a response that effectively addresses their concerns or questions. Ensure the reply is clear, concise, and provides helpful information."
},
"RATE": {
"LABEL": "Rate this conversation",
"CONTENT": "Review the conversation to see how well it meets the customer's needs. Share a rating out of 5 based on tone, clarity, and effectiveness."
}
}
},
"PLAYGROUND": {
"USER": "You",
@@ -392,15 +406,18 @@
},
"NAME": {
"LABEL": "姓名",
"PLACEHOLDER": "Enter assistant name"
"PLACEHOLDER": "Enter assistant name",
"ERROR": "The name is required"
},
"DESCRIPTION": {
"LABEL": "描述資訊",
"PLACEHOLDER": "Enter assistant description"
"PLACEHOLDER": "Enter assistant description",
"ERROR": "The description is required"
},
"PRODUCT_NAME": {
"LABEL": "Product Name",
"PLACEHOLDER": "Enter product name"
"PLACEHOLDER": "Enter product name",
"ERROR": "The product name is required"
},
"WELCOME_MESSAGE": {
"LABEL": "Welcome Message",
@@ -1,25 +1,34 @@
<script>
import { useVuelidate } from '@vuelidate/core';
import { required, minValue, maxValue } from '@vuelidate/validators';
import { required } from '@vuelidate/validators';
import { mapGetters } from 'vuex';
import { useAlert } from 'dashboard/composables';
import { useUISettings } from 'dashboard/composables/useUISettings';
import { useConfig } from 'dashboard/composables/useConfig';
import { useAccount } from 'dashboard/composables/useAccount';
import { FEATURE_FLAGS } from '../../../../featureFlags';
import semver from 'semver';
import { getLanguageDirection } from 'dashboard/components/widgets/conversation/advancedFilterItems/languages';
import WithLabel from 'v3/components/Form/WithLabel.vue';
import NextInput from 'next/input/Input.vue';
import BaseSettingsHeader from '../components/BaseSettingsHeader.vue';
import V4Button from 'dashboard/components-next/button/Button.vue';
import WootConfirmDeleteModal from 'dashboard/components/widgets/modal/ConfirmDeleteModal.vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
import AccountId from './components/AccountId.vue';
import BuildInfo from './components/BuildInfo.vue';
import AccountDelete from './components/AccountDelete.vue';
import AutoResolve from './components/AutoResolve.vue';
import SectionLayout from './components/SectionLayout.vue';
export default {
components: {
BaseSettingsHeader,
V4Button,
WootConfirmDeleteModal,
NextButton,
AccountId,
BuildInfo,
AccountDelete,
AutoResolve,
SectionLayout,
WithLabel,
NextInput,
},
setup() {
const { updateUISettings } = useUISettings();
@@ -37,9 +46,6 @@ export default {
domain: '',
supportEmail: '',
features: {},
autoResolveDuration: null,
latestChatwootVersion: null,
showDeletePopup: false,
};
},
validations: {
@@ -49,14 +55,9 @@ export default {
locale: {
required,
},
autoResolveDuration: {
minValue: minValue(1),
maxValue: maxValue(999),
},
},
computed: {
...mapGetters({
globalConfig: 'globalConfig/get',
getAccount: 'accounts/getAccount',
uiFlags: 'accounts/getUIFlags',
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
@@ -68,16 +69,6 @@ export default {
FEATURE_FLAGS.AUTO_RESOLVE_CONVERSATIONS
);
},
hasAnUpdateAvailable() {
if (!semver.valid(this.latestChatwootVersion)) {
return false;
}
return semver.lt(
this.globalConfig.appVersion,
this.latestChatwootVersion
);
},
languagesSortedByCode() {
const enabledLanguages = [...this.enabledLanguages];
return enabledLanguages.sort((l1, l2) =>
@@ -87,51 +78,19 @@ export default {
isUpdating() {
return this.uiFlags.isUpdating;
},
featureInboundEmailEnabled() {
return !!this.features?.inbound_emails;
},
featureCustomReplyDomainEnabled() {
return (
this.featureInboundEmailEnabled && !!this.features.custom_reply_domain
);
},
featureCustomReplyEmailEnabled() {
return (
this.featureInboundEmailEnabled && !!this.features.custom_reply_email
);
},
getAccountId() {
return this.id.toString();
},
confirmPlaceHolderText() {
return `${this.$t(
'GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.PLACE_HOLDER',
{
accountName: this.name,
}
)}`;
},
isMarkedForDeletion() {
const { custom_attributes = {} } = this.currentAccount;
return !!custom_attributes.marked_for_deletion_at;
},
markedForDeletionDate() {
const { custom_attributes = {} } = this.currentAccount;
if (!custom_attributes.marked_for_deletion_at) return null;
return new Date(custom_attributes.marked_for_deletion_at);
},
markedForDeletionReason() {
const { custom_attributes = {} } = this.currentAccount;
return custom_attributes.marked_for_deletion_reason || 'manual_deletion';
},
formattedDeletionDate() {
if (!this.markedForDeletionDate) return '';
return this.markedForDeletionDate.toLocaleString();
},
currentAccount() {
return this.getAccount(this.accountId) || {};
},
@@ -142,16 +101,8 @@ export default {
methods: {
async initializeAccount() {
try {
const {
name,
locale,
id,
domain,
support_email,
features,
auto_resolve_duration,
latest_chatwoot_version: latestChatwootVersion,
} = this.getAccount(this.accountId);
const { name, locale, id, domain, support_email, features } =
this.getAccount(this.accountId);
this.$root.$i18n.locale = locale;
this.name = name;
@@ -160,8 +111,6 @@ export default {
this.domain = domain;
this.supportEmail = support_email;
this.features = features;
this.autoResolveDuration = auto_resolve_duration;
this.latestChatwootVersion = latestChatwootVersion;
} catch (error) {
// Ignore error
}
@@ -179,7 +128,6 @@ export default {
name: this.name,
domain: this.domain,
support_email: this.supportEmail,
auto_resolve_duration: this.autoResolveDuration,
});
this.$root.$i18n.locale = this.locale;
this.getAccount(this.id).locale = this.locale;
@@ -196,252 +144,101 @@ export default {
rtl_view: isRTLSupported,
});
},
// Delete Function
openDeletePopup() {
this.showDeletePopup = true;
},
closeDeletePopup() {
this.showDeletePopup = false;
},
async markAccountForDeletion() {
this.closeDeletePopup();
try {
// Use the enterprise API to toggle deletion with delete action
await this.$store.dispatch('accounts/toggleDeletion', {
action_type: 'delete',
});
// Refresh account data
await this.$store.dispatch('accounts/get');
useAlert(this.$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SUCCESS'));
} catch (error) {
// Handle error message
this.handleDeletionError(error);
}
},
handleDeletionError(error) {
const errorKey = error.response?.data?.error_key;
if (errorKey) {
useAlert(
this.$t(`GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.${errorKey}`)
);
return;
}
const message = error.response?.data?.message;
if (message) {
useAlert(message);
return;
}
useAlert(this.$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.FAILURE'));
},
async clearDeletionMark() {
try {
// Use the enterprise API to toggle deletion with undelete action
await this.$store.dispatch('accounts/toggleDeletion', {
action_type: 'undelete',
});
// Refresh account data
await this.$store.dispatch('accounts/get');
useAlert(this.$t('GENERAL_SETTINGS.UPDATE.SUCCESS'));
} catch (error) {
useAlert(this.$t('GENERAL_SETTINGS.UPDATE.ERROR'));
}
},
},
};
</script>
<template>
<div class="flex flex-col w-full">
<BaseSettingsHeader :title="$t('GENERAL_SETTINGS.TITLE')">
<template #actions>
<V4Button blue :loading="isUpdating" @click="updateAccount">
{{ $t('GENERAL_SETTINGS.SUBMIT') }}
</V4Button>
</template>
</BaseSettingsHeader>
<div class="flex flex-col max-w-2xl mx-auto w-full">
<BaseSettingsHeader :title="$t('GENERAL_SETTINGS.TITLE')" />
<div class="flex-grow flex-shrink min-w-0 mt-3 overflow-auto">
<form v-if="!uiFlags.isFetchingItem" @submit.prevent="updateAccount">
<div
class="flex flex-row border-b border-slate-25 dark:border-slate-800"
<SectionLayout
:title="$t('GENERAL_SETTINGS.FORM.GENERAL_SECTION.TITLE')"
:description="$t('GENERAL_SETTINGS.FORM.GENERAL_SECTION.NOTE')"
>
<form
v-if="!uiFlags.isFetchingItem"
class="grid gap-4"
@submit.prevent="updateAccount"
>
<div
class="flex-grow-0 flex-shrink-0 flex-[25%] min-w-0 py-4 pr-6 pl-0"
<WithLabel
:has-error="v$.name.$error"
:label="$t('GENERAL_SETTINGS.FORM.NAME.LABEL')"
:error-message="$t('GENERAL_SETTINGS.FORM.NAME.ERROR')"
>
<h4 class="text-lg font-medium text-black-900 dark:text-slate-200">
{{ $t('GENERAL_SETTINGS.FORM.GENERAL_SECTION.TITLE') }}
</h4>
<p>{{ $t('GENERAL_SETTINGS.FORM.GENERAL_SECTION.NOTE') }}</p>
</div>
<div class="p-4 flex-grow-0 flex-shrink-0 flex-[50%]">
<label :class="{ error: v$.name.$error }">
{{ $t('GENERAL_SETTINGS.FORM.NAME.LABEL') }}
<input
v-model="name"
type="text"
:placeholder="$t('GENERAL_SETTINGS.FORM.NAME.PLACEHOLDER')"
@blur="v$.name.$touch"
/>
<span v-if="v$.name.$error" class="message">
{{ $t('GENERAL_SETTINGS.FORM.NAME.ERROR') }}
</span>
</label>
<label :class="{ error: v$.locale.$error }">
{{ $t('GENERAL_SETTINGS.FORM.LANGUAGE.LABEL') }}
<select v-model="locale">
<option
v-for="lang in languagesSortedByCode"
:key="lang.iso_639_1_code"
:value="lang.iso_639_1_code"
>
{{ lang.name }}
</option>
</select>
<span v-if="v$.locale.$error" class="message">
{{ $t('GENERAL_SETTINGS.FORM.LANGUAGE.ERROR') }}
</span>
</label>
<label v-if="featureInboundEmailEnabled">
{{ $t('GENERAL_SETTINGS.FORM.FEATURES.INBOUND_EMAIL_ENABLED') }}
</label>
<label v-if="featureCustomReplyDomainEnabled">
<NextInput
v-model="name"
type="text"
class="w-full"
:placeholder="$t('GENERAL_SETTINGS.FORM.NAME.PLACEHOLDER')"
@blur="v$.name.$touch"
/>
</WithLabel>
<WithLabel
:has-error="v$.locale.$error"
:label="$t('GENERAL_SETTINGS.FORM.LANGUAGE.LABEL')"
:error-message="$t('GENERAL_SETTINGS.FORM.LANGUAGE.ERROR')"
>
<select v-model="locale" class="!mb-0 text-sm">
<option
v-for="lang in languagesSortedByCode"
:key="lang.iso_639_1_code"
:value="lang.iso_639_1_code"
>
{{ lang.name }}
</option>
</select>
</WithLabel>
<WithLabel
v-if="featureCustomReplyDomainEnabled"
:label="$t('GENERAL_SETTINGS.FORM.DOMAIN.LABEL')"
>
<NextInput
v-model="domain"
type="text"
class="w-full"
:placeholder="$t('GENERAL_SETTINGS.FORM.DOMAIN.PLACEHOLDER')"
/>
<template #help>
{{
featureInboundEmailEnabled &&
$t('GENERAL_SETTINGS.FORM.FEATURES.INBOUND_EMAIL_ENABLED')
}}
{{
featureCustomReplyDomainEnabled &&
$t('GENERAL_SETTINGS.FORM.FEATURES.CUSTOM_EMAIL_DOMAIN_ENABLED')
}}
</label>
<label v-if="featureCustomReplyDomainEnabled">
{{ $t('GENERAL_SETTINGS.FORM.DOMAIN.LABEL') }}
<input
v-model="domain"
type="text"
:placeholder="$t('GENERAL_SETTINGS.FORM.DOMAIN.PLACEHOLDER')"
/>
</label>
<label v-if="featureCustomReplyEmailEnabled">
{{ $t('GENERAL_SETTINGS.FORM.SUPPORT_EMAIL.LABEL') }}
<input
v-model="supportEmail"
type="text"
:placeholder="
$t('GENERAL_SETTINGS.FORM.SUPPORT_EMAIL.PLACEHOLDER')
"
/>
</label>
<label
v-if="showAutoResolutionConfig"
:class="{ error: v$.autoResolveDuration.$error }"
>
{{ $t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.LABEL') }}
<input
v-model="autoResolveDuration"
type="number"
:placeholder="
$t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.PLACEHOLDER')
"
@blur="v$.autoResolveDuration.$touch"
/>
<span v-if="v$.autoResolveDuration.$error" class="message">
{{ $t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.ERROR') }}
</span>
</label>
</template>
</WithLabel>
<WithLabel
v-if="featureCustomReplyEmailEnabled"
:label="$t('GENERAL_SETTINGS.FORM.SUPPORT_EMAIL.LABEL')"
>
<NextInput
v-model="supportEmail"
type="text"
class="w-full"
:placeholder="
$t('GENERAL_SETTINGS.FORM.SUPPORT_EMAIL.PLACEHOLDER')
"
/>
</WithLabel>
<div>
<NextButton blue :is-loading="isUpdating" type="submit">
{{ $t('GENERAL_SETTINGS.SUBMIT') }}
</NextButton>
</div>
</div>
</form>
</form>
</SectionLayout>
<woot-loading-state v-if="uiFlags.isFetchingItem" />
</div>
<div class="flex flex-row">
<div class="flex-grow-0 flex-shrink-0 flex-[25%] min-w-0 py-4 pr-6 pl-0">
<h4 class="text-lg font-medium text-black-900 dark:text-slate-200">
{{ $t('GENERAL_SETTINGS.FORM.ACCOUNT_ID.TITLE') }}
</h4>
<p>
{{ $t('GENERAL_SETTINGS.FORM.ACCOUNT_ID.NOTE') }}
</p>
</div>
<div class="p-4 flex-grow-0 flex-shrink-0 flex-[50%]">
<woot-code :script="getAccountId" />
</div>
</div>
<AutoResolve v-if="showAutoResolutionConfig" />
<AccountId />
<div v-if="!uiFlags.isFetchingItem && isOnChatwootCloud">
<div
class="flex flex-row pt-4 mt-2 border-t border-slate-25 dark:border-slate-800 text-black-900 dark:text-slate-300"
>
<div
class="flex-grow-0 flex-shrink-0 flex-[25%] min-w-0 py-4 pr-6 pl-0"
>
<h4 class="text-lg font-medium text-black-900 dark:text-slate-200">
{{ $t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.TITLE') }}
</h4>
<p>
{{ $t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.NOTE') }}
</p>
</div>
<div class="p-4 flex-grow-0 flex-shrink-0 flex-[50%]">
<div v-if="isMarkedForDeletion">
<div
class="p-4 flex-grow-0 flex-shrink-0 flex-[50%] bg-red-50 dark:bg-red-900 rounded"
>
<p class="mb-4">
{{
$t(
`GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SCHEDULED_DELETION.MESSAGE_${markedForDeletionReason === 'manual_deletion' ? 'MANUAL' : 'INACTIVITY'}`,
{
deletionDate: formattedDeletionDate,
}
)
}}
</p>
<NextButton
:label="
$t(
'GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SCHEDULED_DELETION.CLEAR_BUTTON'
)
"
color="ruby"
:is-loading="uiFlags.isUpdating"
@click="clearDeletionMark"
/>
</div>
</div>
<div v-if="!isMarkedForDeletion">
<NextButton
:label="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.BUTTON_TEXT')"
color="ruby"
@click="openDeletePopup()"
/>
</div>
</div>
</div>
<WootConfirmDeleteModal
v-if="showDeletePopup"
v-model:show="showDeletePopup"
:title="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.TITLE')"
:message="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.MESSAGE')"
:confirm-text="
$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.BUTTON_TEXT')
"
:reject-text="
$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.DISMISS')
"
:confirm-value="name"
:confirm-place-holder-text="confirmPlaceHolderText"
@on-confirm="markAccountForDeletion"
@on-close="closeDeletePopup"
/>
</div>
<div class="p-4 text-sm text-center">
<div>{{ `v${globalConfig.appVersion}` }}</div>
<div v-if="hasAnUpdateAvailable && globalConfig.displayManifest">
{{
$t('GENERAL_SETTINGS.UPDATE_CHATWOOT', {
latestChatwootVersion: latestChatwootVersion,
})
}}
</div>
<div class="build-id">
<div>{{ `Build ${globalConfig.gitSha}` }}</div>
</div>
<AccountDelete />
</div>
<BuildInfo />
</div>
</template>
@@ -0,0 +1,149 @@
<script setup>
import { computed } from 'vue';
import { useStore, useMapGetter } from 'dashboard/composables/store';
import { useAccount } from 'dashboard/composables/useAccount';
import { useI18n } from 'vue-i18n';
import { useToggle } from '@vueuse/core';
import { useAlert } from 'dashboard/composables';
import WootConfirmDeleteModal from 'dashboard/components/widgets/modal/ConfirmDeleteModal.vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
import SectionLayout from './SectionLayout.vue';
const { t } = useI18n();
const store = useStore();
const uiFlags = useMapGetter('accounts/getUIFlags');
const { currentAccount } = useAccount();
const [showDeletePopup, toggleDeletePopup] = useToggle();
const confirmPlaceHolderText = computed(() => {
return `${t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.PLACE_HOLDER', {
accountName: currentAccount.value.name,
})}`;
});
const isMarkedForDeletion = computed(() => {
const { custom_attributes = {} } = currentAccount.value;
return !!custom_attributes.marked_for_deletion_at;
});
const markedForDeletionDate = computed(() => {
const { custom_attributes = {} } = currentAccount.value;
if (!custom_attributes.marked_for_deletion_at) return null;
return new Date(custom_attributes.marked_for_deletion_at);
});
const markedForDeletionReason = computed(() => {
const { custom_attributes = {} } = currentAccount.value;
return custom_attributes.marked_for_deletion_reason || 'manual_deletion';
});
const formattedDeletionDate = computed(() => {
if (!markedForDeletionDate.value) return '';
return markedForDeletionDate.value.toLocaleString();
});
const markedForDeletionMessage = computed(() => {
const params = { deletionDate: formattedDeletionDate.value };
if (markedForDeletionReason.value === 'manual_deletion') {
return t(
`GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SCHEDULED_DELETION.MESSAGE_MANUAL`,
params
);
}
return t(
`GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SCHEDULED_DELETION.MESSAGE_INACTIVITY`,
params
);
});
function handleDeletionError(error) {
const message = error.response?.data?.message;
if (message) {
useAlert(message);
return;
}
useAlert(t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.FAILURE'));
}
async function markAccountForDeletion() {
toggleDeletePopup(false);
try {
// Use the enterprise API to toggle deletion with delete action
await store.dispatch('accounts/toggleDeletion', {
action_type: 'delete',
});
// Refresh account data
await store.dispatch('accounts/get');
useAlert(t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SUCCESS'));
} catch (error) {
// Handle error message
handleDeletionError(error);
}
}
async function clearDeletionMark() {
try {
// Use the enterprise API to toggle deletion with undelete action
await store.dispatch('accounts/toggleDeletion', {
action_type: 'undelete',
});
// Refresh account data
await store.dispatch('accounts/get');
useAlert(t('GENERAL_SETTINGS.UPDATE.SUCCESS'));
} catch (error) {
useAlert(t('GENERAL_SETTINGS.UPDATE.ERROR'));
}
}
</script>
<template>
<SectionLayout
:title="t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.TITLE')"
:description="t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.NOTE')"
with-border
>
<div v-if="isMarkedForDeletion">
<div
class="p-4 flex-grow-0 flex-shrink-0 flex-[50%] bg-red-50 dark:bg-red-900 rounded"
>
<p class="mb-4">
{{ markedForDeletionMessage }}
</p>
<NextButton
:label="
$t(
'GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.SCHEDULED_DELETION.CLEAR_BUTTON'
)
"
color="ruby"
:is-loading="uiFlags.isUpdating"
@click="clearDeletionMark"
/>
</div>
</div>
<div v-if="!isMarkedForDeletion">
<NextButton
:label="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.BUTTON_TEXT')"
color="ruby"
@click="toggleDeletePopup(true)"
/>
</div>
</SectionLayout>
<WootConfirmDeleteModal
v-if="showDeletePopup"
v-model:show="showDeletePopup"
:title="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.TITLE')"
:message="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.MESSAGE')"
:confirm-text="
$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.BUTTON_TEXT')
"
:reject-text="$t('GENERAL_SETTINGS.ACCOUNT_DELETE_SECTION.CONFIRM.DISMISS')"
:confirm-value="currentAccount.name"
:confirm-place-holder-text="confirmPlaceHolderText"
@on-confirm="markAccountForDeletion"
@on-close="toggleDeletePopup(false)"
/>
</template>
@@ -0,0 +1,22 @@
<script setup>
import { computed } from 'vue';
import { useAccount } from 'dashboard/composables/useAccount';
import { useI18n } from 'vue-i18n';
import SectionLayout from './SectionLayout.vue';
const { t } = useI18n();
const { currentAccount } = useAccount();
const getAccountId = computed(() => currentAccount.value.id.toString());
</script>
<template>
<SectionLayout
:title="t('GENERAL_SETTINGS.FORM.ACCOUNT_ID.TITLE')"
:description="t('GENERAL_SETTINGS.FORM.ACCOUNT_ID.NOTE')"
with-border
>
<woot-code :script="getAccountId" />
</SectionLayout>
</template>
@@ -0,0 +1,119 @@
<script setup>
import { ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useAccount } from 'dashboard/composables/useAccount';
import { useAlert } from 'dashboard/composables';
import SectionLayout from './SectionLayout.vue';
import WithLabel from 'v3/components/Form/WithLabel.vue';
import DurationInput from 'next/input/DurationInput.vue';
import TextArea from 'next/textarea/TextArea.vue';
import Switch from 'next/switch/Switch.vue';
import NextButton from 'dashboard/components-next/button/Button.vue';
const { t } = useI18n();
const duration = ref(0);
const message = ref('');
const isEnabled = ref(false);
const { currentAccount, updateAccount } = useAccount();
watch(
currentAccount,
() => {
const { auto_resolve_after, auto_resolve_message } =
currentAccount.value?.settings || {};
duration.value = auto_resolve_after;
message.value = auto_resolve_message;
if (duration.value) {
isEnabled.value = true;
}
},
{ deep: true, immediate: true }
);
const updateAccountSettings = async settings => {
try {
await updateAccount(settings);
useAlert(t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.API.SUCCESS'));
} catch (error) {
useAlert(t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.API.ERROR'));
}
};
const handleSubmit = async () => {
return updateAccountSettings({
auto_resolve_after: duration.value,
auto_resolve_message: message.value,
});
};
const handleDisable = async () => {
duration.value = null;
message.value = '';
return updateAccountSettings({
auto_resolve_after: null,
auto_resolve_message: '',
});
};
const toggleAutoResolve = async () => {
if (!isEnabled.value) handleDisable();
};
</script>
<template>
<SectionLayout
:title="t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE.TITLE')"
:description="t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE.NOTE')"
with-border
>
<template #headerActions>
<div class="flex justify-end">
<Switch v-model="isEnabled" @change="toggleAutoResolve" />
</div>
</template>
<form class="grid gap-4" @submit.prevent="handleSubmit">
<WithLabel
:label="t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.LABEL')"
:help-message="t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.HELP')"
>
<div class="gap-2 w-full grid grid-cols-[3fr_1fr]">
<!-- allow 10 mins to 999 days -->
<DurationInput
v-model="duration"
min="10"
max="1439856"
class="w-full"
/>
</div>
</WithLabel>
<WithLabel
:label="t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.MESSAGE_LABEL')"
:help-message="
t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.MESSAGE_HELP')
"
>
<TextArea
v-model="message"
class="w-full"
:placeholder="
t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.MESSAGE_PLACEHOLDER')
"
/>
</WithLabel>
<div class="flex gap-2">
<NextButton
blue
type="submit"
:label="
t('GENERAL_SETTINGS.FORM.AUTO_RESOLVE_DURATION.UPDATE_BUTTON')
"
/>
</div>
</form>
</SectionLayout>
</template>
@@ -0,0 +1,56 @@
<script setup>
import { computed } from 'vue';
import { useAccount } from 'dashboard/composables/useAccount';
import { useMapGetter } from 'dashboard/composables/store';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
import { useI18n } from 'vue-i18n';
import semver from 'semver';
const { t } = useI18n();
const { currentAccount } = useAccount();
const latestChatwootVersion = computed(() => {
return currentAccount.value.latest_chatwoot_version;
});
const globalConfig = useMapGetter('globalConfig/get');
const hasAnUpdateAvailable = computed(() => {
if (!semver.valid(latestChatwootVersion.value)) {
return false;
}
return semver.lt(globalConfig.value.appVersion, latestChatwootVersion.value);
});
const gitSha = computed(() => {
return globalConfig.value.gitSha.substring(0, 7);
});
const copyGitSha = () => {
copyTextToClipboard(globalConfig.value.gitSha);
};
</script>
<template>
<div class="p-4 text-sm text-center">
<div v-if="hasAnUpdateAvailable && globalConfig.displayManifest">
{{
t('GENERAL_SETTINGS.UPDATE_CHATWOOT', {
latestChatwootVersion: latestChatwootVersion,
})
}}
</div>
<div class="divide-x divide-n-slate-9">
<span class="px-2">{{ `v${globalConfig.appVersion}` }}</span>
<span
v-tooltip="t('COMPONENTS.CODE.BUTTON_TEXT')"
class="px-2 build-id cursor-pointer"
@click="copyGitSha"
>
{{ `Build ${gitSha}` }}
</span>
</div>
</div>
</template>
@@ -0,0 +1,40 @@
<script setup>
defineProps({
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
withBorder: {
type: Boolean,
default: false,
},
});
</script>
<template>
<section
class="grid grid-cols-1 py-8 gap-10"
:class="{ 'border-t border-n-weak': withBorder }"
>
<header class="grid grid-cols-4">
<div class="col-span-3">
<h4 class="text-lg font-medium text-n-slate-12">
<slot name="title">{{ title }}</slot>
</h4>
<p class="text-n-slate-11">
<slot name="description">{{ description }}</slot>
</p>
</div>
<div class="col-span-1">
<slot name="headerActions" />
</div>
</header>
<div class="text-n-slate-12">
<slot />
</div>
</section>
</template>
@@ -66,7 +66,8 @@ export const actions = {
update: async ({ commit }, updateObj) => {
commit(types.default.SET_ACCOUNT_UI_FLAG, { isUpdating: true });
try {
await AccountAPI.update('', updateObj);
const response = await AccountAPI.update('', updateObj);
commit(types.default.EDIT_ACCOUNT, response.data);
commit(types.default.SET_ACCOUNT_UI_FLAG, { isUpdating: false });
} catch (error) {
commit(types.default.SET_ACCOUNT_UI_FLAG, { isUpdating: false });
@@ -39,10 +39,13 @@ describe('#actions', () => {
describe('#update', () => {
it('sends correct actions if API is success', async () => {
axios.patch.mockResolvedValue();
axios.patch.mockResolvedValue({
data: { id: 1, name: 'John' },
});
await actions.update({ commit, getters }, accountData);
expect(commit.mock.calls).toEqual([
[types.default.SET_ACCOUNT_UI_FLAG, { isUpdating: true }],
[types.default.EDIT_ACCOUNT, { id: 1, name: 'John' }],
[types.default.SET_ACCOUNT_UI_FLAG, { isUpdating: false }],
]);
});
+12 -6
View File
@@ -23,12 +23,18 @@ const runSDK = ({ baseUrl, websiteToken }) => {
return;
}
if (window.Turbo) {
// if this is a Rails Turbo app
document.addEventListener('turbo:before-render', event =>
restoreWidgetInDOM(event.detail.newBody)
);
}
// if this is a Rails Turbo app
document.addEventListener('turbo:before-render', event => {
// when morphing the page, this typically happens on reload like events
// say you update a "Customer" on a form and it reloads the page
// We have already added data-turbo-permananent to true. This
// will ensure that the widget it preserved
// Read more about morphing here: https://turbo.hotwired.dev/handbook/page_refreshes#morphing
// and peristing elements here: https://turbo.hotwired.dev/handbook/building#persisting-elements-across-page-loads
if (event.detail.renderMethod === 'morph') return;
restoreWidgetInDOM(event.detail.newBody);
});
if (window.Turbolinks) {
document.addEventListener('turbolinks:before-render', event => {
+1
View File
@@ -5,6 +5,7 @@ export const loadCSS = () => {
const css = document.createElement('style');
css.innerHTML = `${SDK_CSS}`;
css.id = 'cw-widget-styles';
css.dataset.turboPermanent = true;
document.body.appendChild(css);
};
+1
View File
@@ -82,6 +82,7 @@ export const IFrameHelper = {
addClasses(widgetHolder, holderClassName);
widgetHolder.id = 'cw-widget-holder';
widgetHolder.dataset.turboPermanent = true;
widgetHolder.appendChild(iframe);
body.appendChild(widgetHolder);
IFrameHelper.initPostMessageCommunication();
+1
View File
@@ -67,6 +67,7 @@ export const createBubbleHolder = hideMessageBubble => {
}
addClasses(bubbleHolder, 'woot--bubble-holder');
bubbleHolder.id = 'cw-bubble-holder';
bubbleHolder.dataset.turboPermanent = true;
body.appendChild(bubbleHolder);
};
+23 -31
View File
@@ -1,28 +1,12 @@
<script>
export default {
props: {
label: {
type: String,
default: '',
},
name: {
type: String,
required: true,
},
icon: {
type: String,
default: '',
},
hasError: {
type: Boolean,
default: false,
},
errorMessage: {
type: String,
default: '',
},
},
};
<script setup>
defineProps({
label: { type: String, default: '' },
name: { type: String, required: true },
icon: { type: String, default: '' },
hasError: { type: Boolean, default: false },
helpMessage: { type: String, default: '' },
errorMessage: { type: String, default: '' },
});
</script>
<template>
@@ -30,8 +14,8 @@ export default {
<label
v-if="label"
:for="name"
class="flex justify-between text-sm font-medium leading-6 text-slate-900 dark:text-white"
:class="{ 'text-red-500': hasError }"
class="flex justify-between text-sm font-medium leading-6 text-n-slate-12"
:class="{ 'text-n-ruby-12': hasError }"
>
<slot name="label">
{{ label }}
@@ -44,16 +28,24 @@ export default {
v-if="icon"
size="16"
:icon="icon"
class="absolute left-2 transform text-slate-400 dark:text-slate-600 w-5 h-5"
class="absolute left-2 transform text-n-slate-9 w-5 h-5"
/>
<slot />
</div>
<span
<div
v-if="errorMessage && hasError"
class="text-xs text-n-ruby-9 dark:text-n-ruby-9 leading-2"
class="text-xs mt-2 ml-px text-n-ruby-9 leading-tight"
>
{{ errorMessage }}
</span>
</div>
<div
v-else-if="helpMessage || $slots.help"
class="text-xs mt-2 ml-px text-n-slate-10 leading-tight"
>
<slot name="help">
{{ helpMessage }}
</slot>
</div>
</div>
</div>
</template>
@@ -2,7 +2,7 @@ class Account::ConversationsResolutionSchedulerJob < ApplicationJob
queue_as :scheduled_jobs
def perform
Account.where.not(auto_resolve_duration: nil).all.find_each(batch_size: 100) do |account|
Account.with_auto_resolve.find_each(batch_size: 100) do |account|
Conversations::ResolutionJob.perform_later(account: account)
end
end
+7 -2
View File
@@ -3,7 +3,12 @@ class Conversations::ResolutionJob < ApplicationJob
def perform(account:)
# limiting the number of conversations to be resolved to avoid any performance issues
resolvable_conversations = account.conversations.resolvable(account.auto_resolve_duration).limit(Limits::BULK_ACTIONS_LIMIT)
resolvable_conversations.each(&:toggle_status)
resolvable_conversations = account.conversations.resolvable(account.auto_resolve_after).limit(Limits::BULK_ACTIONS_LIMIT)
resolvable_conversations.each do |conversation|
# send message from bot that conversation has been resolved
# do this is account.auto_resolve_message is set
::MessageTemplates::Template::AutoResolve.new(conversation: conversation).perform if account.auto_resolve_message.present?
conversation.toggle_status
end
end
end
@@ -5,7 +5,7 @@
# - are older than 30 days
class Internal::ProcessStaleContactsJob < ApplicationJob
queue_as :scheduled_jobs
queue_as :housekeeping
def perform
return unless ChatwootApp.chatwoot_cloud?
@@ -5,7 +5,7 @@
# - are older than 30 days
class Internal::RemoveStaleContactsJob < ApplicationJob
queue_as :low
queue_as :housekeeping
def perform(account, batch_size = 1000)
Internal::RemoveStaleContactsService.new(account: account).perform(batch_size)
+19 -1
View File
@@ -11,6 +11,7 @@
# limits :jsonb
# locale :integer default("en")
# name :string not null
# settings :jsonb
# status :integer default("active")
# support_email :string(100)
# created_at :datetime not null
@@ -28,13 +29,28 @@ class Account < ApplicationRecord
include Featurable
include CacheKeys
SETTINGS_PARAMS_SCHEMA = {
'type': 'object',
'properties':
{
'auto_resolve_after': { 'type': %w[integer null], 'minimum': 10, 'maximum': 1_439_856 },
'auto_resolve_message': { 'type': %w[string null] }
},
'required': [],
'additionalProperties': false
}.to_json.freeze
DEFAULT_QUERY_SETTING = {
flag_query_mode: :bit_operator,
check_for_column: false
}.freeze
validates :auto_resolve_duration, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: 999, allow_nil: true }
validates :domain, length: { maximum: 100 }
validates_with JsonSchemaValidator,
schema: SETTINGS_PARAMS_SCHEMA,
attribute_resolver: ->(record) { record.settings }
store_accessor :settings, :auto_resolve_after, :auto_resolve_message
has_many :account_users, dependent: :destroy_async
has_many :agent_bot_inboxes, dependent: :destroy_async
@@ -83,6 +99,8 @@ class Account < ApplicationRecord
enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h
enum status: { active: 0, suspended: 1 }
scope :with_auto_resolve, -> { where("(settings ->> 'auto_resolve_after')::int IS NOT NULL") }
before_validation :validate_limit_keys
after_create_commit :notify_creation
after_destroy :remove_account_sequences
@@ -56,13 +56,24 @@ module ActivityMessageHandler
::Conversations::ActivityMessageJob.perform_later(self, activity_message_params(content)) if content
end
def auto_resolve_message_key(minutes)
if minutes >= 1440 && (minutes % 1440).zero?
{ key: 'auto_resolved_days', count: minutes / 1440 }
elsif minutes >= 60 && (minutes % 60).zero?
{ key: 'auto_resolved_hours', count: minutes / 60 }
else
{ key: 'auto_resolved_minutes', count: minutes }
end
end
def user_status_change_activity_content(user_name)
if user_name
I18n.t("conversations.activity.status.#{status}", user_name: user_name)
elsif Current.contact.present? && resolved?
I18n.t('conversations.activity.status.contact_resolved', contact_name: Current.contact.name.capitalize)
elsif resolved?
I18n.t('conversations.activity.status.auto_resolved', duration: auto_resolve_duration)
message_data = auto_resolve_message_key(auto_resolve_after || 0)
I18n.t("conversations.activity.status.#{message_data[:key]}", count: message_data[:count])
end
end
@@ -56,6 +56,8 @@ class JsonSchemaValidator < ActiveModel::Validator
def format_and_append_error(error, record)
return handle_required(error, record) if error['type'] == 'required'
return handle_minimum(error, record) if error['type'] == 'minimum'
return handle_maximum(error, record) if error['type'] == 'maximum'
type = error['type'] == 'object' ? 'hash' : error['type']
@@ -74,6 +76,16 @@ class JsonSchemaValidator < ActiveModel::Validator
record.errors.add(data, "must be of type #{expected_type}")
end
def handle_minimum(error, record)
data = get_name_from_data_pointer(error)
record.errors.add(data, "must be greater than or equal to #{error['schema']['minimum']}")
end
def handle_maximum(error, record)
data = get_name_from_data_pointer(error)
record.errors.add(data, "must be less than or equal to #{error['schema']['maximum']}")
end
def get_name_from_data_pointer(error)
data = error['data_pointer']
+4 -4
View File
@@ -76,10 +76,10 @@ class Conversation < ApplicationRecord
scope :assigned, -> { where.not(assignee_id: nil) }
scope :assigned_to, ->(agent) { where(assignee_id: agent.id) }
scope :unattended, -> { where(first_reply_created_at: nil).or(where.not(waiting_since: nil)) }
scope :resolvable, lambda { |auto_resolve_duration|
return none if auto_resolve_duration.to_i.zero?
scope :resolvable, lambda { |auto_resolve_after|
return none if auto_resolve_after.to_i.zero?
open.where('last_activity_at < ? ', Time.now.utc - auto_resolve_duration.days)
open.where('last_activity_at < ? AND waiting_since IS NULL', Time.now.utc - auto_resolve_after.minutes)
}
scope :last_user_message_at, lambda {
@@ -112,7 +112,7 @@ class Conversation < ApplicationRecord
after_create_commit :notify_conversation_creation
after_create_commit :load_attributes_created_by_db_triggers
delegate :auto_resolve_duration, to: :account
delegate :auto_resolve_after, to: :account
def can_reply?
Conversations::MessageWindowService.new(self).can_reply?
+1 -1
View File
@@ -44,7 +44,7 @@ class Instagram::MessageText < Instagram::BaseMessageText
Rails.logger.warn("[InstagramUserFetchError]: account_id #{@inbox.account_id} inbox_id #{@inbox.id}")
Rails.logger.warn("[InstagramUserFetchError]: #{error_message} #{error_code}")
ChatwootExceptionTracker.new(error, account: @inbox.account).capture_exception
ChatwootExceptionTracker.new(parsed_response, account: @inbox.account).capture_exception
end
def base_uri
@@ -0,0 +1,25 @@
class MessageTemplates::Template::AutoResolve
pattr_initialize [:conversation!]
def perform
return if conversation.account.auto_resolve_message.blank?
ActiveRecord::Base.transaction do
conversation.messages.create!(auto_resolve_message_params)
end
end
private
delegate :contact, :account, to: :conversation
delegate :inbox, to: :message
def auto_resolve_message_params
{
account_id: @conversation.account_id,
inbox_id: @conversation.inbox_id,
message_type: :template,
content: account.auto_resolve_message
}
end
end
@@ -1,4 +1,4 @@
json.auto_resolve_duration resource.auto_resolve_duration
json.settings resource.settings
json.created_at resource.created_at
if resource.custom_attributes.present?
json.custom_attributes do
+3 -1
View File
@@ -159,7 +159,9 @@ en:
open: 'Conversation was reopened by %{user_name}'
pending: 'Conversation was marked as pending by %{user_name}'
snoozed: 'Conversation was snoozed by %{user_name}'
auto_resolved: 'Conversation was marked resolved by system due to %{duration} days of inactivity'
auto_resolved_days: 'Conversation was marked resolved by system due to %{count} days of inactivity'
auto_resolved_hours: 'Conversation was marked resolved by system due to %{count} hours of inactivity'
auto_resolved_minutes: 'Conversation was marked resolved by system due to %{count} minutes of inactivity'
system_auto_open: System reopened the conversation due to a new incoming message.
priority:
added: '%{user_name} set the priority to %{new_priority}'
+1 -1
View File
@@ -38,4 +38,4 @@ remove_stale_redis_keys_job.rb:
process_stale_contacts_job:
cron: '30 04 * * *'
class: 'Internal::ProcessStaleContactsJob'
queue: scheduled_jobs
queue: housekeeping

Some files were not shown because too many files have changed in this diff Show More