Merge branch 'release/1.2.1' into develop
This commit is contained in:
@@ -15,7 +15,7 @@ class MessageApi extends ApiClient {
|
||||
}
|
||||
|
||||
getPreviousMessages({ conversationId, before }) {
|
||||
return axios.get(`${this.url}/${conversationId}`, {
|
||||
return axios.get(`${this.url}/${conversationId}/messages`, {
|
||||
params: { before },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -33,14 +33,18 @@
|
||||
<div class="reply-box__bottom">
|
||||
<ul class="tabs">
|
||||
<li class="tabs-title" :class="{ 'is-active': !isPrivate }">
|
||||
<a href="#" @click="makeReply">Reply</a>
|
||||
<a href="#" @click="makeReply">{{
|
||||
$t('CONVERSATION.REPLYBOX.REPLY')
|
||||
}}</a>
|
||||
</li>
|
||||
<li class="tabs-title is-private" :class="{ 'is-active': isPrivate }">
|
||||
<a href="#" @click="makePrivate">Private Note</a>
|
||||
<a href="#" @click="makePrivate">{{
|
||||
$t('CONVERSATION.REPLYBOX.PRIVATE_NOTE')
|
||||
}}</a>
|
||||
</li>
|
||||
<li v-if="message.length" class="tabs-title message-length">
|
||||
<a :class="{ 'message-error': message.length > 620 }">
|
||||
{{ message.length }} / 640
|
||||
<a :class="{ 'message-error': message.length > maxLength - 40 }">
|
||||
{{ message.length }} / {{ maxLength }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -49,16 +53,12 @@
|
||||
class="button send-button"
|
||||
:disabled="disableButton()"
|
||||
:class="{
|
||||
disabled: message.length === 0 || message.length > 640,
|
||||
disabled: message.length === 0 || message.length > maxLength,
|
||||
warning: isPrivate,
|
||||
}"
|
||||
@click="sendMessage"
|
||||
>
|
||||
{{
|
||||
isPrivate
|
||||
? $t('CONVERSATION.REPLYBOX.CREATE')
|
||||
: $t('CONVERSATION.REPLYBOX.SEND')
|
||||
}}
|
||||
{{ replyButtonLabel }}
|
||||
<i
|
||||
class="icon"
|
||||
:class="{
|
||||
@@ -82,6 +82,10 @@ import EmojiInput from '../emoji/EmojiInput';
|
||||
import CannedResponse from './CannedResponse';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EmojiInput,
|
||||
CannedResponse,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
data() {
|
||||
return {
|
||||
@@ -103,10 +107,32 @@ export default {
|
||||
} = this.currentChat;
|
||||
return channel;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
EmojiInput,
|
||||
CannedResponse,
|
||||
conversationType() {
|
||||
const {
|
||||
additional_attributes: additionalAttributes = {},
|
||||
} = this.currentChat;
|
||||
return additionalAttributes.type || '';
|
||||
},
|
||||
maxLength() {
|
||||
if (this.channelType === 'Channel::FacebookPage') {
|
||||
return 640;
|
||||
}
|
||||
if (this.channelType === 'Channel::TwitterProfile') {
|
||||
if (this.conversationType === 'tweet') {
|
||||
return 280;
|
||||
}
|
||||
}
|
||||
return 10000;
|
||||
},
|
||||
replyButtonLabel() {
|
||||
if (this.isPrivate) {
|
||||
return this.$t('CONVERSATION.REPLYBOX.CREATE');
|
||||
}
|
||||
if (this.conversationType === 'tweet') {
|
||||
return this.$t('CONVERSATION.REPLYBOX.TWEET');
|
||||
}
|
||||
return this.$t('CONVERSATION.REPLYBOX.SEND');
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
message(val) {
|
||||
|
||||
@@ -21,8 +21,11 @@
|
||||
"PRIVATE_MSG_INPUT": "Shift + enter for new line. This will be visible only to Agents"
|
||||
},
|
||||
"REPLYBOX": {
|
||||
"REPLY": "Reply",
|
||||
"PRIVATE_NOTE": "Private Note",
|
||||
"SEND": "Send",
|
||||
"CREATE": "Add Note"
|
||||
"CREATE": "Add Note",
|
||||
"TWEET": "Tweet"
|
||||
},
|
||||
"VISIBLE_TO_AGENTS": "Private Note: Only visible to you and your team",
|
||||
"CHANGE_STATUS": "Conversation status changed",
|
||||
|
||||
@@ -58,6 +58,7 @@ export default {
|
||||
this.initialize();
|
||||
this.$watch('$store.state.route', () => this.initialize());
|
||||
this.$watch('chatList.length', () => {
|
||||
this.fetchConversation();
|
||||
this.setActiveChat();
|
||||
});
|
||||
},
|
||||
@@ -81,13 +82,28 @@ export default {
|
||||
break;
|
||||
default:
|
||||
this.$store.dispatch('setActiveInbox', null);
|
||||
this.$store.dispatch('clearSelectedState');
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
setActiveChat() {
|
||||
fetchConversation() {
|
||||
if (!this.conversationId) {
|
||||
return;
|
||||
}
|
||||
const chat = this.findConversation();
|
||||
if (!chat) {
|
||||
this.$store.dispatch('getConversation', this.conversationId);
|
||||
}
|
||||
},
|
||||
findConversation() {
|
||||
const conversationId = parseInt(this.conversationId, 10);
|
||||
const [chat] = this.chatList.filter(c => c.id === conversationId);
|
||||
return chat;
|
||||
},
|
||||
|
||||
setActiveChat() {
|
||||
const chat = this.findConversation();
|
||||
if (!chat) return;
|
||||
this.$store.dispatch('setActiveChat', chat).then(() => {
|
||||
bus.$emit('scrollToMessage');
|
||||
|
||||
@@ -28,7 +28,7 @@ export default {
|
||||
roles: ['administrator', 'agent'],
|
||||
component: ConversationView,
|
||||
props: route => {
|
||||
return { conversationId: route.params.conversation_id };
|
||||
return { inboxId: 0, conversationId: route.params.conversation_id };
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
<span v-if="item.channel_type === 'Channel::WebWidget'">
|
||||
Website
|
||||
</span>
|
||||
<span v-if="item.channel_type === 'Channel::TwitterProfile'">
|
||||
Twitter
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
|
||||
@@ -7,6 +7,15 @@ import FBChannel from '../../../api/channel/fbChannel';
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
getConversation: async ({ commit }, conversationId) => {
|
||||
try {
|
||||
const response = await ConversationApi.show(conversationId);
|
||||
commit(types.default.ADD_CONVERSATION, response.data);
|
||||
} catch (error) {
|
||||
// Ignore error
|
||||
}
|
||||
},
|
||||
|
||||
fetchAllConversations: async ({ commit, dispatch }, params) => {
|
||||
commit(types.default.SET_LIST_LOADING_STATUS);
|
||||
try {
|
||||
|
||||
@@ -33,12 +33,13 @@ const getters = {
|
||||
getChatListLoadingStatus: ({ listLoadingStatus }) => listLoadingStatus,
|
||||
getAllMessagesLoaded(_state) {
|
||||
const [chat] = getSelectedChatConversation(_state);
|
||||
return chat.allMessagesLoaded === undefined
|
||||
return !chat || chat.allMessagesLoaded === undefined
|
||||
? false
|
||||
: chat.allMessagesLoaded;
|
||||
},
|
||||
getUnreadCount(_state) {
|
||||
const [chat] = getSelectedChatConversation(_state);
|
||||
if (!chat) return [];
|
||||
return chat.messages.filter(
|
||||
chatMessage =>
|
||||
chatMessage.created_at * 1000 > chat.agent_last_seen_at * 1000 &&
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import axios from 'axios';
|
||||
import actions from '../../conversations/actions';
|
||||
import * as types from '../../../mutation-types';
|
||||
|
||||
const commit = jest.fn();
|
||||
global.axios = axios;
|
||||
jest.mock('axios');
|
||||
|
||||
describe('#actions', () => {
|
||||
describe('#getConversation', () => {
|
||||
it('sends correct actions if API is success', async () => {
|
||||
axios.get.mockResolvedValue({ data: { id: 1, meta: {} } });
|
||||
await actions.getConversation({ commit }, 1);
|
||||
expect(commit.mock.calls).toEqual([
|
||||
[types.default.ADD_CONVERSATION, { id: 1, meta: {} }],
|
||||
]);
|
||||
});
|
||||
it('sends correct actions if API is error', async () => {
|
||||
axios.get.mockRejectedValue({ message: 'Incorrect header' });
|
||||
await actions.getConversation({ commit });
|
||||
expect(commit.mock.calls).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user