diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb
index 011faaf28..61d16b2ca 100644
--- a/app/controllers/api/v1/accounts/inboxes_controller.rb
+++ b/app/controllers/api/v1/accounts/inboxes_controller.rb
@@ -42,7 +42,9 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController
end
def update
- @inbox.update!(permitted_params.except(:channel))
+ inbox_params = permitted_params.except(:channel, :csat_config)
+ inbox_params[:csat_config] = format_csat_config(permitted_params[:csat_config]) if permitted_params[:csat_config].present?
+ @inbox.update!(inbox_params)
update_inbox_working_hours
update_channel if channel_update_required?
end
@@ -121,10 +123,22 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController
@inbox.channel.save!
end
+ def format_csat_config(config)
+ {
+ display_type: config['display_type'] || 'emoji',
+ message: config['message'] || '',
+ survey_rules: {
+ operator: config.dig('survey_rules', 'operator') || 'contains',
+ values: config.dig('survey_rules', 'values') || []
+ }
+ }
+ end
+
def inbox_attributes
[:name, :avatar, :greeting_enabled, :greeting_message, :enable_email_collect, :csat_survey_enabled,
:enable_auto_assignment, :working_hours_enabled, :out_of_office_message, :timezone, :allow_messages_after_resolved,
- :lock_to_single_conversation, :portal_id, :sender_name_type, :business_name]
+ :lock_to_single_conversation, :portal_id, :sender_name_type, :business_name,
+ { csat_config: [:display_type, :message, { survey_rules: [:operator, { values: [] }] }] }]
end
def permitted_params(channel_attributes = [])
diff --git a/app/javascript/dashboard/components-next/filter/inputs/FilterSelect.vue b/app/javascript/dashboard/components-next/filter/inputs/FilterSelect.vue
index db420920b..56bce8f9d 100644
--- a/app/javascript/dashboard/components-next/filter/inputs/FilterSelect.vue
+++ b/app/javascript/dashboard/components-next/filter/inputs/FilterSelect.vue
@@ -25,6 +25,10 @@ const props = defineProps({
type: String,
default: 'faded',
},
+ label: {
+ type: String,
+ default: null,
+ },
});
const selected = defineModel({
@@ -56,7 +60,7 @@ const updateSelected = newValue => {
:variant
:icon="iconToRender"
:trailing-icon="selectedOption.icon ? false : true"
- :label="hideLabel ? null : selectedOption.label"
+ :label="label || (hideLabel ? null : selectedOption.label)"
@click="toggle"
/>
diff --git a/app/javascript/dashboard/components-next/message/bubbles/CSAT.vue b/app/javascript/dashboard/components-next/message/bubbles/CSAT.vue
index 211840944..6f86bd868 100644
--- a/app/javascript/dashboard/components-next/message/bubbles/CSAT.vue
+++ b/app/javascript/dashboard/components-next/message/bubbles/CSAT.vue
@@ -2,10 +2,10 @@
import { computed } from 'vue';
import BaseBubble from './Base.vue';
import { useI18n } from 'vue-i18n';
-import { CSAT_RATINGS } from 'shared/constants/messages';
+import { CSAT_RATINGS, CSAT_DISPLAY_TYPES } from 'shared/constants/messages';
import { useMessageContext } from '../provider.js';
-const { contentAttributes } = useMessageContext();
+const { contentAttributes, content } = useMessageContext();
const { t } = useI18n();
const response = computed(() => {
@@ -16,6 +16,14 @@ const isRatingSubmitted = computed(() => {
return !!response.value.rating;
});
+const displayType = computed(() => {
+ return contentAttributes.value?.displayType || CSAT_DISPLAY_TYPES.EMOJI;
+});
+
+const isStarRating = computed(() => {
+ return displayType.value === CSAT_DISPLAY_TYPES.STAR;
+});
+
const rating = computed(() => {
if (isRatingSubmitted.value) {
return CSAT_RATINGS.find(
@@ -25,16 +33,33 @@ const rating = computed(() => {
return null;
});
+
+const starRatingValue = computed(() => {
+ return response.value.rating || 0;
+});
- {{ t('CONVERSATION.CSAT_REPLY_MESSAGE') }}
+ {{ content || t('CONVERSATION.CSAT_REPLY_MESSAGE') }}
-
{{ t('CONVERSATION.RATING_TITLE') }}
- - {{ t(rating.translationKey) }}
+ -
+ {{ t(rating.translationKey) }}
+
+ -
+
+
+
+
-
{{ t('CONVERSATION.FEEDBACK_TITLE') }}
diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
index 5716e050c..cc0fe4b33 100644
--- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
+++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
@@ -481,7 +481,8 @@
"PRE_CHAT_FORM": "Pre Chat Form",
"BUSINESS_HOURS": "Business Hours",
"WIDGET_BUILDER": "Widget Builder",
- "BOT_CONFIGURATION": "Bot Configuration"
+ "BOT_CONFIGURATION": "Bot Configuration",
+ "CSAT": "CSAT"
},
"SETTINGS": "Settings",
"FEATURES": {
@@ -502,9 +503,7 @@
"ENABLE_EMAIL_COLLECT_BOX": "Enable email collect box",
"ENABLE_EMAIL_COLLECT_BOX_SUB_TEXT": "Enable or disable email collect box on new conversation",
"AUTO_ASSIGNMENT": "Enable auto assignment",
- "ENABLE_CSAT": "Enable CSAT",
"SENDER_NAME_SECTION": "Enable Agent Name in Email",
- "ENABLE_CSAT_SUB_TEXT": "Enable/Disable CSAT(Customer satisfaction) survey after resolving a conversation",
"SENDER_NAME_SECTION_TEXT": "Enable/Disable showing Agent's name in email, if disabled it will show business name",
"ENABLE_CONTINUITY_VIA_EMAIL": "Enable conversation continuity via email",
"ENABLE_CONTINUITY_VIA_EMAIL_SUB_TEXT": "Conversations will continue over email if the contact email address is available.",
@@ -578,6 +577,32 @@
"LABEL": "Visitors should provide their name and email address before starting the chat"
}
},
+ "CSAT": {
+ "TITLE": "Enable CSAT",
+ "SUBTITLE": "Automatically trigger CSAT surveys at the end of conversations to understand how customers feel about their support experience. Track satisfaction trends and identify areas for improvement over time.",
+ "DISPLAY_TYPE": {
+ "LABEL": "Display type"
+ },
+ "MESSAGE": {
+ "LABEL": "Message",
+ "PLACEHOLDER": "Please enter a message to show users with the form"
+ },
+ "SURVEY_RULE": {
+ "LABEL": "Survey rule",
+ "DESCRIPTION_PREFIX": "Send the survey if the conversation",
+ "DESCRIPTION_SUFFIX": "any of the labels",
+ "OPERATOR": {
+ "CONTAINS": "contains",
+ "DOES_NOT_CONTAINS": "does not contain"
+ },
+ "SELECT_PLACEHOLDER": "select labels"
+ },
+ "NOTE": "Note: CSAT surveys are sent only once per conversation",
+ "API": {
+ "SUCCESS_MESSAGE": "CSAT settings updated successfully",
+ "ERROR_MESSAGE": "We couldn't update CSAT settings. Please try again later."
+ }
+ },
"BUSINESS_HOURS": {
"TITLE": "Set your availability",
"SUBTITLE": "Set your availability on your livechat widget",
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue
index 73d9963bd..d9551c427 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue
@@ -15,6 +15,7 @@ import PreChatFormSettings from './PreChatForm/Settings.vue';
import WeeklyAvailability from './components/WeeklyAvailability.vue';
import GreetingsEditor from 'shared/components/GreetingsEditor.vue';
import ConfigurationPage from './settingsPage/ConfigurationPage.vue';
+import CustomerSatisfactionPage from './settingsPage/CustomerSatisfactionPage.vue';
import CollaboratorsPage from './settingsPage/CollaboratorsPage.vue';
import WidgetBuilder from './WidgetBuilder.vue';
import BotConfiguration from './components/BotConfiguration.vue';
@@ -28,6 +29,7 @@ export default {
BotConfiguration,
CollaboratorsPage,
ConfigurationPage,
+ CustomerSatisfactionPage,
FacebookReauthorize,
GreetingsEditor,
PreChatFormSettings,
@@ -53,7 +55,6 @@ export default {
greetingEnabled: true,
greetingMessage: '',
emailCollectEnabled: false,
- csatSurveyEnabled: false,
senderNameType: 'friendly',
businessName: '',
locktoSingleConversation: false,
@@ -107,6 +108,10 @@ export default {
key: 'businesshours',
name: this.$t('INBOX_MGMT.TABS.BUSINESS_HOURS'),
},
+ {
+ key: 'csat',
+ name: this.$t('INBOX_MGMT.TABS.CSAT'),
+ },
];
if (this.isAWebWidgetInbox) {
@@ -277,7 +282,6 @@ export default {
this.greetingEnabled = this.inbox.greeting_enabled || false;
this.greetingMessage = this.inbox.greeting_message || '';
this.emailCollectEnabled = this.inbox.enable_email_collect;
- this.csatSurveyEnabled = this.inbox.csat_survey_enabled;
this.senderNameType = this.inbox.sender_name_type;
this.businessName = this.inbox.business_name;
this.allowMessagesAfterResolved =
@@ -300,7 +304,6 @@ export default {
id: this.currentInboxId,
name: this.selectedInboxName,
enable_email_collect: this.emailCollectEnabled,
- csat_survey_enabled: this.csatSurveyEnabled,
allow_messages_after_resolved: this.allowMessagesAfterResolved,
greeting_enabled: this.greetingEnabled,
greeting_message: this.greetingMessage || '',
@@ -589,21 +592,6 @@ export default {
-
-