fix: render markdown in CSAT survey messages (#14468)

This commit is contained in:
Sivin Varghese
2026-05-19 10:27:14 +05:30
committed by GitHub
parent 4371793741
commit 497d34c097
4 changed files with 30 additions and 9 deletions
@@ -1,6 +1,7 @@
<script setup>
import { computed } from 'vue';
import BaseBubble from './Base.vue';
import FormattedContent from './Text/FormattedContent.vue';
import { useI18n } from 'vue-i18n';
import { CSAT_RATINGS, CSAT_DISPLAY_TYPES } from 'shared/constants/messages';
import { useMessageContext } from '../provider.js';
@@ -41,7 +42,8 @@ const starRatingValue = computed(() => {
<template>
<BaseBubble class="px-4 py-3" data-bubble-name="csat">
<h4>{{ content || t('CONVERSATION.CSAT_REPLY_MESSAGE') }}</h4>
<FormattedContent v-if="content" :content="content" />
<h4 v-else>{{ t('CONVERSATION.CSAT_REPLY_MESSAGE') }}</h4>
<dl v-if="isRatingSubmitted" class="mt-4">
<dt class="text-n-slate-11 italic">
{{ t('CONVERSATION.RATING_TITLE') }}
+3
View File
@@ -1,8 +1,10 @@
import { createApp } from 'vue';
import { createI18n } from 'vue-i18n';
import VueDOMPurifyHTML from 'vue-dompurify-html';
import store from '../survey/store';
import i18nMessages from '../survey/i18n';
import App from '../survey/App.vue';
import { domPurifyConfig } from '../shared/helpers/HTMLSanitizer';
const app = createApp(App);
const i18n = createI18n({
@@ -12,6 +14,7 @@ const i18n = createI18n({
app.use(i18n);
app.use(store);
app.use(VueDOMPurifyHTML, domPurifyConfig);
window.onload = () => {
window.WOOT_SURVEY = app.mount('#app');
@@ -4,6 +4,7 @@ import Spinner from 'shared/components/Spinner.vue';
import { CSAT_RATINGS, CSAT_DISPLAY_TYPES } from 'shared/constants/messages';
import FluentIcon from 'shared/components/FluentIcon/Index.vue';
import StarRating from 'shared/components/StarRating.vue';
import { useMessageFormatter } from 'shared/composables/useMessageFormatter';
import { getContrastingTextColor } from '@chatwoot/utils';
export default {
@@ -30,6 +31,10 @@ export default {
default: '',
},
},
setup() {
const { formatMessage } = useMessageFormatter();
return { formatMessage };
},
data() {
return {
email: '',
@@ -61,6 +66,9 @@ export default {
? this.$t('CSAT.SUBMITTED_TITLE')
: this.message || this.$t('CSAT.TITLE');
},
formattedTitle() {
return this.formatMessage(this.title, false);
},
isEmojiType() {
return this.displayType === CSAT_DISPLAY_TYPES.EMOJI;
},
@@ -128,9 +136,10 @@ export default {
class="customer-satisfaction w-full bg-n-background dark:bg-n-solid-3 shadow-[0_0.25rem_6px_rgba(50,50,93,0.08),0_1px_3px_rgba(0,0,0,0.05)] ltr:rounded-bl-[0.25rem] rtl:rounded-br-[0.25rem] rounded-lg inline-block leading-[1.5] mt-1 border-t-2 border-t-n-brand border-solid"
:style="{ borderColor: widgetColor }"
>
<h6 class="text-n-slate-12 text-sm font-medium pt-5 px-2.5 text-center">
{{ title }}
</h6>
<h6
v-dompurify-html="formattedTitle"
class="text-n-slate-12 text-sm font-medium pt-5 px-2.5 text-center prose prose-bubble"
/>
<div v-if="isEmojiType" class="ratings flex justify-around py-5 px-4">
<button
v-for="rating in ratings"
+12 -5
View File
@@ -6,6 +6,7 @@ import Rating from 'survey/components/Rating.vue';
import Feedback from 'survey/components/Feedback.vue';
import Banner from 'survey/components/Banner.vue';
import StarRating from 'shared/components/StarRating.vue';
import { useMessageFormatter } from 'shared/composables/useMessageFormatter';
import { getSurveyDetails, updateSurvey } from 'survey/api/survey';
import { CSAT_DISPLAY_TYPES } from 'shared/constants/messages';
@@ -20,6 +21,10 @@ export default {
Feedback,
StarRating,
},
setup() {
const { formatMessage } = useMessageFormatter();
return { formatMessage };
},
data() {
return {
surveyDetails: null,
@@ -77,6 +82,9 @@ export default {
}
return this.$t('SURVEY.RATING.SUCCESS_MESSAGE');
},
formattedMessageContent() {
return this.formatMessage(this.messageContent, false);
},
},
async mounted() {
this.getSurveyDetails();
@@ -167,12 +175,11 @@ export default {
>
<div class="w-full px-12 pt-12 pb-6 m-auto my-0">
<img v-if="logo" :src="logo" alt="Chatwoot logo" class="mb-6 logo" />
<p
<div
v-if="!isRatingSubmitted"
class="mb-8 text-lg leading-relaxed text-n-slate-12"
>
{{ messageContent }}
</p>
v-dompurify-html="formattedMessageContent"
class="mb-8 text-lg leading-relaxed text-n-slate-12 prose prose-bubble"
/>
<Banner
v-if="shouldShowBanner"
:show-success="shouldShowSuccessMessage"