diff --git a/app/javascript/dashboard/components/ui/Switch.vue b/app/javascript/dashboard/components/ui/Switch.vue index b0bc32881..7dc4bcbfb 100644 --- a/app/javascript/dashboard/components/ui/Switch.vue +++ b/app/javascript/dashboard/components/ui/Switch.vue @@ -17,8 +17,12 @@ export default { value: { type: Boolean, default: false }, }, methods: { - onClick() { - this.$emit('input', !this.value); + onClick(event) { + if (event.pointerId === -1) { + event.preventDefault(); + } else { + this.$emit('input', !this.value); + } }, }, }; diff --git a/app/javascript/dashboard/helper/preChat.js b/app/javascript/dashboard/helper/preChat.js new file mode 100644 index 000000000..bc5502e5b --- /dev/null +++ b/app/javascript/dashboard/helper/preChat.js @@ -0,0 +1,100 @@ +import i18n from 'widget/i18n/index'; +const defaultTranslations = Object.fromEntries( + Object.entries(i18n).filter(([key]) => key.includes('en')) +).en; + +export const standardFieldKeys = { + emailAddress: { + key: 'EMAIL_ADDRESS', + label: 'Email Id', + placeholder: 'Please enter your email address', + }, + fullName: { + key: 'FULL_NAME', + label: 'Full Name', + placeholder: 'Please enter your full name', + }, + phoneNumber: { + key: 'PHONE_NUMBER', + label: 'Phone Number', + placeholder: 'Please enter your phone number', + }, +}; + +export const getLabel = ({ key, label }) => { + return defaultTranslations.PRE_CHAT_FORM.FIELDS[key] + ? defaultTranslations.PRE_CHAT_FORM.FIELDS[key].LABEL + : label; +}; +export const getPlaceHolder = ({ key, placeholder }) => { + return defaultTranslations.PRE_CHAT_FORM.FIELDS[key] + ? defaultTranslations.PRE_CHAT_FORM.FIELDS[key].PLACEHOLDER + : placeholder; +}; + +export const getCustomFields = ({ standardFields, customAttributes }) => { + let customFields = []; + const { pre_chat_fields: preChatFields } = standardFields; + customAttributes.forEach(attribute => { + const itemExist = preChatFields.find( + item => item.name === attribute.attribute_key + ); + if (!itemExist) { + customFields.push({ + label: attribute.attribute_display_name, + placeholder: attribute.attribute_display_name, + name: attribute.attribute_key, + type: attribute.attribute_display_type, + values: attribute.attribute_values, + field_type: attribute.attribute_model, + required: false, + enabled: false, + }); + } + }); + return customFields; +}; + +export const getFormattedPreChatFields = ({ preChatFields }) => { + return preChatFields.map(item => { + return { + ...item, + label: getLabel({ + key: standardFieldKeys[item.name] + ? standardFieldKeys[item.name].key + : item.name, + label: item.label ? item.label : item.name, + }), + placeholder: getPlaceHolder({ + key: standardFieldKeys[item.name] + ? standardFieldKeys[item.name].key + : item.name, + placeholder: item.placeholder ? item.placeholder : item.name, + }), + }; + }); +}; + +export const getPreChatFields = ({ + preChatFormOptions = {}, + customAttributes = [], +}) => { + const { pre_chat_message, pre_chat_fields } = preChatFormOptions; + let customFields = {}; + let preChatFields = {}; + + const formattedPreChatFields = getFormattedPreChatFields({ + preChatFields: pre_chat_fields, + }); + + customFields = getCustomFields({ + standardFields: { pre_chat_fields: formattedPreChatFields }, + customAttributes, + }); + preChatFields = [...formattedPreChatFields, ...customFields]; + + return { + pre_chat_message, + pre_chat_fields: preChatFields, + }; +}; diff --git a/app/javascript/dashboard/helper/specs/inboxFixture.js b/app/javascript/dashboard/helper/specs/inboxFixture.js new file mode 100644 index 000000000..6622a6de2 --- /dev/null +++ b/app/javascript/dashboard/helper/specs/inboxFixture.js @@ -0,0 +1,47 @@ +export default { + customFields: { + pre_chat_message: 'Share your queries or comments here.', + pre_chat_fields: [ + { + label: 'Email Address', + name: 'emailAddress', + type: 'email', + field_type: 'standard', + required: false, + enabled: false, + + placeholder: 'Please enter your email address', + }, + { + label: 'Full Name', + name: 'fullName', + type: 'text', + field_type: 'standard', + required: false, + enabled: false, + placeholder: 'Please enter your full name', + }, + { + label: 'Phone Number', + name: 'phoneNumber', + type: 'text', + field_type: 'standard', + required: false, + enabled: false, + placeholder: 'Please enter your phone number', + }, + ], + }, + customAttributes: [ + { + id: 101, + attribute_description: 'Order Identifier', + attribute_display_name: 'Order Id', + attribute_display_type: 'number', + attribute_key: 'order_id', + attribute_model: 'conversation_attribute', + attribute_values: Array(0), + created_at: '2021-11-29T10:20:04.563Z', + }, + ], +}; diff --git a/app/javascript/dashboard/helper/specs/preChat.spec.js b/app/javascript/dashboard/helper/specs/preChat.spec.js new file mode 100644 index 000000000..74f3e72f5 --- /dev/null +++ b/app/javascript/dashboard/helper/specs/preChat.spec.js @@ -0,0 +1,76 @@ +import { + getPreChatFields, + getFormattedPreChatFields, + getCustomFields, +} from '../preChat'; +import inboxFixture from './inboxFixture'; + +const { customFields, customAttributes } = inboxFixture; +describe('#Pre chat Helpers', () => { + describe('getPreChatFields', () => { + it('should return correct pre-chat fields form options passed', () => { + expect(getPreChatFields({ preChatFormOptions: customFields })).toEqual( + customFields + ); + }); + }); + describe('getFormattedPreChatFields', () => { + it('should return correct custom fields', () => { + expect( + getFormattedPreChatFields({ + preChatFields: customFields.pre_chat_fields, + }) + ).toEqual([ + { + label: 'Email Address', + name: 'emailAddress', + placeholder: 'Please enter your email address', + type: 'email', + field_type: 'standard', + + required: false, + enabled: false, + }, + { + label: 'Full Name', + name: 'fullName', + placeholder: 'Please enter your full name', + type: 'text', + field_type: 'standard', + required: false, + enabled: false, + }, + { + label: 'Phone Number', + name: 'phoneNumber', + placeholder: 'Please enter your phone number', + type: 'text', + field_type: 'standard', + required: false, + enabled: false, + }, + ]); + }); + }); + describe('getCustomFields', () => { + it('should return correct custom fields', () => { + expect( + getCustomFields({ + standardFields: { pre_chat_fields: customFields.pre_chat_fields }, + customAttributes, + }) + ).toEqual([ + { + enabled: false, + label: 'Order Id', + placeholder: 'Order Id', + name: 'order_id', + required: false, + field_type: 'conversation_attribute', + type: 'number', + values: [], + }, + ]); + }); + }); +}); diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json index 365fd92f9..218d1cf95 100644 --- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json +++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json @@ -187,7 +187,7 @@ } } }, - "WHATSAPP": { + "WHATSAPP": { "TITLE": "WhatsApp Channel", "DESC": "Start supporting your customers via WhatsApp.", "PROVIDERS": { @@ -211,7 +211,6 @@ "PLACEHOLDER": "API key", "APPLY_FOR_ACCESS": "Don't have any API key? Apply for access here", "ERROR": "Please enter a valid value." - }, "SUBMIT_BUTTON": "Create WhatsApp Channel", "API": { @@ -433,6 +432,15 @@ }, "PRE_CHAT_FORM": { "DESCRIPTION": "Pre chat forms enable you to capture user information before they start conversation with you.", + "SET_FIELDS": "Pre chat form fields", + "SET_FIELDS_HEADER": { + "FIELDS": "Fields", + "LABEL": "Label", + "PLACE_HOLDER":"Placeholder", + "KEY": "Key", + "TYPE": "Type", + "REQUIRED": "Required" + }, "ENABLE": { "LABEL": "Enable pre chat form", "OPTIONS": { @@ -441,7 +449,7 @@ } }, "PRE_CHAT_MESSAGE": { - "LABEL": "Pre Chat Message", + "LABEL": "Pre chat message", "PLACEHOLDER": "This message would be visible to the users along with the form" }, "REQUIRE_EMAIL": { @@ -465,7 +473,7 @@ "VALIDATION_ERROR": "Starting time should be before closing time.", "CHOOSE": "Choose" }, - "ALL_DAY":"All-Day" + "ALL_DAY": "All-Day" }, "IMAP": { "TITLE": "IMAP", diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/PreChatFields.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/PreChatFields.vue new file mode 100644 index 000000000..9d2691036 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/PreChatFields.vue @@ -0,0 +1,91 @@ + + + + + + + + + {{ item.name }} + + + {{ item.type }} + + + + + + + + + + + + + + + + diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/Settings.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/Settings.vue index 6c01bc3dd..184e16e0f 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/Settings.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/PreChatForm/Settings.vue @@ -1,10 +1,10 @@ - + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.DESCRIPTION') }} - - + + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.ENABLE.LABEL') }} @@ -15,28 +15,55 @@ - - - {{ $t('INBOX_MGMT.PRE_CHAT_FORM.PRE_CHAT_MESSAGE.LABEL') }} - - - - - - {{ $t('INBOX_MGMT.PRE_CHAT_FORM.REQUIRE_EMAIL.LABEL') }} + + + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.PRE_CHAT_MESSAGE.LABEL') }} + + + + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.SET_FIELDS') }} + + + + + + + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.SET_FIELDS_HEADER.KEY') }} + + + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.SET_FIELDS_HEADER.TYPE') }} + + + {{ + $t('INBOX_MGMT.PRE_CHAT_FORM.SET_FIELDS_HEADER.REQUIRED') + }} + + + {{ $t('INBOX_MGMT.PRE_CHAT_FORM.SET_FIELDS_HEADER.LABEL') }} + + + {{ + $t( + 'INBOX_MGMT.PRE_CHAT_FORM.SET_FIELDS_HEADER.PLACE_HOLDER' + ) + }} + + + + + + import { mapGetters } from 'vuex'; import alertMixin from 'shared/mixins/alertMixin'; +import PreChatFields from './PreChatFields.vue'; +import { getPreChatFields, standardFieldKeys } from 'dashboard/helper/preChat'; export default { + components: { + PreChatFields, + }, mixins: [alertMixin], props: { inbox: { @@ -60,11 +92,21 @@ export default { return { preChatFormEnabled: false, preChatMessage: '', - preChatFieldOptions: [], + preChatFields: [], }; }, computed: { - ...mapGetters({ uiFlags: 'inboxes/getUIFlags' }), + ...mapGetters({ + uiFlags: 'inboxes/getUIFlags', + customAttributes: 'attributes/getAttributes', + }), + preChatFieldOptions() { + const { pre_chat_form_options: preChatFormOptions } = this.inbox; + return getPreChatFields({ + preChatFormOptions, + customAttributes: this.customAttributes, + }); + }, }, watch: { inbox() { @@ -76,25 +118,26 @@ export default { }, methods: { setDefaults() { - const { - pre_chat_form_enabled: preChatFormEnabled, - pre_chat_form_options: preChatFormOptions, - } = this.inbox; + const { pre_chat_form_enabled: preChatFormEnabled } = this.inbox; this.preChatFormEnabled = preChatFormEnabled; - const { pre_chat_message: preChatMessage, require_email: requireEmail } = - preChatFormOptions || {}; + const { + pre_chat_message: preChatMessage, + pre_chat_fields: preChatFields, + } = this.preChatFieldOptions || {}; this.preChatMessage = preChatMessage; - if (requireEmail) { - this.preChatFieldOptions = ['requireEmail']; - } + this.preChatFields = preChatFields; }, - handlePreChatFieldOptions(event) { - if (this.preChatFieldOptions.includes(event.target.value)) { - this.preChatFieldOptions = []; - } else { - this.preChatFieldOptions = [event.target.value]; - } + isFieldEditable(item) { + return !!standardFieldKeys[item.name] || !item.enabled; }, + handlePreChatFieldOptions(event, type, item) { + this.preChatFields.forEach((field, index) => { + if (field.name === item.name) { + this.preChatFields[index][type] = !item[type]; + } + }); + }, + async updateInbox() { try { const payload = { @@ -104,7 +147,7 @@ export default { pre_chat_form_enabled: this.preChatFormEnabled, pre_chat_form_options: { pre_chat_message: this.preChatMessage, - require_email: this.preChatFieldOptions.includes('requireEmail'), + pre_chat_fields: this.preChatFields, }, }, }; @@ -117,12 +160,11 @@ export default { }, }; - diff --git a/app/javascript/dashboard/store/modules/attributes.js b/app/javascript/dashboard/store/modules/attributes.js index 40cfc99d7..af6d3ce4f 100644 --- a/app/javascript/dashboard/store/modules/attributes.js +++ b/app/javascript/dashboard/store/modules/attributes.js @@ -16,6 +16,9 @@ export const getters = { getUIFlags(_state) { return _state.uiFlags; }, + getAttributes: _state => { + return _state.records; + }, getAttributesByModel: _state => attributeModel => { return _state.records.filter( record => record.attribute_model === attributeModel diff --git a/app/javascript/dashboard/store/modules/specs/attributes/getters.spec.js b/app/javascript/dashboard/store/modules/specs/attributes/getters.spec.js index 0e29eb514..9d8f027f5 100644 --- a/app/javascript/dashboard/store/modules/specs/attributes/getters.spec.js +++ b/app/javascript/dashboard/store/modules/specs/attributes/getters.spec.js @@ -2,6 +2,26 @@ import { getters } from '../../attributes'; import attributesList from './fixtures'; describe('#getters', () => { + it('getAttributes', () => { + const state = { records: attributesList }; + expect(getters.getAttributes(state)).toEqual([ + { + attribute_display_name: 'Language', + attribute_display_type: 1, + attribute_description: 'The conversation language', + attribute_key: 'language', + attribute_model: 0, + }, + { + attribute_display_name: 'Language one', + attribute_display_type: 2, + attribute_description: 'The conversation language one', + attribute_key: 'language_one', + attribute_model: 1, + }, + ]); + }); + it('getAttributesByModel', () => { const state = { records: attributesList }; expect(getters.getAttributesByModel(state)(1)).toEqual([ diff --git a/app/javascript/packs/widget.js b/app/javascript/packs/widget.js index 421e2f8b9..850645581 100644 --- a/app/javascript/packs/widget.js +++ b/app/javascript/packs/widget.js @@ -1,11 +1,12 @@ import Vue from 'vue'; import Vuelidate from 'vuelidate'; import VueI18n from 'vue-i18n'; +import VueFormulate from '@braid/vue-formulate'; import store from '../widget/store'; import App from '../widget/App.vue'; import ActionCableConnector from '../widget/helpers/actionCable'; import i18n from '../widget/i18n'; - +import { isPhoneE164OrEmpty } from 'shared/helpers/Validators'; import router from '../widget/router'; Vue.use(VueI18n); Vue.use(Vuelidate); @@ -14,7 +15,15 @@ const i18nConfig = new VueI18n({ locale: 'en', messages: i18n, }); - +Vue.use(VueFormulate, { + rules: { + isPhoneE164OrEmpty: ({ value }) => isPhoneE164OrEmpty(value), + }, + classes: { + outer: 'mb-4 wrapper', + error: 'text-red-400 mt-2 text-xs font-medium', + }, +}); // Event Bus window.bus = new Vue(); diff --git a/app/javascript/shared/components/FluentIcon/dashboard-icons.json b/app/javascript/shared/components/FluentIcon/dashboard-icons.json index 0cbc85d22..9f19f8a9d 100644 --- a/app/javascript/shared/components/FluentIcon/dashboard-icons.json +++ b/app/javascript/shared/components/FluentIcon/dashboard-icons.json @@ -126,5 +126,6 @@ "brand-whatsapp-outline": "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z", "brand-github-outline": "M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385c.6.105.825-.255.825-.57c0-.285-.015-1.23-.015-2.235c-3.015.555-3.795-.735-4.035-1.41c-.135-.345-.72-1.41-1.23-1.695c-.42-.225-1.02-.78-.015-.795c.945-.015 1.62.87 1.845 1.23c1.08 1.815 2.805 1.305 3.495.99c.105-.78.42-1.305.765-1.605c-2.67-.3-5.46-1.335-5.46-5.925c0-1.305.465-2.385 1.23-3.225c-.12-.3-.54-1.53.12-3.18c0 0 1.005-.315 3.3 1.23c.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23c.66 1.65.24 2.88.12 3.18c.765.84 1.23 1.905 1.23 3.225c0 4.605-2.805 5.625-5.475 5.925c.435.375.81 1.095.81 2.22c0 1.605-.015 2.895-.015 3.3c0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12Z", "add-solid": "M11.883 3.007 12 3a1 1 0 0 1 .993.883L13 4v7h7a1 1 0 0 1 .993.883L21 12a1 1 0 0 1-.883.993L20 13h-7v7a1 1 0 0 1-.883.993L12 21a1 1 0 0 1-.993-.883L11 20v-7H4a1 1 0 0 1-.993-.883L3 12a1 1 0 0 1 .883-.993L4 11h7V4a1 1 0 0 1 .883-.993L12 3l-.117.007Z", - "subtract-solid": "M3.997 13H20a1 1 0 1 0 0-2H3.997a1 1 0 1 0 0 2Z" + "subtract-solid": "M3.997 13H20a1 1 0 1 0 0-2H3.997a1 1 0 1 0 0 2Z", + "drag-outline": "M15 3.707V8.5a.5.5 0 0 0 1 0V3.707l1.146 1.147a.5.5 0 0 0 .708-.708l-2-2a.499.499 0 0 0-.708 0l-2 2a.5.5 0 0 0 .708.708L15 3.707ZM2 4.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5Zm0 5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5Zm.5 4.5a.5.5 0 0 0 0 1h6a.5.5 0 0 0 0-1h-6ZM15 16.293V11.5a.5.5 0 0 1 1 0v4.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L15 16.293Z" } diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue index 9d6600264..ec30064a7 100755 --- a/app/javascript/widget/App.vue +++ b/app/javascript/widget/App.vue @@ -151,10 +151,7 @@ export default { }, registerCampaignEvents() { bus.$on(ON_CAMPAIGN_MESSAGE_CLICK, () => { - const showPreChatForm = - this.preChatFormEnabled && this.preChatFormOptions.requireEmail; - const isUserEmailAvailable = !!this.currentUser.email; - if (showPreChatForm && !isUserEmailAvailable) { + if (this.shouldShowPreChatForm) { this.replaceRoute('prechat-form'); } else { this.replaceRoute('messages'); diff --git a/app/javascript/widget/components/PreChat/Form.vue b/app/javascript/widget/components/PreChat/Form.vue index 793c59ecb..823440cc1 100644 --- a/app/javascript/widget/components/PreChat/Form.vue +++ b/app/javascript/widget/components/PreChat/Form.vue @@ -1,47 +1,44 @@ - {{ headerMessage }} - - - + {{ $t('START_CONVERSATION') }} - + + diff --git a/app/javascript/widget/i18n/locale/en.json b/app/javascript/widget/i18n/locale/en.json index 66bf83fe5..ef4149191 100644 --- a/app/javascript/widget/i18n/locale/en.json +++ b/app/javascript/widget/i18n/locale/en.json @@ -44,12 +44,19 @@ "FULL_NAME": { "LABEL": "Full Name", "PLACEHOLDER": "Please enter your full name", - "ERROR": "Full Name is required" + "REQUIRED_ERROR": "Full Name is required" }, "EMAIL_ADDRESS": { "LABEL": "Email Address", "PLACEHOLDER": "Please enter your email address", - "ERROR": "Invalid email address" + "REQUIRED_ERROR": "Email Address is required", + "VALID_ERROR": "Please enter a valid email address" + }, + "PHONE_NUMBER": { + "LABEL": "Phone Number", + "PLACEHOLDER": "Please enter your phone number", + "REQUIRED_ERROR": "Phone Number is required", + "VALID_ERROR": "Phone number should be of E.164 format eg: +1415555555" }, "MESSAGE": { "LABEL": "Message", @@ -57,7 +64,8 @@ "ERROR": "Message too short" } }, - "CAMPAIGN_HEADER": "Please provide your name and email before starting the conversation" + "CAMPAIGN_HEADER": "Please provide your name and email before starting the conversation", + "IS_REQUIRED": "is required" }, "FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_FILE_UPLOAD_SIZE} attachment limit", "CHAT_FORM": { diff --git a/app/javascript/widget/mixins/configMixin.js b/app/javascript/widget/mixins/configMixin.js index 9cb09f062..70c2ac258 100644 --- a/app/javascript/widget/mixins/configMixin.js +++ b/app/javascript/widget/mixins/configMixin.js @@ -25,15 +25,21 @@ export default { return window.chatwootWebChannel.preChatFormEnabled; }, preChatFormOptions() { - let requireEmail = false; let preChatMessage = ''; const options = window.chatwootWebChannel.preChatFormOptions || {}; - requireEmail = options.require_email; preChatMessage = options.pre_chat_message; + const { pre_chat_fields: preChatFields = [] } = options; return { - requireEmail, preChatMessage, + preChatFields, }; }, + shouldShowPreChatForm() { + const { preChatFields } = this.preChatFormOptions; + // Check if at least one enabled field in pre-chat fields + const hasEnabledFields = + preChatFields.filter(field => field.enabled).length > 0; + return this.preChatFormEnabled && hasEnabledFields; + }, }, }; diff --git a/app/javascript/widget/mixins/specs/configMixin.spec.js b/app/javascript/widget/mixins/specs/configMixin.spec.js index 975001249..c81e5bab3 100644 --- a/app/javascript/widget/mixins/specs/configMixin.spec.js +++ b/app/javascript/widget/mixins/specs/configMixin.spec.js @@ -1,12 +1,30 @@ import { createWrapper } from '@vue/test-utils'; import configMixin from '../configMixin'; import Vue from 'vue'; - +const preChatFields = [ + { + label: 'Email Id', + name: 'emailAddress', + type: 'email', + field_type: 'standard', + required: false, + enabled: false, + }, + { + label: 'Full name', + name: 'fullName', + type: 'text', + field_type: 'standard', + required: true, + enabled: true, + }, +]; global.chatwootWebChannel = { avatarUrl: 'https://test.url', hasAConnectedAgentBot: 'AgentBot', enabledFeatures: ['emoji_picker', 'attachments', 'end_conversation'], - preChatFormOptions: { require_email: false, pre_chat_message: '' }, + preChatFormOptions: { pre_chat_fields: preChatFields, pre_chat_message: '' }, + preChatFormEnabled: true, }; global.chatwootWidgetDefaults = { @@ -29,18 +47,22 @@ describe('configMixin', () => { expect(wrapper.vm.hasAConnectedAgentBot).toBe(true); expect(wrapper.vm.useInboxAvatarForBot).toBe(true); expect(wrapper.vm.inboxAvatarUrl).toBe('https://test.url'); + expect(wrapper.vm.channelConfig).toEqual({ avatarUrl: 'https://test.url', hasAConnectedAgentBot: 'AgentBot', enabledFeatures: ['emoji_picker', 'attachments', 'end_conversation'], preChatFormOptions: { pre_chat_message: '', - require_email: false, + pre_chat_fields: preChatFields, }, + preChatFormEnabled: true, }); expect(wrapper.vm.preChatFormOptions).toEqual({ - requireEmail: false, preChatMessage: '', + preChatFields: preChatFields, }); + expect(wrapper.vm.preChatFormEnabled).toEqual(true); + expect(wrapper.vm.shouldShowPreChatForm).toEqual(true); }); }); diff --git a/app/javascript/widget/views/Home.vue b/app/javascript/widget/views/Home.vue index 0fbfa094f..10109b318 100755 --- a/app/javascript/widget/views/Home.vue +++ b/app/javascript/widget/views/Home.vue @@ -1,7 +1,7 @@ - +