feat: Show errors for message bubbles in dashboard (#3585)
This commit is contained in:
committed by
GitHub
parent
6fe5484119
commit
83655f4ca4
@@ -86,7 +86,7 @@ export default {
|
||||
this.isExpanded ? 'expanded' : '',
|
||||
];
|
||||
},
|
||||
withTextIconSize() {
|
||||
iconSize() {
|
||||
switch (this.size) {
|
||||
case 'tiny':
|
||||
return 12;
|
||||
@@ -101,26 +101,6 @@ export default {
|
||||
return 16;
|
||||
}
|
||||
},
|
||||
withoutTextIconSize() {
|
||||
switch (this.size) {
|
||||
case 'tiny':
|
||||
return 14;
|
||||
case 'small':
|
||||
return 16;
|
||||
case 'medium':
|
||||
return 18;
|
||||
case 'large':
|
||||
return 20;
|
||||
|
||||
default:
|
||||
return 18;
|
||||
}
|
||||
},
|
||||
iconSize() {
|
||||
return this.hasOnlyIcon
|
||||
? this.withoutTextIconSize
|
||||
: this.withTextIconSize;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClick(evt) {
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
</span>
|
||||
<span v-else-if="lastMessageInChat.attachments">
|
||||
<fluent-icon
|
||||
v-if="attachmentIcon"
|
||||
size="16"
|
||||
class="message--attachment-icon"
|
||||
:icon="attachmentIcon"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<li v-if="hasAttachments || data.content" :class="alignBubble">
|
||||
<div :class="wrapClass">
|
||||
<div v-tooltip.top-start="sentByMessage" :class="bubbleClass">
|
||||
<div v-tooltip.top-start="messageToolTip" :class="bubbleClass">
|
||||
<bubble-mail-head
|
||||
:email-attributes="contentAttributes.email"
|
||||
:cc="emailHeadAttributes.cc"
|
||||
@@ -73,8 +73,18 @@
|
||||
{{ sender.name }}
|
||||
</div>
|
||||
</a>
|
||||
<div v-if="isFailed" class="message-failed--alert">
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('CONVERSATION.TRY_AGAIN')"
|
||||
size="tiny"
|
||||
color-scheme="alert"
|
||||
variant="clear"
|
||||
icon="arrow-clockwise"
|
||||
@click="retrySendMessage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-wrap">
|
||||
<div v-if="shouldShowContextMenu" class="context-menu-wrap">
|
||||
<context-menu
|
||||
v-if="isBubble && !isMessageDeleted"
|
||||
:is-open="showContextMenu"
|
||||
@@ -248,10 +258,13 @@ export default {
|
||||
hasText() {
|
||||
return !!this.data.content;
|
||||
},
|
||||
sentByMessage() {
|
||||
messageToolTip() {
|
||||
if (this.isMessageDeleted) {
|
||||
return false;
|
||||
}
|
||||
if (this.isFailed) {
|
||||
return this.$t(`CONVERSATION.SEND_FAILED`);
|
||||
}
|
||||
const { sender } = this;
|
||||
return this.data.message_type === 1 && !isEmptyObject(sender)
|
||||
? {
|
||||
@@ -265,6 +278,7 @@ export default {
|
||||
wrap: this.isBubble,
|
||||
'activity-wrap': !this.isBubble,
|
||||
'is-pending': this.isPending,
|
||||
'is-failed': this.isFailed,
|
||||
};
|
||||
},
|
||||
bubbleClass() {
|
||||
@@ -275,19 +289,30 @@ export default {
|
||||
'is-video': this.hasMediaAttachment('video'),
|
||||
'is-text': this.hasText,
|
||||
'is-from-bot': this.isSentByBot,
|
||||
'is-failed': this.isFailed,
|
||||
};
|
||||
},
|
||||
isPending() {
|
||||
return this.data.status === MESSAGE_STATUS.PROGRESS;
|
||||
},
|
||||
isFailed() {
|
||||
return this.data.status === MESSAGE_STATUS.FAILED;
|
||||
},
|
||||
isSentByBot() {
|
||||
if (this.isPending) return false;
|
||||
if (this.isPending || this.isFailed) return false;
|
||||
return !this.sender.type || this.sender.type === 'agent_bot';
|
||||
},
|
||||
contextMenuPosition() {
|
||||
const { message_type: messageType } = this.data;
|
||||
return messageType ? 'right' : 'left';
|
||||
},
|
||||
shouldShowContextMenu() {
|
||||
return !(this.isFailed || this.isPending);
|
||||
},
|
||||
errorMessage() {
|
||||
const { meta } = this.data;
|
||||
return meta ? meta.error : '';
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
data() {
|
||||
@@ -327,6 +352,9 @@ export default {
|
||||
this.showAlert(this.$t('CONTACT_PANEL.COPY_SUCCESSFUL'));
|
||||
this.showContextMenu = false;
|
||||
},
|
||||
async retrySendMessage() {
|
||||
await this.$store.dispatch('sendMessageWithData', this.data);
|
||||
},
|
||||
onImageLoadError() {
|
||||
this.hasImageError = true;
|
||||
},
|
||||
@@ -396,6 +424,14 @@ export default {
|
||||
color: var(--v-50);
|
||||
}
|
||||
}
|
||||
|
||||
&.is-failed {
|
||||
background: var(--r-200);
|
||||
|
||||
.message-text--metadata .time {
|
||||
color: var(--r-50);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-pending {
|
||||
@@ -426,6 +462,13 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.message-failed--alert {
|
||||
color: var(--r-900);
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
margin-top: var(--space-smaller) var(--space-smaller) 0 0;
|
||||
}
|
||||
|
||||
.button--delete-message {
|
||||
visibility: hidden;
|
||||
}
|
||||
@@ -451,6 +494,17 @@ li.right .context-menu-wrap {
|
||||
li.right {
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
|
||||
.wrap.is-pending {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.wrap.is-failed {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
align-items: flex-end;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.has-context-menu {
|
||||
|
||||
@@ -369,7 +369,10 @@ export default {
|
||||
const messagePayload = this.getMessagePayload(newMessage);
|
||||
this.clearMessage();
|
||||
try {
|
||||
await this.$store.dispatch('sendMessage', messagePayload);
|
||||
await this.$store.dispatch(
|
||||
'createPendingMessageAndSend',
|
||||
messagePayload
|
||||
);
|
||||
this.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
"FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit",
|
||||
"MESSAGE_ERROR": "Unable to send this message, please try again later",
|
||||
"SENT_BY": "Sent by:",
|
||||
"SEND_FAILED": "Couldn't send message! Try again",
|
||||
"TRY_AGAIN": "retry",
|
||||
"ASSIGNMENT": {
|
||||
"SELECT_AGENT": "Select Agent",
|
||||
"REMOVE": "Remove",
|
||||
|
||||
@@ -158,17 +158,33 @@ const actions = {
|
||||
}
|
||||
},
|
||||
|
||||
sendMessage: async ({ commit }, data) => {
|
||||
// eslint-disable-next-line no-useless-catch
|
||||
createPendingMessageAndSend: async ({ dispatch }, data) => {
|
||||
const pendingMessage = createPendingMessage(data);
|
||||
dispatch('sendMessageWithData', pendingMessage);
|
||||
},
|
||||
|
||||
sendMessageWithData: async ({ commit }, pendingMessage) => {
|
||||
try {
|
||||
const pendingMessage = createPendingMessage(data);
|
||||
commit(types.ADD_MESSAGE, pendingMessage);
|
||||
commit(types.ADD_MESSAGE, {
|
||||
...pendingMessage,
|
||||
status: MESSAGE_STATUS.PROGRESS,
|
||||
});
|
||||
const response = await MessageApi.create(pendingMessage);
|
||||
commit(types.ADD_MESSAGE, {
|
||||
...response.data,
|
||||
status: MESSAGE_STATUS.SENT,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorMessage = error.response
|
||||
? error.response.data.error
|
||||
: undefined;
|
||||
commit(types.ADD_MESSAGE, {
|
||||
...pendingMessage,
|
||||
meta: {
|
||||
error: errorMessage,
|
||||
},
|
||||
status: MESSAGE_STATUS.FAILED,
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user