Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
994519bb2e | ||
|
|
3d24fa2a2d | ||
|
|
00ea51abd4 | ||
|
|
f803cb98c7 | ||
|
|
755556e2d7 | ||
|
|
a0fbfbe38f | ||
|
|
b998101a4c | ||
|
|
6577b40f90 |
@@ -3,7 +3,6 @@ import { useUISettings } from 'dashboard/composables/useUISettings';
|
|||||||
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
||||||
import FileUpload from 'vue-upload-component';
|
import FileUpload from 'vue-upload-component';
|
||||||
import * as ActiveStorage from 'activestorage';
|
import * as ActiveStorage from 'activestorage';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
|
||||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||||
import {
|
import {
|
||||||
ALLOWED_FILE_TYPES,
|
ALLOWED_FILE_TYPES,
|
||||||
@@ -18,7 +17,6 @@ import { mapGetters } from 'vuex';
|
|||||||
export default {
|
export default {
|
||||||
name: 'ReplyBottomPanel',
|
name: 'ReplyBottomPanel',
|
||||||
components: { FileUpload, VideoCallButton, AIAssistanceButton },
|
components: { FileUpload, VideoCallButton, AIAssistanceButton },
|
||||||
mixins: [inboxMixin],
|
|
||||||
props: {
|
props: {
|
||||||
mode: {
|
mode: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -36,13 +34,6 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
// inbox prop is used in /mixins/inboxMixin,
|
|
||||||
// remove this props when refactoring to composable if not needed
|
|
||||||
// eslint-disable-next-line vue/no-unused-properties
|
|
||||||
inbox: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
showFileUpload: {
|
showFileUpload: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
@@ -111,6 +102,22 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
isALineChannel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isATwilioWhatsAppChannel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isAWebWidgetInbox: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isAPIInbox: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const { setSignatureFlagForInbox, fetchSignatureFlagFromUISettings } =
|
const { setSignatureFlagForInbox, fetchSignatureFlagFromUISettings } =
|
||||||
@@ -211,7 +218,6 @@ export default {
|
|||||||
return !this.isOnPrivateNote;
|
return !this.isOnPrivateNote;
|
||||||
},
|
},
|
||||||
sendWithSignature() {
|
sendWithSignature() {
|
||||||
// channelType is sourced from inboxMixin
|
|
||||||
return this.fetchSignatureFlagFromUISettings(this.channelType);
|
return this.fetchSignatureFlagFromUISettings(this.channelType);
|
||||||
},
|
},
|
||||||
signatureToggleTooltip() {
|
signatureToggleTooltip() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import MessagePreview from './MessagePreview.vue';
|
|||||||
import router from '../../../routes';
|
import router from '../../../routes';
|
||||||
import { frontendURL, conversationUrl } from '../../../helper/URLHelper';
|
import { frontendURL, conversationUrl } from '../../../helper/URLHelper';
|
||||||
import InboxName from '../InboxName.vue';
|
import InboxName from '../InboxName.vue';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
import ConversationContextMenu from './contextMenu/Index.vue';
|
import ConversationContextMenu from './contextMenu/Index.vue';
|
||||||
import TimeAgo from 'dashboard/components/ui/TimeAgo.vue';
|
import TimeAgo from 'dashboard/components/ui/TimeAgo.vue';
|
||||||
import CardLabels from './conversationCardComponents/CardLabels.vue';
|
import CardLabels from './conversationCardComponents/CardLabels.vue';
|
||||||
@@ -24,7 +24,6 @@ export default {
|
|||||||
PriorityMark,
|
PriorityMark,
|
||||||
SLACardLabel,
|
SLACardLabel,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin],
|
|
||||||
props: {
|
props: {
|
||||||
activeLabel: {
|
activeLabel: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -67,6 +66,14 @@ export default {
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
setup(props) {
|
||||||
|
const { inbox_id: inboxId } = props.chat;
|
||||||
|
const { inboxBadge, inbox } = useInbox({ inboxId });
|
||||||
|
return {
|
||||||
|
inboxBadge,
|
||||||
|
inbox,
|
||||||
|
};
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
hovered: false,
|
hovered: false,
|
||||||
@@ -121,12 +128,6 @@ export default {
|
|||||||
return getLastMessage(this.chat);
|
return getLastMessage(this.chat);
|
||||||
},
|
},
|
||||||
|
|
||||||
inbox() {
|
|
||||||
const { inbox_id: inboxId } = this.chat;
|
|
||||||
const stateInbox = this.$store.getters['inboxes/getInbox'](inboxId);
|
|
||||||
return stateInbox;
|
|
||||||
},
|
|
||||||
|
|
||||||
showInboxName() {
|
showInboxName() {
|
||||||
return (
|
return (
|
||||||
!this.hideInboxName &&
|
!this.hideInboxName &&
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { ref } from 'vue';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
||||||
|
import agentMixin from '../../../mixins/agentMixin.js';
|
||||||
import BackButton from '../BackButton.vue';
|
import BackButton from '../BackButton.vue';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
import InboxName from '../InboxName.vue';
|
import InboxName from '../InboxName.vue';
|
||||||
import MoreActions from './MoreActions.vue';
|
import MoreActions from './MoreActions.vue';
|
||||||
import Thumbnail from '../Thumbnail.vue';
|
import Thumbnail from '../Thumbnail.vue';
|
||||||
@@ -22,7 +24,7 @@ export default {
|
|||||||
SLACardLabel,
|
SLACardLabel,
|
||||||
Linear,
|
Linear,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin],
|
mixins: [agentMixin],
|
||||||
props: {
|
props: {
|
||||||
chat: {
|
chat: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -42,12 +44,20 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
const conversationHeaderActionsRef = ref(null);
|
||||||
|
const { inbox, inboxBadge } = useInbox({ inboxId: props.chat.inbox_id });
|
||||||
const keyboardEvents = {
|
const keyboardEvents = {
|
||||||
'Alt+KeyO': {
|
'Alt+KeyO': {
|
||||||
action: () => emit('contactPanelToggle'),
|
action: () => emit('contactPanelToggle'),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
useKeyboardEvents(keyboardEvents);
|
useKeyboardEvents(keyboardEvents, conversationHeaderActionsRef);
|
||||||
|
|
||||||
|
return {
|
||||||
|
conversationHeaderActionsRef,
|
||||||
|
inbox,
|
||||||
|
inboxBadge,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
@@ -102,10 +112,6 @@ export default {
|
|||||||
: this.$t('CONVERSATION.HEADER.OPEN')
|
: this.$t('CONVERSATION.HEADER.OPEN')
|
||||||
} ${this.$t('CONVERSATION.HEADER.DETAILS')}`;
|
} ${this.$t('CONVERSATION.HEADER.DETAILS')}`;
|
||||||
},
|
},
|
||||||
inbox() {
|
|
||||||
const { inbox_id: inboxId } = this.chat;
|
|
||||||
return this.$store.getters['inboxes/getInbox'](inboxId);
|
|
||||||
},
|
|
||||||
hasMultipleInboxes() {
|
hasMultipleInboxes() {
|
||||||
return this.$store.getters['inboxes/getInboxes'].length > 1;
|
return this.$store.getters['inboxes/getInboxes'].length > 1;
|
||||||
},
|
},
|
||||||
@@ -175,6 +181,7 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
ref="conversationHeaderActionsRef"
|
||||||
class="flex items-center gap-2 overflow-hidden text-xs conversation--header--actions text-ellipsis whitespace-nowrap"
|
class="flex items-center gap-2 overflow-hidden text-xs conversation--header--actions text-ellipsis whitespace-nowrap"
|
||||||
>
|
>
|
||||||
<InboxName v-if="hasMultipleInboxes" :inbox="inbox" />
|
<InboxName v-if="hasMultipleInboxes" :inbox="inbox" />
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { ref } from 'vue';
|
|||||||
// composable
|
// composable
|
||||||
import { useConfig } from 'dashboard/composables/useConfig';
|
import { useConfig } from 'dashboard/composables/useConfig';
|
||||||
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents';
|
||||||
import { useAI } from 'dashboard/composables/useAI';
|
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import ReplyBox from './ReplyBox.vue';
|
import ReplyBox from './ReplyBox.vue';
|
||||||
@@ -15,7 +14,9 @@ import Banner from 'dashboard/components/ui/Banner.vue';
|
|||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
// mixins
|
// mixins
|
||||||
import inboxMixin, { INBOX_FEATURES } from 'shared/mixins/inboxMixin';
|
import { useInbox, INBOX_FEATURES } from 'shared/composables/useInbox';
|
||||||
|
|
||||||
|
import aiMixin from 'dashboard/mixins/aiMixin';
|
||||||
|
|
||||||
// utils
|
// utils
|
||||||
import { getTypingUsersText } from '../../../helper/commons';
|
import { getTypingUsersText } from '../../../helper/commons';
|
||||||
@@ -40,7 +41,7 @@ export default {
|
|||||||
Banner,
|
Banner,
|
||||||
ConversationLabelSuggestion,
|
ConversationLabelSuggestion,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin],
|
mixins: [aiMixin],
|
||||||
props: {
|
props: {
|
||||||
isContactPanelOpen: {
|
isContactPanelOpen: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -52,6 +53,17 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const {
|
||||||
|
inbox,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
isAPIInbox,
|
||||||
|
is360DialogWhatsAppChannel,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isAnEmailChannel,
|
||||||
|
inboxHasFeature,
|
||||||
|
} = useInbox({ getCurrentChat: true });
|
||||||
|
const conversationFooterRef = ref(null);
|
||||||
const isPopOutReplyBox = ref(false);
|
const isPopOutReplyBox = ref(false);
|
||||||
const { isEnterprise } = useConfig();
|
const { isEnterprise } = useConfig();
|
||||||
|
|
||||||
@@ -69,24 +81,22 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
useKeyboardEvents(keyboardEvents);
|
useKeyboardEvents(keyboardEvents, conversationFooterRef);
|
||||||
|
|
||||||
const {
|
|
||||||
isAIIntegrationEnabled,
|
|
||||||
isLabelSuggestionFeatureEnabled,
|
|
||||||
fetchIntegrationsIfRequired,
|
|
||||||
fetchLabelSuggestions,
|
|
||||||
} = useAI();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isEnterprise,
|
isEnterprise,
|
||||||
|
conversationFooterRef,
|
||||||
isPopOutReplyBox,
|
isPopOutReplyBox,
|
||||||
closePopOutReplyBox,
|
closePopOutReplyBox,
|
||||||
showPopOutReplyBox,
|
showPopOutReplyBox,
|
||||||
isAIIntegrationEnabled,
|
inbox,
|
||||||
isLabelSuggestionFeatureEnabled,
|
isAWhatsAppChannel,
|
||||||
fetchIntegrationsIfRequired,
|
isAPIInbox,
|
||||||
fetchLabelSuggestions,
|
is360DialogWhatsAppChannel,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isAnEmailChannel,
|
||||||
|
inboxHasFeature,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -121,9 +131,6 @@ export default {
|
|||||||
inboxId() {
|
inboxId() {
|
||||||
return this.currentChat.inbox_id;
|
return this.currentChat.inbox_id;
|
||||||
},
|
},
|
||||||
inbox() {
|
|
||||||
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
|
||||||
},
|
|
||||||
typingUsersList() {
|
typingUsersList() {
|
||||||
const userList = this.$store.getters[
|
const userList = this.$store.getters[
|
||||||
'conversationTypingStatus/getUserList'
|
'conversationTypingStatus/getUserList'
|
||||||
@@ -527,6 +534,7 @@ export default {
|
|||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
<div
|
<div
|
||||||
|
ref="conversationFooterRef"
|
||||||
class="conversation-footer"
|
class="conversation-footer"
|
||||||
:class="{ 'modal-mask': isPopOutReplyBox }"
|
:class="{ 'modal-mask': isPopOutReplyBox }"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import Banner from 'dashboard/components/ui/Banner.vue';
|
|||||||
import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
|
import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
|
||||||
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
|
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
|
||||||
import WootAudioRecorder from 'dashboard/components/widgets/WootWriter/AudioRecorder.vue';
|
import WootAudioRecorder from 'dashboard/components/widgets/WootWriter/AudioRecorder.vue';
|
||||||
|
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
|
||||||
import { AUDIO_FORMATS } from 'shared/constants/messages';
|
import { AUDIO_FORMATS } from 'shared/constants/messages';
|
||||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||||
import {
|
import {
|
||||||
@@ -26,7 +27,7 @@ import {
|
|||||||
} from '@chatwoot/utils';
|
} from '@chatwoot/utils';
|
||||||
import WhatsappTemplates from './WhatsappTemplates/Modal.vue';
|
import WhatsappTemplates from './WhatsappTemplates/Modal.vue';
|
||||||
import { MESSAGE_MAX_LENGTH } from 'shared/helpers/MessageTypeHelper';
|
import { MESSAGE_MAX_LENGTH } from 'shared/helpers/MessageTypeHelper';
|
||||||
import inboxMixin, { INBOX_FEATURES } from 'shared/mixins/inboxMixin';
|
import { useInbox, INBOX_FEATURES } from 'shared/composables/useInbox';
|
||||||
import { trimContent, debounce } from '@chatwoot/utils';
|
import { trimContent, debounce } from '@chatwoot/utils';
|
||||||
import wootConstants from 'dashboard/constants/globals';
|
import wootConstants from 'dashboard/constants/globals';
|
||||||
import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events';
|
import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events';
|
||||||
@@ -60,7 +61,7 @@ export default {
|
|||||||
MessageSignatureMissingAlert,
|
MessageSignatureMissingAlert,
|
||||||
ArticleSearchPopover,
|
ArticleSearchPopover,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin, fileUploadMixin, keyboardEventListenerMixins],
|
mixins: [messageFormatterMixin, fileUploadMixin, keyboardEventListenerMixins],
|
||||||
props: {
|
props: {
|
||||||
popoutReplyBox: {
|
popoutReplyBox: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -68,6 +69,22 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const {
|
||||||
|
is360DialogWhatsAppChannel,
|
||||||
|
isAPIInbox,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
isATwitterInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isASmsInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isAnEmailChannel,
|
||||||
|
isATelegramChannel,
|
||||||
|
isALineChannel,
|
||||||
|
channelType,
|
||||||
|
isAWhatsAppCloudChannel,
|
||||||
|
isATwilioWhatsAppChannel,
|
||||||
|
inbox,
|
||||||
|
} = useInbox({ getCurrentChat: true });
|
||||||
const {
|
const {
|
||||||
uiSettings,
|
uiSettings,
|
||||||
updateUISettings,
|
updateUISettings,
|
||||||
@@ -80,6 +97,20 @@ export default {
|
|||||||
updateUISettings,
|
updateUISettings,
|
||||||
isEditorHotKeyEnabled,
|
isEditorHotKeyEnabled,
|
||||||
fetchSignatureFlagFromUISettings,
|
fetchSignatureFlagFromUISettings,
|
||||||
|
is360DialogWhatsAppChannel,
|
||||||
|
isAPIInbox,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
isATwitterInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isASmsInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isAnEmailChannel,
|
||||||
|
isATelegramChannel,
|
||||||
|
isALineChannel,
|
||||||
|
channelType,
|
||||||
|
isAWhatsAppCloudChannel,
|
||||||
|
isATwilioWhatsAppChannel,
|
||||||
|
inbox,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -189,9 +220,6 @@ export default {
|
|||||||
inboxId() {
|
inboxId() {
|
||||||
return this.currentChat.inbox_id;
|
return this.currentChat.inbox_id;
|
||||||
},
|
},
|
||||||
inbox() {
|
|
||||||
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
|
||||||
},
|
|
||||||
messagePlaceHolder() {
|
messagePlaceHolder() {
|
||||||
return this.isPrivate
|
return this.isPrivate
|
||||||
? this.$t('CONVERSATION.FOOTER.PRIVATE_MSG_INPUT')
|
? this.$t('CONVERSATION.FOOTER.PRIVATE_MSG_INPUT')
|
||||||
@@ -1202,6 +1230,12 @@ export default {
|
|||||||
:message="message"
|
:message="message"
|
||||||
:portal-slug="connectedPortalSlug"
|
:portal-slug="connectedPortalSlug"
|
||||||
:new-conversation-modal-active="newConversationModalActive"
|
:new-conversation-modal-active="newConversationModalActive"
|
||||||
|
:is-a-line-channel="isALineChannel"
|
||||||
|
:is-a-twilio-whatsapp-channel="isATwilioWhatsAppChannel"
|
||||||
|
:is-a-web-widget-inbox="isAWebWidgetInbox"
|
||||||
|
:is-an-email-channel="isAnEmailChannel"
|
||||||
|
:is-api-inbox="isAPIInbox"
|
||||||
|
:channel-type="channelType"
|
||||||
@selectWhatsappTemplate="openWhatsappTemplateModal"
|
@selectWhatsappTemplate="openWhatsappTemplateModal"
|
||||||
@toggleEditor="toggleRichContentEditor"
|
@toggleEditor="toggleRichContentEditor"
|
||||||
@replaceText="replaceText"
|
@replaceText="replaceText"
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages';
|
import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
import { messageTimestamp } from 'shared/helpers/timeHelper';
|
import { messageTimestamp } from 'shared/helpers/timeHelper';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [inboxMixin],
|
|
||||||
props: {
|
props: {
|
||||||
sender: {
|
sender: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -55,10 +54,33 @@ export default {
|
|||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
setup(props) {
|
||||||
|
const {
|
||||||
|
inbox,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
isATwilioChannel,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isASmsInbox,
|
||||||
|
isATelegramChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isAPIInbox,
|
||||||
|
isAnEmailChannel,
|
||||||
|
} = useInbox({ inboxId: props.inboxId });
|
||||||
|
return {
|
||||||
|
inbox,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
isATwilioChannel,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isASmsInbox,
|
||||||
|
isATelegramChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isAPIInbox,
|
||||||
|
isAnEmailChannel,
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
inbox() {
|
|
||||||
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
|
||||||
},
|
|
||||||
isIncoming() {
|
isIncoming() {
|
||||||
return MESSAGE_TYPE.INCOMING === this.messageType;
|
return MESSAGE_TYPE.INCOMING === this.messageType;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import DyteVideoCall from './integrations/Dyte.vue';
|
import DyteVideoCall from './integrations/Dyte.vue';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { DyteVideoCall },
|
components: { DyteVideoCall },
|
||||||
mixins: [inboxMixin],
|
|
||||||
props: {
|
props: {
|
||||||
messageId: {
|
messageId: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
@@ -19,14 +18,20 @@ export default {
|
|||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
setup(props) {
|
||||||
|
const { isAPIInbox, isAWebWidgetInbox } = useInbox({
|
||||||
|
inboxId: props.inboxId,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
isAPIInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showDyteIntegration() {
|
showDyteIntegration() {
|
||||||
const isEnabledOnTheInbox = this.isAPIInbox || this.isAWebWidgetInbox;
|
const isEnabledOnTheInbox = this.isAPIInbox || this.isAWebWidgetInbox;
|
||||||
return isEnabledOnTheInbox && this.contentAttributes.type === 'dyte';
|
return isEnabledOnTheInbox && this.contentAttributes.type === 'dyte';
|
||||||
},
|
},
|
||||||
inbox() {
|
|
||||||
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { INBOX_TYPES } from 'shared/mixins/inboxMixin';
|
import { INBOX_TYPES } from 'shared/composables/useInbox';
|
||||||
|
|
||||||
export const getInboxSource = (type, phoneNumber, inbox) => {
|
export const getInboxSource = (type, phoneNumber, inbox) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
+10
-5
@@ -9,12 +9,11 @@ import CannedResponse from 'dashboard/components/widgets/conversation/CannedResp
|
|||||||
import MessageSignatureMissingAlert from 'dashboard/components/widgets/conversation/MessageSignatureMissingAlert';
|
import MessageSignatureMissingAlert from 'dashboard/components/widgets/conversation/MessageSignatureMissingAlert';
|
||||||
import InboxDropdownItem from 'dashboard/components/widgets/InboxDropdownItem.vue';
|
import InboxDropdownItem from 'dashboard/components/widgets/InboxDropdownItem.vue';
|
||||||
import WhatsappTemplates from './WhatsappTemplates.vue';
|
import WhatsappTemplates from './WhatsappTemplates.vue';
|
||||||
import { INBOX_TYPES } from 'shared/mixins/inboxMixin';
|
|
||||||
import { ExceptionWithMessage } from 'shared/helpers/CustomErrors';
|
import { ExceptionWithMessage } from 'shared/helpers/CustomErrors';
|
||||||
import { getInboxSource } from 'dashboard/helper/inbox';
|
import { getInboxSource } from 'dashboard/helper/inbox';
|
||||||
import { useVuelidate } from '@vuelidate/core';
|
import { useVuelidate } from '@vuelidate/core';
|
||||||
import { required, requiredIf } from '@vuelidate/validators';
|
import { required, requiredIf } from '@vuelidate/validators';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox, INBOX_TYPES } from 'shared/composables/useInbox';
|
||||||
import FileUpload from 'vue-upload-component';
|
import FileUpload from 'vue-upload-component';
|
||||||
import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview';
|
import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview';
|
||||||
import { ALLOWED_FILE_TYPES } from 'shared/constants/messages';
|
import { ALLOWED_FILE_TYPES } from 'shared/constants/messages';
|
||||||
@@ -36,7 +35,7 @@ export default {
|
|||||||
AttachmentPreview,
|
AttachmentPreview,
|
||||||
MessageSignatureMissingAlert,
|
MessageSignatureMissingAlert,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin, fileUploadMixin],
|
mixins: [fileUploadMixin],
|
||||||
props: {
|
props: {
|
||||||
contact: {
|
contact: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -47,12 +46,18 @@ export default {
|
|||||||
default: () => {},
|
default: () => {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup(props) {
|
||||||
|
const { channelType } = useInbox({ inboxObj: props.targetInbox });
|
||||||
const { fetchSignatureFlagFromUISettings, setSignatureFlagForInbox } =
|
const { fetchSignatureFlagFromUISettings, setSignatureFlagForInbox } =
|
||||||
useUISettings();
|
useUISettings();
|
||||||
const v$ = useVuelidate();
|
const v$ = useVuelidate();
|
||||||
|
|
||||||
return { fetchSignatureFlagFromUISettings, setSignatureFlagForInbox, v$ };
|
return {
|
||||||
|
fetchSignatureFlagFromUISettings,
|
||||||
|
setSignatureFlagForInbox,
|
||||||
|
v$,
|
||||||
|
channelType,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useAlert } from 'dashboard/composables';
|
|||||||
import { useVuelidate } from '@vuelidate/core';
|
import { useVuelidate } from '@vuelidate/core';
|
||||||
import SettingIntroBanner from 'dashboard/components/widgets/SettingIntroBanner.vue';
|
import SettingIntroBanner from 'dashboard/components/widgets/SettingIntroBanner.vue';
|
||||||
import SettingsSection from '../../../../components/SettingsSection.vue';
|
import SettingsSection from '../../../../components/SettingsSection.vue';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
import FacebookReauthorize from './facebook/Reauthorize.vue';
|
import FacebookReauthorize from './facebook/Reauthorize.vue';
|
||||||
import PreChatFormSettings from './PreChatForm/Settings.vue';
|
import PreChatFormSettings from './PreChatForm/Settings.vue';
|
||||||
import WeeklyAvailability from './components/WeeklyAvailability.vue';
|
import WeeklyAvailability from './components/WeeklyAvailability.vue';
|
||||||
@@ -33,9 +33,42 @@ export default {
|
|||||||
SenderNameExamplePreview,
|
SenderNameExamplePreview,
|
||||||
MicrosoftReauthorize,
|
MicrosoftReauthorize,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin],
|
|
||||||
setup() {
|
setup() {
|
||||||
return { v$: useVuelidate() };
|
const {
|
||||||
|
isAMicrosoftInbox,
|
||||||
|
isAGoogleInbox,
|
||||||
|
isAPIInbox,
|
||||||
|
isATwitterInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isATwilioChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAnEmailChannel,
|
||||||
|
isATwilioSMSChannel,
|
||||||
|
isASmsInbox,
|
||||||
|
isATwilioWhatsAppChannel,
|
||||||
|
isAWhatsAppCloudChannel,
|
||||||
|
is360DialogWhatsAppChannel,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
} = useInbox({ inboxId: this.currentInboxId });
|
||||||
|
return {
|
||||||
|
v$: useVuelidate(),
|
||||||
|
isAMicrosoftInbox,
|
||||||
|
isAGoogleInbox,
|
||||||
|
isAPIInbox,
|
||||||
|
isATwitterInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isATwilioChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAnEmailChannel,
|
||||||
|
isATwilioSMSChannel,
|
||||||
|
isASmsInbox,
|
||||||
|
isATwilioWhatsAppChannel,
|
||||||
|
isAWhatsAppCloudChannel,
|
||||||
|
is360DialogWhatsAppChannel,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
+11
-2
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { useAlert } from 'dashboard/composables';
|
import { useAlert } from 'dashboard/composables';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
import SettingsSection from 'dashboard/components/SettingsSection.vue';
|
import SettingsSection from 'dashboard/components/SettingsSection.vue';
|
||||||
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
|
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
|
||||||
import BusinessDay from './BusinessDay.vue';
|
import BusinessDay from './BusinessDay.vue';
|
||||||
@@ -23,13 +23,22 @@ export default {
|
|||||||
BusinessDay,
|
BusinessDay,
|
||||||
WootMessageEditor,
|
WootMessageEditor,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin],
|
|
||||||
props: {
|
props: {
|
||||||
inbox: {
|
inbox: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
setup(props) {
|
||||||
|
const { isATwilioChannel, isATwitterInbox, isAFacebookInbox } = useInbox({
|
||||||
|
inboxObj: props.inbox,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
isATwitterInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isATwilioChannel,
|
||||||
|
};
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isBusinessHoursEnabled: false,
|
isBusinessHoursEnabled: false,
|
||||||
|
|||||||
+19
-4
@@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { useAlert } from 'dashboard/composables';
|
import { useAlert } from 'dashboard/composables';
|
||||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
import { useInbox } from 'shared/composables/useInbox';
|
||||||
import SettingsSection from '../../../../../components/SettingsSection.vue';
|
import SettingsSection from '../../../../../components/SettingsSection.vue';
|
||||||
import ImapSettings from '../ImapSettings.vue';
|
import ImapSettings from '../ImapSettings.vue';
|
||||||
import SmtpSettings from '../SmtpSettings.vue';
|
import SmtpSettings from '../SmtpSettings.vue';
|
||||||
@@ -13,15 +13,30 @@ export default {
|
|||||||
ImapSettings,
|
ImapSettings,
|
||||||
SmtpSettings,
|
SmtpSettings,
|
||||||
},
|
},
|
||||||
mixins: [inboxMixin],
|
|
||||||
props: {
|
props: {
|
||||||
inbox: {
|
inbox: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup(props) {
|
||||||
return { v$: useVuelidate() };
|
const {
|
||||||
|
isAPIInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isATwilioChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAnEmailChannel,
|
||||||
|
} = useInbox({
|
||||||
|
inboxObj: props.inbox,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
v$: useVuelidate(),
|
||||||
|
isAPIInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isATwilioChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAnEmailChannel,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers';
|
import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers';
|
||||||
import * as types from '../mutation-types';
|
import * as types from '../mutation-types';
|
||||||
import { INBOX_TYPES } from 'shared/mixins/inboxMixin';
|
import { INBOX_TYPES } from 'shared/composables/useInbox';
|
||||||
import InboxesAPI from '../../api/inboxes';
|
import InboxesAPI from '../../api/inboxes';
|
||||||
import WebChannel from '../../api/channel/webChannel';
|
import WebChannel from '../../api/channel/webChannel';
|
||||||
import FBChannel from '../../api/channel/fbChannel';
|
import FBChannel from '../../api/channel/fbChannel';
|
||||||
|
|||||||
@@ -0,0 +1,148 @@
|
|||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
import { useInbox } from '../useInbox';
|
||||||
|
|
||||||
|
// Mock the useStore composable
|
||||||
|
vi.mock('dashboard/composables/store', () => ({
|
||||||
|
useStore: () => ({
|
||||||
|
getters: {
|
||||||
|
'inboxes/getInbox': vi.fn(id => ({
|
||||||
|
id,
|
||||||
|
channel_type: 'Channel::WebWidget',
|
||||||
|
})),
|
||||||
|
getSelectedChat: {
|
||||||
|
id: 1,
|
||||||
|
inbox_id: 1,
|
||||||
|
channel_type: 'Channel::WebWidget',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('useInbox', () => {
|
||||||
|
const createInbox = (channelType, additionalConfig = {}) => ({
|
||||||
|
channel_type: channelType,
|
||||||
|
...additionalConfig,
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the correct channel type', () => {
|
||||||
|
const inbox = createInbox('Channel::WebWidget');
|
||||||
|
const { channelType } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(channelType.value).toBe('Channel::WebWidget');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isAPIInbox returns true if channel type is API', () => {
|
||||||
|
const inbox = createInbox('Channel::Api');
|
||||||
|
const { isAPIInbox } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isAPIInbox.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isATwitterInbox returns true if channel type is twitter', () => {
|
||||||
|
const inbox = createInbox('Channel::TwitterProfile');
|
||||||
|
const { isATwitterInbox } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isATwitterInbox.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isAFacebookInbox returns true if channel type is Facebook', () => {
|
||||||
|
const inbox = createInbox('Channel::FacebookPage');
|
||||||
|
const { isAFacebookInbox } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isAFacebookInbox.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isAWebWidgetInbox returns true if channel type is WebWidget', () => {
|
||||||
|
const inbox = createInbox('Channel::WebWidget');
|
||||||
|
const { isAWebWidgetInbox } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isAWebWidgetInbox.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isASmsInbox returns true if channel type is sms', () => {
|
||||||
|
const inbox = createInbox('Channel::Sms');
|
||||||
|
const { isASmsInbox } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isASmsInbox.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isASmsInbox returns true if channel type is twilio sms', () => {
|
||||||
|
const inbox = createInbox('Channel::TwilioSms', { medium: 'sms' });
|
||||||
|
const { isASmsInbox } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isASmsInbox.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isATwilioSMSChannel', () => {
|
||||||
|
it('returns true if channel type is Twilio and medium is SMS', () => {
|
||||||
|
const inbox = createInbox('Channel::TwilioSms', { medium: 'sms' });
|
||||||
|
const { isATwilioSMSChannel } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isATwilioSMSChannel.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if channel type is Twilio but medium is not SMS', () => {
|
||||||
|
const inbox = createInbox('Channel::TwilioSms', { medium: 'whatsapp' });
|
||||||
|
const { isATwilioSMSChannel } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isATwilioSMSChannel.value).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if channel type is not Twilio but medium is SMS', () => {
|
||||||
|
const inbox = createInbox('Channel::NotTwilio', { medium: 'sms' });
|
||||||
|
const { isATwilioSMSChannel } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isATwilioSMSChannel.value).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Badges', () => {
|
||||||
|
it('inboxBadge returns correct badge for Telegram', () => {
|
||||||
|
const inbox = createInbox('Channel::Telegram');
|
||||||
|
const { inboxBadge } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(inboxBadge.value).toBe('Channel::Telegram');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('inboxBadge returns correct badge for WhatsApp channel', () => {
|
||||||
|
const inbox = createInbox('Channel::Whatsapp');
|
||||||
|
const { inboxBadge } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(inboxBadge.value).toBe('whatsapp');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('inboxBadge returns the twitterBadge when isATwitterInbox is true', () => {
|
||||||
|
const inbox = createInbox('Channel::TwitterProfile');
|
||||||
|
const { inboxBadge } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(inboxBadge.value).toBe('twitter-dm');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('WhatsApp channel', () => {
|
||||||
|
it('returns correct whatsAppAPIProvider', () => {
|
||||||
|
const inbox = createInbox('Channel::Whatsapp', {
|
||||||
|
provider: 'whatsapp_cloud',
|
||||||
|
});
|
||||||
|
const { whatsAppAPIProvider } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(whatsAppAPIProvider.value).toBe('whatsapp_cloud');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('isAWhatsAppCloudChannel returns true if channel type is WhatsApp and provider is whatsapp_cloud', () => {
|
||||||
|
const inbox = createInbox('Channel::Whatsapp', {
|
||||||
|
provider: 'whatsapp_cloud',
|
||||||
|
});
|
||||||
|
const { isAWhatsAppCloudChannel } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(isAWhatsAppCloudChannel.value).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is360DialogWhatsAppChannel returns true if channel type is WhatsApp and provider is default', () => {
|
||||||
|
const inbox = createInbox('Channel::Whatsapp', { provider: 'default' });
|
||||||
|
const { is360DialogWhatsAppChannel } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(is360DialogWhatsAppChannel.value).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#inboxHasFeature', () => {
|
||||||
|
it('detects the correct feature', () => {
|
||||||
|
const inbox = createInbox('Channel::Telegram');
|
||||||
|
const { inboxHasFeature } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(inboxHasFeature('replyTo')).toBe(true);
|
||||||
|
expect(inboxHasFeature('feature-does-not-exist')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for feature not included', () => {
|
||||||
|
const inbox = createInbox('Channel::Sms');
|
||||||
|
const { inboxHasFeature } = useInbox({ inboxObj: inbox });
|
||||||
|
expect(inboxHasFeature('replyTo')).toBe(false);
|
||||||
|
expect(inboxHasFeature('feature-does-not-exist')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { useStore } from 'dashboard/composables/store';
|
||||||
|
|
||||||
|
export const INBOX_TYPES = {
|
||||||
|
WEB: 'Channel::WebWidget',
|
||||||
|
FB: 'Channel::FacebookPage',
|
||||||
|
TWITTER: 'Channel::TwitterProfile',
|
||||||
|
TWILIO: 'Channel::TwilioSms',
|
||||||
|
WHATSAPP: 'Channel::Whatsapp',
|
||||||
|
API: 'Channel::Api',
|
||||||
|
EMAIL: 'Channel::Email',
|
||||||
|
TELEGRAM: 'Channel::Telegram',
|
||||||
|
LINE: 'Channel::Line',
|
||||||
|
SMS: 'Channel::Sms',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const INBOX_FEATURES = {
|
||||||
|
REPLY_TO: 'replyTo',
|
||||||
|
REPLY_TO_OUTGOING: 'replyToOutgoing',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const INBOX_FEATURE_MAP = {
|
||||||
|
[INBOX_FEATURES.REPLY_TO]: [
|
||||||
|
INBOX_TYPES.FB,
|
||||||
|
INBOX_TYPES.WEB,
|
||||||
|
INBOX_TYPES.TWITTER,
|
||||||
|
INBOX_TYPES.WHATSAPP,
|
||||||
|
INBOX_TYPES.TELEGRAM,
|
||||||
|
INBOX_TYPES.API,
|
||||||
|
],
|
||||||
|
[INBOX_FEATURES.REPLY_TO_OUTGOING]: [
|
||||||
|
INBOX_TYPES.WEB,
|
||||||
|
INBOX_TYPES.TWITTER,
|
||||||
|
INBOX_TYPES.WHATSAPP,
|
||||||
|
INBOX_TYPES.TELEGRAM,
|
||||||
|
INBOX_TYPES.API,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// useInbox(inboxId) {}
|
||||||
|
// useChatInbox {
|
||||||
|
// chat = getCurrentChat
|
||||||
|
// return useInbox(chat.inboxId)
|
||||||
|
// }
|
||||||
|
|
||||||
|
export function useInbox({ inboxObj, inboxId, chat, getCurrentChat }) {
|
||||||
|
const store = useStore();
|
||||||
|
const inbox = ref(null);
|
||||||
|
if (inboxObj) {
|
||||||
|
inbox.value = inboxObj;
|
||||||
|
}
|
||||||
|
if (inboxId) {
|
||||||
|
inbox.value = store.getters['inboxes/getInbox'](inboxId);
|
||||||
|
}
|
||||||
|
if (getCurrentChat) {
|
||||||
|
inbox.value = store.getters.getSelectedChat;
|
||||||
|
}
|
||||||
|
const channelType = computed(() => inbox.value.channel_type);
|
||||||
|
const whatsAppAPIProvider = computed(() => inbox.value.provider || '');
|
||||||
|
|
||||||
|
const isAPIInbox = computed(() => channelType.value === INBOX_TYPES.API);
|
||||||
|
const isATwitterInbox = computed(
|
||||||
|
() => channelType.value === INBOX_TYPES.TWITTER
|
||||||
|
);
|
||||||
|
const isAFacebookInbox = computed(() => channelType.value === INBOX_TYPES.FB);
|
||||||
|
const isAWebWidgetInbox = computed(
|
||||||
|
() => channelType.value === INBOX_TYPES.WEB
|
||||||
|
);
|
||||||
|
const isATwilioChannel = computed(
|
||||||
|
() => channelType.value === INBOX_TYPES.TWILIO
|
||||||
|
);
|
||||||
|
const isALineChannel = computed(() => channelType.value === INBOX_TYPES.LINE);
|
||||||
|
const isAnEmailChannel = computed(
|
||||||
|
() => channelType.value === INBOX_TYPES.EMAIL
|
||||||
|
);
|
||||||
|
const isATelegramChannel = computed(
|
||||||
|
() => channelType.value === INBOX_TYPES.TELEGRAM
|
||||||
|
);
|
||||||
|
|
||||||
|
const isATwilioSMSChannel = computed(() => {
|
||||||
|
const medium = inbox.value.medium || '';
|
||||||
|
return isATwilioChannel.value && medium === 'sms';
|
||||||
|
});
|
||||||
|
|
||||||
|
const isAMicrosoftInbox = computed(
|
||||||
|
() => isAnEmailChannel.value && inbox.value.provider === 'microsoft'
|
||||||
|
);
|
||||||
|
|
||||||
|
const isAGoogleInbox = computed(
|
||||||
|
() => isAnEmailChannel.value && inbox.value.provider === 'google'
|
||||||
|
);
|
||||||
|
|
||||||
|
const isASmsInbox = computed(
|
||||||
|
() => channelType.value === INBOX_TYPES.SMS || isATwilioSMSChannel.value
|
||||||
|
);
|
||||||
|
|
||||||
|
const isATwilioWhatsAppChannel = computed(() => {
|
||||||
|
const medium = inbox.value.medium || '';
|
||||||
|
return isATwilioChannel.value && medium === 'whatsapp';
|
||||||
|
});
|
||||||
|
|
||||||
|
const isAWhatsAppCloudChannel = computed(
|
||||||
|
() =>
|
||||||
|
channelType.value === INBOX_TYPES.WHATSAPP &&
|
||||||
|
whatsAppAPIProvider.value === 'whatsapp_cloud'
|
||||||
|
);
|
||||||
|
|
||||||
|
const is360DialogWhatsAppChannel = computed(
|
||||||
|
() =>
|
||||||
|
channelType.value === INBOX_TYPES.WHATSAPP &&
|
||||||
|
whatsAppAPIProvider.value === 'default'
|
||||||
|
);
|
||||||
|
|
||||||
|
const chatAdditionalAttributes = computed(() => {
|
||||||
|
return chat?.additional_attributes || {};
|
||||||
|
});
|
||||||
|
|
||||||
|
const isTwitterInboxTweet = computed(
|
||||||
|
() => chatAdditionalAttributes.value.type === 'tweet'
|
||||||
|
);
|
||||||
|
|
||||||
|
const twilioBadge = computed(
|
||||||
|
() => `${isATwilioSMSChannel.value ? 'sms' : 'whatsapp'}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const twitterBadge = computed(
|
||||||
|
() => `${isTwitterInboxTweet.value ? 'twitter-tweet' : 'twitter-dm'}`
|
||||||
|
);
|
||||||
|
|
||||||
|
const facebookBadge = computed(
|
||||||
|
() => chatAdditionalAttributes.value.type || 'facebook'
|
||||||
|
);
|
||||||
|
|
||||||
|
const isAWhatsAppChannel = computed(
|
||||||
|
() =>
|
||||||
|
channelType.value === INBOX_TYPES.WHATSAPP ||
|
||||||
|
isATwilioWhatsAppChannel.value
|
||||||
|
);
|
||||||
|
|
||||||
|
const inboxBadge = computed(() => {
|
||||||
|
if (isATwitterInbox.value) return twitterBadge.value;
|
||||||
|
if (isAFacebookInbox.value) return facebookBadge.value;
|
||||||
|
if (isATwilioChannel.value) return twilioBadge.value;
|
||||||
|
if (isAWhatsAppChannel.value) return 'whatsapp';
|
||||||
|
return channelType.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
function inboxHasFeature(feature) {
|
||||||
|
return INBOX_FEATURE_MAP[feature]?.includes(channelType.value) ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
channelType,
|
||||||
|
whatsAppAPIProvider,
|
||||||
|
isAMicrosoftInbox,
|
||||||
|
isAGoogleInbox,
|
||||||
|
isAPIInbox,
|
||||||
|
inbox,
|
||||||
|
isATwitterInbox,
|
||||||
|
isAFacebookInbox,
|
||||||
|
isAWebWidgetInbox,
|
||||||
|
isATwilioChannel,
|
||||||
|
isALineChannel,
|
||||||
|
isAnEmailChannel,
|
||||||
|
isATelegramChannel,
|
||||||
|
isATwilioSMSChannel,
|
||||||
|
isASmsInbox,
|
||||||
|
isATwilioWhatsAppChannel,
|
||||||
|
isAWhatsAppCloudChannel,
|
||||||
|
is360DialogWhatsAppChannel,
|
||||||
|
chatAdditionalAttributes,
|
||||||
|
isTwitterInboxTweet,
|
||||||
|
twilioBadge,
|
||||||
|
twitterBadge,
|
||||||
|
facebookBadge,
|
||||||
|
inboxBadge,
|
||||||
|
isAWhatsAppChannel,
|
||||||
|
inboxHasFeature,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
export const INBOX_TYPES = {
|
|
||||||
WEB: 'Channel::WebWidget',
|
|
||||||
FB: 'Channel::FacebookPage',
|
|
||||||
TWITTER: 'Channel::TwitterProfile',
|
|
||||||
TWILIO: 'Channel::TwilioSms',
|
|
||||||
WHATSAPP: 'Channel::Whatsapp',
|
|
||||||
API: 'Channel::Api',
|
|
||||||
EMAIL: 'Channel::Email',
|
|
||||||
TELEGRAM: 'Channel::Telegram',
|
|
||||||
LINE: 'Channel::Line',
|
|
||||||
SMS: 'Channel::Sms',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const INBOX_FEATURES = {
|
|
||||||
REPLY_TO: 'replyTo',
|
|
||||||
REPLY_TO_OUTGOING: 'replyToOutgoing',
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is a single source of truth for inbox features
|
|
||||||
// This is used to check if a feature is available for a particular inbox or not
|
|
||||||
export const INBOX_FEATURE_MAP = {
|
|
||||||
[INBOX_FEATURES.REPLY_TO]: [
|
|
||||||
INBOX_TYPES.FB,
|
|
||||||
INBOX_TYPES.WEB,
|
|
||||||
INBOX_TYPES.TWITTER,
|
|
||||||
INBOX_TYPES.WHATSAPP,
|
|
||||||
INBOX_TYPES.TELEGRAM,
|
|
||||||
INBOX_TYPES.API,
|
|
||||||
],
|
|
||||||
[INBOX_FEATURES.REPLY_TO_OUTGOING]: [
|
|
||||||
INBOX_TYPES.WEB,
|
|
||||||
INBOX_TYPES.TWITTER,
|
|
||||||
INBOX_TYPES.WHATSAPP,
|
|
||||||
INBOX_TYPES.TELEGRAM,
|
|
||||||
INBOX_TYPES.API,
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
computed: {
|
|
||||||
channelType() {
|
|
||||||
return this.inbox.channel_type;
|
|
||||||
},
|
|
||||||
whatsAppAPIProvider() {
|
|
||||||
return this.inbox.provider || '';
|
|
||||||
},
|
|
||||||
isAMicrosoftInbox() {
|
|
||||||
return this.isAnEmailChannel && this.inbox.provider === 'microsoft';
|
|
||||||
},
|
|
||||||
isAGoogleInbox() {
|
|
||||||
return this.isAnEmailChannel && this.inbox.provider === 'google';
|
|
||||||
},
|
|
||||||
isAPIInbox() {
|
|
||||||
return this.channelType === INBOX_TYPES.API;
|
|
||||||
},
|
|
||||||
isATwitterInbox() {
|
|
||||||
return this.channelType === INBOX_TYPES.TWITTER;
|
|
||||||
},
|
|
||||||
isAFacebookInbox() {
|
|
||||||
return this.channelType === INBOX_TYPES.FB;
|
|
||||||
},
|
|
||||||
isAWebWidgetInbox() {
|
|
||||||
return this.channelType === INBOX_TYPES.WEB;
|
|
||||||
},
|
|
||||||
isATwilioChannel() {
|
|
||||||
return this.channelType === INBOX_TYPES.TWILIO;
|
|
||||||
},
|
|
||||||
isALineChannel() {
|
|
||||||
return this.channelType === INBOX_TYPES.LINE;
|
|
||||||
},
|
|
||||||
isAnEmailChannel() {
|
|
||||||
return this.channelType === INBOX_TYPES.EMAIL;
|
|
||||||
},
|
|
||||||
isATelegramChannel() {
|
|
||||||
return this.channelType === INBOX_TYPES.TELEGRAM;
|
|
||||||
},
|
|
||||||
isATwilioSMSChannel() {
|
|
||||||
const { medium: medium = '' } = this.inbox;
|
|
||||||
return this.isATwilioChannel && medium === 'sms';
|
|
||||||
},
|
|
||||||
isASmsInbox() {
|
|
||||||
return this.channelType === INBOX_TYPES.SMS || this.isATwilioSMSChannel;
|
|
||||||
},
|
|
||||||
isATwilioWhatsAppChannel() {
|
|
||||||
const { medium: medium = '' } = this.inbox;
|
|
||||||
return this.isATwilioChannel && medium === 'whatsapp';
|
|
||||||
},
|
|
||||||
isAWhatsAppCloudChannel() {
|
|
||||||
return (
|
|
||||||
this.channelType === INBOX_TYPES.WHATSAPP &&
|
|
||||||
this.whatsAppAPIProvider === 'whatsapp_cloud'
|
|
||||||
);
|
|
||||||
},
|
|
||||||
is360DialogWhatsAppChannel() {
|
|
||||||
return (
|
|
||||||
this.channelType === INBOX_TYPES.WHATSAPP &&
|
|
||||||
this.whatsAppAPIProvider === 'default'
|
|
||||||
);
|
|
||||||
},
|
|
||||||
chatAdditionalAttributes() {
|
|
||||||
const { additional_attributes: additionalAttributes } = this.chat || {};
|
|
||||||
return additionalAttributes || {};
|
|
||||||
},
|
|
||||||
isTwitterInboxTweet() {
|
|
||||||
return this.chatAdditionalAttributes.type === 'tweet';
|
|
||||||
},
|
|
||||||
twilioBadge() {
|
|
||||||
return `${this.isATwilioSMSChannel ? 'sms' : 'whatsapp'}`;
|
|
||||||
},
|
|
||||||
twitterBadge() {
|
|
||||||
return `${this.isTwitterInboxTweet ? 'twitter-tweet' : 'twitter-dm'}`;
|
|
||||||
},
|
|
||||||
facebookBadge() {
|
|
||||||
return this.chatAdditionalAttributes.type || 'facebook';
|
|
||||||
},
|
|
||||||
inboxBadge() {
|
|
||||||
let badgeKey = '';
|
|
||||||
if (this.isATwitterInbox) {
|
|
||||||
badgeKey = this.twitterBadge;
|
|
||||||
} else if (this.isAFacebookInbox) {
|
|
||||||
badgeKey = this.facebookBadge;
|
|
||||||
} else if (this.isATwilioChannel) {
|
|
||||||
badgeKey = this.twilioBadge;
|
|
||||||
} else if (this.isAWhatsAppChannel) {
|
|
||||||
badgeKey = 'whatsapp';
|
|
||||||
}
|
|
||||||
return badgeKey || this.channelType;
|
|
||||||
},
|
|
||||||
isAWhatsAppChannel() {
|
|
||||||
return (
|
|
||||||
this.channelType === INBOX_TYPES.WHATSAPP ||
|
|
||||||
this.isATwilioWhatsAppChannel
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
inboxHasFeature(feature) {
|
|
||||||
return INBOX_FEATURE_MAP[feature]?.includes(this.channelType) ?? false;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
import { shallowMount } from '@vue/test-utils';
|
|
||||||
import inboxMixin from '../inboxMixin';
|
|
||||||
|
|
||||||
function getComponentConfigForInbox(channelType, additionalConfig = {}) {
|
|
||||||
return {
|
|
||||||
render() {},
|
|
||||||
mixins: [inboxMixin],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
inbox: {
|
|
||||||
channel_type: channelType,
|
|
||||||
...additionalConfig,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getComponentConfigForChat(chat) {
|
|
||||||
return {
|
|
||||||
render() {},
|
|
||||||
mixins: [inboxMixin],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
chat,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('inboxMixin', () => {
|
|
||||||
it('returns the correct channel type', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::WebWidget');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.channelType).toBe('Channel::WebWidget');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAPIInbox returns true if channel type is API', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Api');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAPIInbox).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isATwitterInbox returns true if channel type is twitter', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwitterProfile');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwitterInbox).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAFacebookInbox returns true if channel type is Facebook', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::FacebookPage');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAFacebookInbox).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAWebWidgetInbox returns true if channel type is Facebook', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::WebWidget');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAWebWidgetInbox).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isASmsInbox returns true if channel type is sms', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Sms');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isASmsInbox).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isASmsInbox returns true if channel type is twilio sms', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: 'sms',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isASmsInbox).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isALineChannel returns true if channel type is Line', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Line');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isALineChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isATelegramChannel returns true if channel type is Telegram', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Telegram');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATelegramChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isATwilioChannel returns true if channel type is Twilio', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('isATwilioSMSChannel', () => {
|
|
||||||
it('returns true if channel type is Twilio and medium is SMS', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: 'sms',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false if channel type is Twilio but medium is not SMS', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: 'whatsapp',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false if channel type is not Twilio but medium is SMS', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::NotTwilio', {
|
|
||||||
medium: 'sms',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false if neither channel type is Twilio nor medium is SMS', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::NotTwilio', {
|
|
||||||
medium: 'not_sms',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false if channel type is Twilio but medium is empty', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: undefined,
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAnEmailChannel returns true if channel type is email', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Email');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAnEmailChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isTwitterInboxTweet returns true if Twitter channel type is tweet', () => {
|
|
||||||
const Component = getComponentConfigForChat({
|
|
||||||
channel_type: 'Channel::TwitterProfile',
|
|
||||||
additional_attributes: {
|
|
||||||
type: 'tweet',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isTwitterInboxTweet).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('twilioBadge returns string sms if channel type is Twilio and medium is sms', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: 'sms',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(true);
|
|
||||||
expect(wrapper.vm.twilioBadge).toBe('sms');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('twitterBadge returns string twitter-tweet if Twitter channel type is tweet', () => {
|
|
||||||
const Component = getComponentConfigForChat({
|
|
||||||
id: 1,
|
|
||||||
additional_attributes: {
|
|
||||||
type: 'tweet',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isTwitterInboxTweet).toBe(true);
|
|
||||||
expect(wrapper.vm.twitterBadge).toBe('twitter-tweet');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Badges', () => {
|
|
||||||
it('inboxBadge returns string Channel::Telegram if isATwilioChannel and isATwitterInbox is false', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Telegram');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isATwilioChannel).toBe(false);
|
|
||||||
expect(wrapper.vm.isATwitterInbox).toBe(false);
|
|
||||||
expect(wrapper.vm.channelType).toBe('Channel::Telegram');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('inboxBadge returns correct badge for WhatsApp channel', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxBadge).toBe('whatsapp');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('inboxBadge returns the twitterBadge when isATwitterInbox is true', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwitterProfile');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxBadge).toBe('twitter-dm');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('inboxBadge returns the facebookBadge when isAFacebookInbox is true', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::FacebookPage');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxBadge).toBe('facebook');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('inboxBadge returns the twilioBadge when isATwilioChannel is true', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: 'sms',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxBadge).toBe('sms');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('inboxBadge returns "whatsapp" when isAWhatsAppChannel is true', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxBadge).toBe('whatsapp');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('inboxBadge returns the channelType when no specific condition is true', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Email');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxBadge).toBe('Channel::Email');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#inboxHasFeature', () => {
|
|
||||||
it('detects the correct feature', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Telegram');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxHasFeature('replyTo')).toBe(true);
|
|
||||||
expect(wrapper.vm.inboxHasFeature('feature-does-not-exist')).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false for feature not included', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Sms');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.inboxHasFeature('replyTo')).toBe(false);
|
|
||||||
expect(wrapper.vm.inboxHasFeature('feature-does-not-exist')).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('WhatsApp channel', () => {
|
|
||||||
it('returns correct whatsAppAPIProvider', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp', {
|
|
||||||
provider: 'whatsapp_cloud',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.whatsAppAPIProvider).toBe('whatsapp_cloud');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns empty whatsAppAPIProvider if nothing is present', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp', {
|
|
||||||
provider: undefined,
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.whatsAppAPIProvider).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAWhatsAppCloudChannel returns true if channel type is WhatsApp and provider is whatsapp_cloud', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp', {
|
|
||||||
provider: 'whatsapp_cloud',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAWhatsAppCloudChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is360DialogWhatsAppChannel returns true if channel type is WhatsApp and provider is default', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp', {
|
|
||||||
provider: 'default',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.is360DialogWhatsAppChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAWhatsAppChannel returns true if channel type is WhatsApp', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::Whatsapp');
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAWhatsAppChannel).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('isAWhatsAppChannel returns true if channel type is Twilio and medium is WhatsApp', () => {
|
|
||||||
const Component = getComponentConfigForInbox('Channel::TwilioSms', {
|
|
||||||
medium: 'whatsapp',
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(Component);
|
|
||||||
expect(wrapper.vm.isAWhatsAppChannel).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user