feat: Disable attachments and emoji picker in the web widget (#1102)
Signed-off-by: Pranav Raj Sreepuram <pranavrajs@gmail.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.app-wrapper {
|
||||
@@ -26,36 +26,40 @@ body {
|
||||
|
||||
.view-box {
|
||||
@include full-height;
|
||||
height: 100vh;
|
||||
@include margin(0);
|
||||
@include space-between-column;
|
||||
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.view-panel {
|
||||
flex-direction: column;
|
||||
@include margin($zero);
|
||||
@include padding($space-normal);
|
||||
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.content-box {
|
||||
overflow: auto;
|
||||
@include padding($space-normal);
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
@include flex;
|
||||
|
||||
align-items: center;
|
||||
color: $color-woot;
|
||||
cursor: pointer;
|
||||
font-size: $font-size-default;
|
||||
font-weight: $font-weight-normal;
|
||||
margin-right: $space-normal;
|
||||
cursor: pointer;
|
||||
|
||||
&:before {
|
||||
vertical-align: text-bottom;
|
||||
margin-right: $space-smaller;
|
||||
&::before {
|
||||
font-size: $font-size-large;
|
||||
margin-right: $space-small;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,12 +70,14 @@ body {
|
||||
.no-items-error-message {
|
||||
@include flex;
|
||||
@include full-height;
|
||||
justify-content: center;
|
||||
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
max-width: $space-mega;
|
||||
@include padding($space-one);
|
||||
|
||||
max-width: $space-mega;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
}
|
||||
|
||||
.settings--content {
|
||||
@include margin($space-small $space-larger);
|
||||
@include margin($space-small $space-large);
|
||||
|
||||
.title {
|
||||
font-weight: $font-weight-medium;
|
||||
|
||||
@@ -7,15 +7,25 @@
|
||||
<p v-if="headerContent" class="small-12 column">
|
||||
{{ headerContent }}
|
||||
</p>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
headerTitle: String,
|
||||
headerContent: String,
|
||||
headerImage: String,
|
||||
headerTitle: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
headerContent: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
headerImage: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -57,15 +57,8 @@ import { mapGetters } from 'vuex';
|
||||
|
||||
import router from '../../routes';
|
||||
import adminMixin from '../../mixins/isAdmin';
|
||||
import { INBOX_TYPES } from 'shared/mixins/inboxMixin';
|
||||
|
||||
const INBOX_TYPES = {
|
||||
WEB: 'Channel::WebWidget',
|
||||
FB: 'Channel::FacebookPage',
|
||||
TWITTER: 'Channel::TwitterProfile',
|
||||
TWILIO: 'Channel::TwilioSms',
|
||||
API: 'Channel::Api',
|
||||
EMAIL: 'Channel::Email',
|
||||
};
|
||||
const getInboxClassByType = type => {
|
||||
switch (type) {
|
||||
case INBOX_TYPES.WEB:
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
<template>
|
||||
<div
|
||||
class="small-3 columns channel"
|
||||
:class="{ inactive: !isActive(channel) }"
|
||||
:class="{ inactive: !isActive }"
|
||||
@click="onItemClick"
|
||||
>
|
||||
<img
|
||||
v-if="channel === 'facebook'"
|
||||
v-if="channel.key === 'facebook'"
|
||||
src="~dashboard/assets/images/channels/facebook.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'twitter'"
|
||||
v-if="channel.key === 'twitter'"
|
||||
src="~dashboard/assets/images/channels/twitter.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'telegram'"
|
||||
v-if="channel.key === 'telegram'"
|
||||
src="~dashboard/assets/images/channels/telegram.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'api'"
|
||||
v-if="channel.key === 'api'"
|
||||
src="~dashboard/assets/images/channels/api.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'email'"
|
||||
v-if="channel.key === 'email'"
|
||||
src="~dashboard/assets/images/channels/email.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'line'"
|
||||
v-if="channel.key === 'line'"
|
||||
src="~dashboard/assets/images/channels/line.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'website'"
|
||||
v-if="channel.key === 'website'"
|
||||
src="~dashboard/assets/images/channels/website.png"
|
||||
/>
|
||||
<img
|
||||
v-if="channel === 'twilio'"
|
||||
v-if="channel.key === 'twilio'"
|
||||
src="~dashboard/assets/images/channels/twilio.png"
|
||||
/>
|
||||
<h3 class="channel__title">
|
||||
{{ channel }}
|
||||
{{ channel.name }}
|
||||
</h3>
|
||||
</div>
|
||||
</template>
|
||||
@@ -45,7 +45,7 @@
|
||||
export default {
|
||||
props: {
|
||||
channel: {
|
||||
type: String,
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
enabledFeatures: {
|
||||
@@ -53,25 +53,28 @@ export default {
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isActive(channel) {
|
||||
computed: {
|
||||
isActive() {
|
||||
const { key } = this.channel;
|
||||
if (Object.keys(this.enabledFeatures) === 0) {
|
||||
return false;
|
||||
}
|
||||
if (channel === 'facebook') {
|
||||
if (key === 'facebook') {
|
||||
return this.enabledFeatures.channel_facebook;
|
||||
}
|
||||
if (channel === 'twitter') {
|
||||
if (key === 'twitter') {
|
||||
return this.enabledFeatures.channel_twitter;
|
||||
}
|
||||
if (channel === 'email') {
|
||||
if (key === 'email') {
|
||||
return this.enabledFeatures.channel_email;
|
||||
}
|
||||
return ['website', 'twilio', 'api'].includes(channel);
|
||||
return ['website', 'twilio', 'api'].includes(key);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onItemClick() {
|
||||
if (this.isActive(this.channel)) {
|
||||
this.$emit('channel-item-click', this.channel);
|
||||
if (this.isActive) {
|
||||
this.$emit('channel-item-click', this.channel.key);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -96,6 +96,7 @@ import {
|
||||
hasPressedShift,
|
||||
} from 'shared/helpers/KeyboardHelpers';
|
||||
import { MESSAGE_MAX_LENGTH } from 'shared/helpers/MessageTypeHelper';
|
||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -104,7 +105,7 @@ export default {
|
||||
FileUpload,
|
||||
ResizableTextArea,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
mixins: [clickaway, inboxMixin],
|
||||
data() {
|
||||
return {
|
||||
message: '',
|
||||
@@ -148,9 +149,6 @@ export default {
|
||||
this.message.length > this.maxLength
|
||||
);
|
||||
},
|
||||
channelType() {
|
||||
return this.inbox.channel_type;
|
||||
},
|
||||
conversationType() {
|
||||
const { additional_attributes: additionalAttributes } = this.currentChat;
|
||||
const type = additionalAttributes ? additionalAttributes.type : '';
|
||||
@@ -174,29 +172,6 @@ export default {
|
||||
}
|
||||
return MESSAGE_MAX_LENGTH.GENERAL;
|
||||
},
|
||||
isATwitterInbox() {
|
||||
return this.channelType === 'Channel::TwitterProfile';
|
||||
},
|
||||
isAFacebookInbox() {
|
||||
return this.channelType === 'Channel::FacebookPage';
|
||||
},
|
||||
isAWebWidgetInbox() {
|
||||
return this.channelType === 'Channel::WebWidget';
|
||||
},
|
||||
isATwilioSMSChannel() {
|
||||
const { phone_number: phoneNumber = '' } = this.inbox;
|
||||
return (
|
||||
this.channelType === 'Channel::TwilioSms' &&
|
||||
!phoneNumber.startsWith('whatsapp')
|
||||
);
|
||||
},
|
||||
isATwilioWhatsappChannel() {
|
||||
const { phone_number: phoneNumber = '' } = this.inbox;
|
||||
return (
|
||||
this.channelType === 'Channel::TwilioSms' &&
|
||||
phoneNumber.startsWith('whatsapp')
|
||||
);
|
||||
},
|
||||
showFileUpload() {
|
||||
return (
|
||||
this.isAWebWidgetInbox ||
|
||||
|
||||
@@ -117,16 +117,16 @@
|
||||
},
|
||||
"API_CHANNEL": {
|
||||
"TITLE": "API Channel",
|
||||
"DESC": "Integrate with API channel and start supporting your customers via chatwoot.",
|
||||
"DESC": "Integrate with API channel and start supporting your customers.",
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Channel Name",
|
||||
"PLACEHOLDER": "Please enter a channel name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"WEBHOOK_URL": {
|
||||
"LABEL": "Webhook Url",
|
||||
"SUBTITLE": "Configure the url where you want to recieve callbacks from chatwoot on events.",
|
||||
"PLACEHOLDER": "Webhook Url"
|
||||
"LABEL": "Webhook URL",
|
||||
"SUBTITLE": "Configure the URL where you want to recieve callbacks on events.",
|
||||
"PLACEHOLDER": "Webhook URL"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create API Channel",
|
||||
"API": {
|
||||
@@ -135,7 +135,7 @@
|
||||
},
|
||||
"EMAIL_CHANNEL": {
|
||||
"TITLE": "Email Channel",
|
||||
"DESC": "Integrate you email inbox with chatwoot.",
|
||||
"DESC": "Integrate you email inbox.",
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Channel Name",
|
||||
"PLACEHOLDER": "Please enter a channel name",
|
||||
@@ -150,7 +150,7 @@
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the email channel"
|
||||
},
|
||||
"FINISH_MESSAGE" : "Start forwarding your emails to the following email address."
|
||||
"FINISH_MESSAGE": "Start forwarding your emails to the following email address."
|
||||
},
|
||||
"AUTH": {
|
||||
"TITLE": "Channels",
|
||||
@@ -212,7 +212,17 @@
|
||||
"ERROR_MESSAGE": "Could not delete inbox. Please try again later."
|
||||
}
|
||||
},
|
||||
"TABS": {
|
||||
"SETTINGS": "Settings",
|
||||
"COLLABORATORS": "Collaborators",
|
||||
"CONFIGURATION": "Configuration"
|
||||
},
|
||||
"SETTINGS": "Settings",
|
||||
"FEATURES": {
|
||||
"LABEL": "Features",
|
||||
"DISPLAY_FILE_PICKER": "Display file picker on the widget",
|
||||
"DISPLAY_EMOJI_PICKER": "Display emoji picker on the widget"
|
||||
},
|
||||
"SETTINGS_POPUP": {
|
||||
"MESSENGER_HEADING": "Messenger Script",
|
||||
"MESSENGER_SUB_HEAD": "Place this button inside your body tag",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
v-model="selectedAgents"
|
||||
:options="agentList"
|
||||
track-by="id"
|
||||
label="name"
|
||||
label="available_name"
|
||||
:multiple="true"
|
||||
:close-on-select="false"
|
||||
:clear-on-select="false"
|
||||
|
||||
@@ -30,14 +30,14 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
channelList: [
|
||||
'website',
|
||||
'facebook',
|
||||
'twitter',
|
||||
'twilio',
|
||||
'email',
|
||||
'api',
|
||||
'telegram',
|
||||
'line',
|
||||
{ key: 'website', name: 'Website' },
|
||||
{ key: 'facebook', name: 'Facebook' },
|
||||
{ key: 'twitter', name: 'Twitter' },
|
||||
{ key: 'twilio', name: 'Twilio' },
|
||||
{ key: 'email', name: 'Email' },
|
||||
{ key: 'api', name: 'API' },
|
||||
{ key: 'telegram', name: 'Telegram' },
|
||||
{ key: 'line', name: 'Line' },
|
||||
],
|
||||
enabledFeatures: {},
|
||||
};
|
||||
|
||||
@@ -3,9 +3,18 @@
|
||||
<woot-modal-header
|
||||
:header-image="inbox.avatarUrl"
|
||||
:header-title="inboxName"
|
||||
/>
|
||||
>
|
||||
<woot-tabs :index="selectedTabIndex" @change="onTabChange">
|
||||
<woot-tabs-item
|
||||
v-for="tab in tabs"
|
||||
:key="tab.key"
|
||||
:name="tab.name"
|
||||
:show-badge="false"
|
||||
/>
|
||||
</woot-tabs>
|
||||
</woot-modal-header>
|
||||
|
||||
<div class="settings--content">
|
||||
<div v-if="selectedTabKey === 'inbox_settings'" class="settings--content">
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.SETTINGS_POPUP.INBOX_UPDATE_TITLE')"
|
||||
:sub-title="$t('INBOX_MGMT.SETTINGS_POPUP.INBOX_UPDATE_SUB_TEXT')"
|
||||
@@ -16,7 +25,7 @@
|
||||
@change="handleImageUpload"
|
||||
/>
|
||||
<woot-input
|
||||
v-if="isAWidgetInbox"
|
||||
v-if="isAWebWidgetInbox"
|
||||
v-model.trim="selectedInboxName"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_NAME.LABEL')"
|
||||
@@ -25,7 +34,7 @@
|
||||
"
|
||||
/>
|
||||
<woot-input
|
||||
v-if="isAWidgetInbox"
|
||||
v-if="isAWebWidgetInbox"
|
||||
v-model.trim="channelWebsiteUrl"
|
||||
class="medium-9 columns"
|
||||
:label="$t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.CHANNEL_DOMAIN.LABEL')"
|
||||
@@ -34,7 +43,7 @@
|
||||
"
|
||||
/>
|
||||
<woot-input
|
||||
v-if="isAWidgetInbox"
|
||||
v-if="isAWebWidgetInbox"
|
||||
v-model.trim="channelWelcomeTitle"
|
||||
class="medium-9 columns"
|
||||
:label="
|
||||
@@ -48,7 +57,7 @@
|
||||
/>
|
||||
|
||||
<woot-input
|
||||
v-if="isAWidgetInbox"
|
||||
v-if="isAWebWidgetInbox"
|
||||
v-model.trim="channelWelcomeTagline"
|
||||
class="medium-9 columns"
|
||||
:label="
|
||||
@@ -61,7 +70,7 @@
|
||||
"
|
||||
/>
|
||||
|
||||
<label v-if="isAWidgetInbox" class="medium-9 columns">
|
||||
<label v-if="isAWebWidgetInbox" class="medium-9 columns">
|
||||
{{ $t('INBOX_MGMT.ADD.WEBSITE_CHANNEL.WIDGET_COLOR.LABEL') }}
|
||||
<woot-color-picker v-model="inbox.widget_color" />
|
||||
</label>
|
||||
@@ -94,7 +103,6 @@
|
||||
}}
|
||||
</p>
|
||||
</label>
|
||||
|
||||
<woot-input
|
||||
v-if="greetingEnabled"
|
||||
v-model.trim="greetingMessage"
|
||||
@@ -122,6 +130,33 @@
|
||||
{{ $t('INBOX_MGMT.SETTINGS_POPUP.AUTO_ASSIGNMENT_SUB_TEXT') }}
|
||||
</p>
|
||||
</label>
|
||||
|
||||
<label v-if="isAWebWidgetInbox">
|
||||
{{ $t('INBOX_MGMT.FEATURES.LABEL') }}
|
||||
</label>
|
||||
<div v-if="isAWebWidgetInbox" class="widget--feature-flag">
|
||||
<input
|
||||
v-model="selectedFeatureFlags"
|
||||
type="checkbox"
|
||||
value="attachments"
|
||||
@input="handleFeatureFlag"
|
||||
/>
|
||||
<label for="attachments">
|
||||
{{ $t('INBOX_MGMT.FEATURES.DISPLAY_FILE_PICKER') }}
|
||||
</label>
|
||||
</div>
|
||||
<div v-if="isAWebWidgetInbox">
|
||||
<input
|
||||
v-model="selectedFeatureFlags"
|
||||
type="checkbox"
|
||||
value="emoji_picker"
|
||||
@input="handleFeatureFlag"
|
||||
/>
|
||||
<label for="emoji_picker">
|
||||
{{ $t('INBOX_MGMT.FEATURES.DISPLAY_EMOJI_PICKER') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<woot-submit-button
|
||||
:button-text="$t('INBOX_MGMT.SETTINGS_POPUP.UPDATE')"
|
||||
:loading="uiFlags.isUpdatingInbox"
|
||||
@@ -132,7 +167,7 @@
|
||||
|
||||
<!-- update agents in inbox -->
|
||||
|
||||
<div class="settings--content">
|
||||
<div v-if="selectedTabKey === 'collaborators'" class="settings--content">
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.SETTINGS_POPUP.INBOX_AGENTS')"
|
||||
:sub-title="$t('INBOX_MGMT.SETTINGS_POPUP.INBOX_AGENTS_SUB_TEXT')"
|
||||
@@ -141,7 +176,7 @@
|
||||
v-model="selectedAgents"
|
||||
:options="agentList"
|
||||
track-by="id"
|
||||
label="name"
|
||||
label="available_name"
|
||||
:multiple="true"
|
||||
:close-on-select="false"
|
||||
:clear-on-select="false"
|
||||
@@ -157,56 +192,43 @@
|
||||
/>
|
||||
</settings-section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="inbox.channel_type === 'Channel::TwilioSms'"
|
||||
class="settings--content"
|
||||
>
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.ADD.TWILIO.API_CALLBACK.TITLE')"
|
||||
:sub-title="$t('INBOX_MGMT.ADD.TWILIO.API_CALLBACK.SUBTITLE')"
|
||||
>
|
||||
<woot-code :script="twilioCallbackURL" lang="html"></woot-code>
|
||||
</settings-section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="inbox.channel_type === 'Channel::FacebookPage'"
|
||||
class="settings--content"
|
||||
>
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.SETTINGS_POPUP.MESSENGER_HEADING')"
|
||||
:sub-title="$t('INBOX_MGMT.SETTINGS_POPUP.MESSENGER_SUB_HEAD')"
|
||||
>
|
||||
<woot-code :script="messengerScript"></woot-code>
|
||||
</settings-section>
|
||||
</div>
|
||||
<div v-else-if="inbox.channel_type === 'Channel::WebWidget'">
|
||||
<div class="settings--content">
|
||||
<div v-if="selectedTabKey === 'configuration'">
|
||||
<div v-if="isATwilioChannel" class="settings--content">
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.SETTINGS_POPUP.MESSENGER_HEADING')"
|
||||
:sub-title="$t('INBOX_MGMT.SETTINGS_POPUP.MESSENGER_SUB_HEAD')"
|
||||
:title="$t('INBOX_MGMT.ADD.TWILIO.API_CALLBACK.TITLE')"
|
||||
:sub-title="$t('INBOX_MGMT.ADD.TWILIO.API_CALLBACK.SUBTITLE')"
|
||||
>
|
||||
<woot-code :script="inbox.web_widget_script"></woot-code>
|
||||
<woot-code :script="twilioCallbackURL" lang="html"></woot-code>
|
||||
</settings-section>
|
||||
</div>
|
||||
<div v-else-if="isAWebWidgetInbox">
|
||||
<div class="settings--content">
|
||||
<settings-section
|
||||
:title="$t('INBOX_MGMT.SETTINGS_POPUP.MESSENGER_HEADING')"
|
||||
:sub-title="$t('INBOX_MGMT.SETTINGS_POPUP.MESSENGER_SUB_HEAD')"
|
||||
>
|
||||
<woot-code :script="inbox.web_widget_script"></woot-code>
|
||||
</settings-section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint no-console: 0 */
|
||||
/* global bus */
|
||||
import { mapGetters } from 'vuex';
|
||||
import { createMessengerScript } from 'dashboard/helper/scriptGenerator';
|
||||
import configMixin from 'shared/mixins/configMixin';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import SettingsSection from '../../../../components/SettingsSection';
|
||||
import inboxMixin from 'shared/mixins/inboxMixin';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SettingsSection,
|
||||
},
|
||||
mixins: [configMixin],
|
||||
mixins: [alertMixin, configMixin, inboxMixin],
|
||||
data() {
|
||||
return {
|
||||
avatarFile: null,
|
||||
@@ -220,6 +242,7 @@ export default {
|
||||
channelWebsiteUrl: '',
|
||||
channelWelcomeTitle: '',
|
||||
channelWelcomeTagline: '',
|
||||
selectedFeatureFlags: [],
|
||||
autoAssignmentOptions: [
|
||||
{
|
||||
value: true,
|
||||
@@ -230,6 +253,7 @@ export default {
|
||||
label: this.$t('INBOX_MGMT.EDIT.AUTO_ASSIGNMENT.DISABLED'),
|
||||
},
|
||||
],
|
||||
selectedTabIndex: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -237,17 +261,41 @@ export default {
|
||||
agentList: 'agents/getAgents',
|
||||
uiFlags: 'inboxes/getUIFlags',
|
||||
}),
|
||||
selectedTabKey() {
|
||||
return this.tabs[this.selectedTabIndex]?.key;
|
||||
},
|
||||
tabs() {
|
||||
const visibleToAllChannelTabs = [
|
||||
{
|
||||
key: 'inbox_settings',
|
||||
name: this.$t('INBOX_MGMT.TABS.SETTINGS'),
|
||||
},
|
||||
{
|
||||
key: 'collaborators',
|
||||
name: this.$t('INBOX_MGMT.TABS.COLLABORATORS'),
|
||||
},
|
||||
];
|
||||
|
||||
if (this.isAWebWidgetInbox || this.isATwilioChannel) {
|
||||
return [
|
||||
...visibleToAllChannelTabs,
|
||||
{
|
||||
key: 'configuration',
|
||||
name: this.$t('INBOX_MGMT.TABS.CONFIGURATION'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return visibleToAllChannelTabs;
|
||||
},
|
||||
currentInboxId() {
|
||||
return this.$route.params.inboxId;
|
||||
},
|
||||
inbox() {
|
||||
return this.$store.getters['inboxes/getInbox'](this.currentInboxId);
|
||||
},
|
||||
isAWidgetInbox() {
|
||||
return this.inbox.channel_type === 'Channel::WebWidget';
|
||||
},
|
||||
inboxName() {
|
||||
if (this.inbox.channel_type === 'Channel::TwilioSms') {
|
||||
if (this.isATwilioSMSChannel || this.isATwilioWhatsappChannel) {
|
||||
return `${this.inbox.name} (${this.inbox.phone_number})`;
|
||||
}
|
||||
return this.inbox.name;
|
||||
@@ -267,10 +315,25 @@ export default {
|
||||
this.fetchInboxSettings();
|
||||
},
|
||||
methods: {
|
||||
showAlert(message) {
|
||||
bus.$emit('newToastMessage', message);
|
||||
handleFeatureFlag(e) {
|
||||
console.log(e.target.value);
|
||||
this.selectedFeatureFlags = this.toggleInput(
|
||||
this.selectedFeatureFlags,
|
||||
e.target.value
|
||||
);
|
||||
},
|
||||
toggleInput(selected, current) {
|
||||
if (selected.includes(current)) {
|
||||
const newSelectedFlags = selected.filter(flag => flag !== current);
|
||||
return newSelectedFlags;
|
||||
}
|
||||
return [...selected, current];
|
||||
},
|
||||
onTabChange(selectedTabIndex) {
|
||||
this.selectedTabIndex = selectedTabIndex;
|
||||
},
|
||||
fetchInboxSettings() {
|
||||
this.selectedTabIndex = 0;
|
||||
this.selectedAgents = [];
|
||||
this.$store.dispatch('agents/get');
|
||||
this.$store.dispatch('inboxes/get').then(() => {
|
||||
@@ -283,6 +346,7 @@ export default {
|
||||
this.channelWebsiteUrl = this.inbox.website_url;
|
||||
this.channelWelcomeTitle = this.inbox.welcome_title;
|
||||
this.channelWelcomeTagline = this.inbox.welcome_tagline;
|
||||
this.selectedFeatureFlags = this.inbox.selected_feature_flags || [];
|
||||
});
|
||||
},
|
||||
async fetchAttachedAgents() {
|
||||
@@ -325,6 +389,7 @@ export default {
|
||||
website_url: this.channelWebsiteUrl,
|
||||
welcome_title: this.channelWelcomeTitle || '',
|
||||
welcome_tagline: this.channelWelcomeTagline || '',
|
||||
selectedFeatureFlags: this.selectedFeatureFlags,
|
||||
},
|
||||
};
|
||||
if (this.avatarFile) {
|
||||
@@ -370,7 +435,16 @@ export default {
|
||||
.page-top-bar {
|
||||
@include background-light;
|
||||
@include border-normal-bottom;
|
||||
padding: $space-normal $space-larger;
|
||||
padding: $space-normal $space-large 0;
|
||||
|
||||
.tabs {
|
||||
padding: 0;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.widget--feature-flag {
|
||||
padding-top: var(--space-small);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,7 +11,15 @@ const buildInboxData = inboxParams => {
|
||||
Object.keys(inboxProperties).forEach(key => {
|
||||
formData.append(key, inboxProperties[key]);
|
||||
});
|
||||
Object.keys(channel).forEach(key => {
|
||||
const { selectedFeatureFlags = [], ...channelParams } = channel;
|
||||
if (selectedFeatureFlags.length) {
|
||||
selectedFeatureFlags.forEach(featureFlag => {
|
||||
formData.append(`channel[selected_feature_flags][]`, featureFlag);
|
||||
});
|
||||
} else {
|
||||
formData.append('channel[selected_feature_flags][]', '');
|
||||
}
|
||||
Object.keys(channelParams).forEach(key => {
|
||||
formData.append(`channel[${key}]`, channel[key]);
|
||||
});
|
||||
return formData;
|
||||
|
||||
42
app/javascript/shared/mixins/inboxMixin.js
Normal file
42
app/javascript/shared/mixins/inboxMixin.js
Normal file
@@ -0,0 +1,42 @@
|
||||
export const INBOX_TYPES = {
|
||||
WEB: 'Channel::WebWidget',
|
||||
FB: 'Channel::FacebookPage',
|
||||
TWITTER: 'Channel::TwitterProfile',
|
||||
TWILIO: 'Channel::TwilioSms',
|
||||
API: 'Channel::Api',
|
||||
EMAIL: 'Channel::Email',
|
||||
};
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
channelType() {
|
||||
return this.inbox.channel_type;
|
||||
},
|
||||
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;
|
||||
},
|
||||
isAnEmailChannel() {
|
||||
return this.channelType === INBOX_TYPES.EMAIL;
|
||||
},
|
||||
isATwilioSMSChannel() {
|
||||
const { phone_number: phoneNumber = '' } = this.inbox;
|
||||
return this.isATwilioChannel && !phoneNumber.startsWith('whatsapp');
|
||||
},
|
||||
isATwilioWhatsappChannel() {
|
||||
const { phone_number: phoneNumber = '' } = this.inbox;
|
||||
return this.isATwilioChannel && phoneNumber.startsWith('whatsapp');
|
||||
},
|
||||
},
|
||||
};
|
||||
114
app/javascript/shared/mixins/specs/inboxMixin.spec.js
Normal file
114
app/javascript/shared/mixins/specs/inboxMixin.spec.js
Normal file
@@ -0,0 +1,114 @@
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import inboxMixin from '../inboxMixin';
|
||||
|
||||
describe('inboxMixin', () => {
|
||||
it('returns the correct channel type', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return { inbox: { channel_type: 'Channel::WebWidget' } };
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.channelType).toBe('Channel::WebWidget');
|
||||
});
|
||||
|
||||
it('isAPIInbox returns true if channel type is API', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return { inbox: { channel_type: 'Channel::Api' } };
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isAPIInbox).toBe(true);
|
||||
});
|
||||
|
||||
it('isATwitterInbox returns true if channel type is twitter', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return { inbox: { channel_type: 'Channel::TwitterProfile' } };
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isATwitterInbox).toBe(true);
|
||||
});
|
||||
|
||||
it('isAFacebookInbox returns true if channel type is Facebook', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return { inbox: { channel_type: 'Channel::FacebookPage' } };
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isAFacebookInbox).toBe(true);
|
||||
});
|
||||
|
||||
it('isAWebWidgetInbox returns true if channel type is Facebook', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return { inbox: { channel_type: 'Channel::WebWidget' } };
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isAWebWidgetInbox).toBe(true);
|
||||
});
|
||||
|
||||
it('isATwilioChannel returns true if channel type is Twilio', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return {
|
||||
inbox: {
|
||||
channel_type: 'Channel::TwilioSms',
|
||||
phone_number: '+91944444444',
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isATwilioChannel).toBe(true);
|
||||
expect(wrapper.vm.isATwilioSMSChannel).toBe(true);
|
||||
});
|
||||
|
||||
it('isATwilioWhatsappChannel returns true if channel type is Twilio and phonenumber is a whatsapp number', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return {
|
||||
inbox: {
|
||||
channel_type: 'Channel::TwilioSms',
|
||||
phone_number: 'whatsapp:+91944444444',
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isATwilioChannel).toBe(true);
|
||||
expect(wrapper.vm.isATwilioWhatsappChannel).toBe(true);
|
||||
});
|
||||
|
||||
it('isAnEmailChannel returns true if channel type is email', () => {
|
||||
const Component = {
|
||||
render() {},
|
||||
mixins: [inboxMixin],
|
||||
data() {
|
||||
return {
|
||||
inbox: { channel_type: 'Channel::Email' },
|
||||
};
|
||||
},
|
||||
};
|
||||
const wrapper = shallowMount(Component);
|
||||
expect(wrapper.vm.isAnEmailChannel).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -18,6 +18,7 @@
|
||||
:on-click="emojiOnClick"
|
||||
/>
|
||||
<i
|
||||
v-if="hasEmojiPickerEnabled"
|
||||
class="emoji-toggle icon ion-happy-outline"
|
||||
:class="{ active: showEmojiPicker }"
|
||||
@click="toggleEmojiPicker()"
|
||||
@@ -39,6 +40,7 @@ import ChatSendButton from 'widget/components/ChatSendButton.vue';
|
||||
import ChatAttachmentButton from 'widget/components/ChatAttachment.vue';
|
||||
import ResizableTextArea from 'shared/components/ResizableTextArea';
|
||||
import EmojiInput from 'dashboard/components/widgets/emoji/EmojiInput';
|
||||
import configMixin from '../mixins/configMixin';
|
||||
|
||||
export default {
|
||||
name: 'ChatInputWrap',
|
||||
@@ -48,7 +50,7 @@ export default {
|
||||
EmojiInput,
|
||||
ResizableTextArea,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
mixins: [clickaway, configMixin],
|
||||
props: {
|
||||
onSendMessage: {
|
||||
type: Function,
|
||||
@@ -72,7 +74,7 @@ export default {
|
||||
widgetColor: 'appConfig/getWidgetColor',
|
||||
}),
|
||||
showAttachment() {
|
||||
return this.userInput.length === 0;
|
||||
return this.hasAttachmentsEnabled && this.userInput.length === 0;
|
||||
},
|
||||
showSendButton() {
|
||||
return this.userInput.length > 0;
|
||||
|
||||
@@ -15,5 +15,11 @@ export default {
|
||||
channelConfig() {
|
||||
return window.chatwootWebChannel;
|
||||
},
|
||||
hasEmojiPickerEnabled() {
|
||||
return this.channelConfig.enabledFeatures.includes('emoji_picker');
|
||||
},
|
||||
hasAttachmentsEnabled() {
|
||||
return this.channelConfig.enabledFeatures.includes('attachments');
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ global.chatwootWebChannel = {
|
||||
hideInputForBotConversations: true,
|
||||
avatarUrl: 'https://test.url',
|
||||
hasAConnectedAgentBot: 'AgentBot',
|
||||
enabledFeatures: ['emoji_picker', 'attachments'],
|
||||
};
|
||||
|
||||
global.chatwootWidgetDefaults = {
|
||||
@@ -22,6 +23,8 @@ describe('configMixin', () => {
|
||||
const Constructor = Vue.extend(Component);
|
||||
const vm = new Constructor().$mount();
|
||||
const wrapper = createWrapper(vm);
|
||||
expect(wrapper.vm.hasEmojiPickerEnabled).toBe(true);
|
||||
expect(wrapper.vm.hasAttachmentsEnabled).toBe(true);
|
||||
expect(wrapper.vm.hideInputForBotConversations).toBe(true);
|
||||
expect(wrapper.vm.hasAConnectedAgentBot).toBe(true);
|
||||
expect(wrapper.vm.useInboxAvatarForBot).toBe(true);
|
||||
@@ -30,6 +33,7 @@ describe('configMixin', () => {
|
||||
hideInputForBotConversations: true,
|
||||
avatarUrl: 'https://test.url',
|
||||
hasAConnectedAgentBot: 'AgentBot',
|
||||
enabledFeatures: ['emoji_picker', 'attachments'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user