mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-23 11:03:43 +00:00
Fix CSAT responses not visible agent message bubble
- Fix csat form submission in widget - Update vite config to allow cross origin requests
This commit is contained in:
@@ -1,25 +1,36 @@
|
||||
<template>
|
||||
<div v-if="csatResponse" class="mt-3 p-3 bg-muted/50 rounded-md border">
|
||||
<div class="text-sm font-medium text-muted-foreground mb-2">
|
||||
{{ $t('globals.terms.feedback') }}:
|
||||
<div v-if="isCsatMessage" class="mt-3 pt-3 border-t border-border">
|
||||
<!-- Submitted CSAT -->
|
||||
<div v-if="isSubmitted && hasResponse">
|
||||
<div class="text-xs text-muted-foreground mb-2">
|
||||
{{ t('globals.terms.feedback', 1) }}
|
||||
</div>
|
||||
|
||||
<div v-if="csatResponse.rating" class="flex items-center gap-2 mb-2">
|
||||
<span class="text-lg">{{ getRatingEmoji(csatResponse.rating) }}</span>
|
||||
<span class="text-sm font-medium">{{ getRatingText(csatResponse.rating) }}</span>
|
||||
<span class="text-xs text-muted-foreground">{{ csatResponse.rating }}/5</span>
|
||||
</div>
|
||||
|
||||
<p
|
||||
v-if="csatResponse.feedback"
|
||||
class="text-sm text-muted-foreground italic pl-3 border-l-2 border-muted"
|
||||
>
|
||||
{{ csatResponse.feedback }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Rating -->
|
||||
<div v-if="csatResponse.rating" class="flex items-center gap-2 mb-2">
|
||||
<span class="text-lg">{{ getRatingEmoji(csatResponse.rating) }}</span>
|
||||
<span class="text-sm font-medium">{{ getRatingText(csatResponse.rating) }}</span>
|
||||
<span class="text-xs text-muted-foreground">({{ csatResponse.rating }}/5)</span>
|
||||
</div>
|
||||
|
||||
<!-- Feedback -->
|
||||
<div v-if="csatResponse.feedback" class="text-sm italic text-foreground">
|
||||
"{{ csatResponse.feedback }}"
|
||||
</div>
|
||||
<span v-else-if="!isSubmitted" class="text-xs text-muted-foreground italic">
|
||||
{{ t('globals.terms.awaitingResponse') }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
message: {
|
||||
@@ -28,37 +39,34 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const csatResponse = computed(() => {
|
||||
const meta = props.message.meta
|
||||
if (!meta?.is_csat || !meta?.csat_submitted) {
|
||||
return null
|
||||
}
|
||||
const isCsatMessage = computed(() => props.message.meta?.is_csat === true)
|
||||
const isSubmitted = computed(() => props.message.meta?.csat_submitted === true)
|
||||
|
||||
const csatResponse = computed(() => {
|
||||
if (!isSubmitted.value) return null
|
||||
return {
|
||||
rating: meta.submitted_rating || null,
|
||||
feedback: meta.submitted_feedback || null
|
||||
rating: props.message.meta.submitted_rating || null,
|
||||
feedback: props.message.meta.submitted_feedback || null
|
||||
}
|
||||
})
|
||||
|
||||
const hasResponse = computed(() =>
|
||||
csatResponse.value && (csatResponse.value.rating || csatResponse.value.feedback)
|
||||
)
|
||||
|
||||
const getRatingEmoji = (rating) => {
|
||||
const ratings = {
|
||||
1: '😢',
|
||||
2: '😕',
|
||||
3: '😊',
|
||||
4: '😃',
|
||||
5: '🤩'
|
||||
}
|
||||
return ratings[rating] || ''
|
||||
const emojis = { 1: '😢', 2: '😕', 3: '😊', 4: '😃', 5: '🤩' }
|
||||
return emojis[rating] || ''
|
||||
}
|
||||
|
||||
const getRatingText = (rating) => {
|
||||
const ratings = {
|
||||
1: 'Poor',
|
||||
2: 'Fair',
|
||||
3: 'Good',
|
||||
4: 'Great',
|
||||
5: 'Excellent'
|
||||
const keys = {
|
||||
1: 'globals.terms.poor',
|
||||
2: 'globals.terms.fair',
|
||||
3: 'globals.terms.good',
|
||||
4: 'globals.terms.great',
|
||||
5: 'globals.terms.excellent'
|
||||
}
|
||||
return ratings[rating] || ''
|
||||
return keys[rating] ? t(keys[rating]) : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -73,6 +73,9 @@
|
||||
<!-- Attachments -->
|
||||
<MessageAttachmentPreview :attachments="nonInlineAttachments" />
|
||||
|
||||
<!-- CSAT Response -->
|
||||
<CSATResponseDisplay :message="message" />
|
||||
|
||||
<!-- Spinner for Pending Messages (outgoing only) -->
|
||||
<Spinner v-if="isOutgoing && message.status === 'pending'" size="sm" />
|
||||
|
||||
@@ -129,6 +132,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@shared-ui/components/ui/av
|
||||
import { Letter } from 'vue-letter'
|
||||
import MessageAttachmentPreview from '@main/features/conversation/message/attachment/MessageAttachmentPreview.vue'
|
||||
import MessageEnvelope from './MessageEnvelope.vue'
|
||||
import CSATResponseDisplay from './CSATResponseDisplay.vue'
|
||||
import api from '@main/api'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -165,6 +169,10 @@ const avatarFallback = computed(() => {
|
||||
|
||||
// Content sanitization - different processing for incoming vs outgoing
|
||||
const sanitizedContent = computed(() => {
|
||||
if (props.message.meta?.is_csat) {
|
||||
return t('globals.messages.pleaseRateConversation')
|
||||
}
|
||||
|
||||
let content = props.message.content || ''
|
||||
|
||||
if (isOutgoing.value) {
|
||||
|
||||
@@ -32,6 +32,7 @@ export default defineConfig(({ mode }) => {
|
||||
// Separate cache per app to avoid stale/conflicting caches.
|
||||
cacheDir: path.resolve(__dirname, `node_modules/.vite-${isWidget ? 'widget' : 'main'}`),
|
||||
server: {
|
||||
cors: { origin: "*" },
|
||||
// Allow access to parent dir so shared-ui imports work in dev.
|
||||
fs: {
|
||||
allow: [path.resolve(__dirname)],
|
||||
@@ -40,23 +41,29 @@ export default defineConfig(({ mode }) => {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:9000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/widget.js': {
|
||||
target: 'http://127.0.0.1:9000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/logout': {
|
||||
target: 'http://127.0.0.1:9000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/uploads': {
|
||||
target: 'http://127.0.0.1:9000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/ws': {
|
||||
target: 'ws://127.0.0.1:9000',
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/widget/ws': {
|
||||
target: 'ws://127.0.0.1:9000',
|
||||
ws: true,
|
||||
changeOrigin: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1326,7 +1326,8 @@ func (m *Manager) SendCSATReply(actorUserID int, conversation models.Conversatio
|
||||
message := fmt.Sprintf(csatReplyMessage, csatPublicURL)
|
||||
// Store `is_csat` meta to identify and filter CSAT public url from the message.
|
||||
meta := map[string]interface{}{
|
||||
"is_csat": true,
|
||||
"is_csat": true,
|
||||
"csat_uuid": csat.UUID,
|
||||
}
|
||||
|
||||
// Make recipient list.
|
||||
|
||||
Reference in New Issue
Block a user