diff --git a/app/javascript/widget/App.vue b/app/javascript/widget/App.vue
index ef9d63aac..bda48e2ec 100755
--- a/app/javascript/widget/App.vue
+++ b/app/javascript/widget/App.vue
@@ -8,6 +8,7 @@
:is-left-aligned="isLeftAligned"
:hide-message-bubble="hideMessageBubble"
:show-popout-button="showPopoutButton"
+ :is-campaign-view-clicked="isCampaignViewClicked"
/>
@@ -15,18 +16,19 @@
import { mapGetters, mapActions, mapMutations } from 'vuex';
import { setHeader } from 'widget/helpers/axios';
import { IFrameHelper, RNHelper } from 'widget/helpers/utils';
+import configMixin from './mixins/configMixin';
+import availabilityMixin from 'widget/mixins/availability';
import Router from './views/Router';
import { getLocale } from './helpers/urlParamsHelper';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import { isEmptyObject } from 'widget/helpers/utils';
-import availabilityMixin from 'widget/mixins/availability';
export default {
name: 'App',
components: {
Router,
},
- mixins: [availabilityMixin],
+ mixins: [availabilityMixin, configMixin],
data() {
return {
showUnreadView: false,
@@ -36,6 +38,7 @@ export default {
widgetPosition: 'right',
showPopoutButton: false,
isWebWidgetTriggered: false,
+ isCampaignViewClicked: false,
isWidgetOpen: false,
};
},
@@ -98,7 +101,11 @@ export default {
methods: {
...mapActions('appConfig', ['setWidgetColor']),
...mapActions('conversation', ['fetchOldConversations', 'setUserLastSeen']),
- ...mapActions('campaign', ['initCampaigns', 'executeCampaign']),
+ ...mapActions('campaign', [
+ 'initCampaigns',
+ 'executeCampaign',
+ 'resetCampaign',
+ ]),
...mapActions('agent', ['fetchAvailableAgents']),
...mapMutations('events', ['toggleOpen']),
scrollConversationToBottom() {
@@ -147,15 +154,25 @@ export default {
});
},
registerCampaignEvents() {
- bus.$on('on-campaign-view-clicked', campaignId => {
- const { websiteToken } = window.chatwootWebChannel;
+ bus.$on('on-campaign-view-clicked', () => {
+ this.isCampaignViewClicked = true;
this.showCampaignView = false;
this.showUnreadView = false;
this.unsetUnreadView();
this.setUserLastSeen();
+ // Execute campaign only if pre-chat form (and require email too) is not enabled
+ if (
+ !(this.preChatFormEnabled && this.preChatFormOptions.requireEmail)
+ ) {
+ bus.$emit('execute-campaign', this.activeCampaign.id);
+ }
+ });
+ bus.$on('execute-campaign', campaignId => {
+ const { websiteToken } = window.chatwootWebChannel;
this.executeCampaign({ campaignId, websiteToken });
});
},
+
setPopoutDisplay(showPopoutButton) {
this.showPopoutButton = showPopoutButton;
},
@@ -255,6 +272,10 @@ export default {
this.showUnreadView = true;
this.showCampaignView = false;
} else if (message.event === 'unset-unread-view') {
+ // Reset campaign, If widget opened via clciking on bubble button
+ if (!this.isCampaignViewClicked) {
+ this.resetCampaign();
+ }
this.showUnreadView = false;
this.showCampaignView = false;
} else if (message.event === 'toggle-open') {
diff --git a/app/javascript/widget/components/PreChat/Form.vue b/app/javascript/widget/components/PreChat/Form.vue
index 448c33ba5..157c1f233 100644
--- a/app/javascript/widget/components/PreChat/Form.vue
+++ b/app/javascript/widget/components/PreChat/Form.vue
@@ -3,8 +3,11 @@
class="flex flex-1 flex-col p-6 overflow-y-auto"
@submit.prevent="onSubmit"
>
-
- {{ options.preChatMessage }}
+
+ {{ headerMessage }}
$state.uiFlags.hasFetched,
getCampaigns: $state => $state.records,
getActiveCampaign: $state => $state.activeCampaign,
+ getCampaignHasExecuted: $state => $state.campaignHasExecuted,
};
export const actions = {
@@ -76,17 +78,37 @@ export const actions = {
);
}
},
- startCampaign: async ({ commit }, { websiteToken, campaignId }) => {
- const { data: campaigns } = await getCampaigns(websiteToken);
- const campaign = campaigns.find(item => item.id === campaignId);
- if (campaign) {
- commit('setActiveCampaign', campaign);
+ startCampaign: async (
+ {
+ commit,
+ rootState: {
+ events: { isOpen },
+ },
+ },
+ { websiteToken, campaignId }
+ ) => {
+ // Disable campaign execution if widget is opened
+ if (!isOpen) {
+ const { data: campaigns } = await getCampaigns(websiteToken);
+ // Check campaign is disabled or not
+ const campaign = campaigns.find(item => item.id === campaignId);
+ if (campaign) {
+ commit('setActiveCampaign', campaign);
+ }
}
},
executeCampaign: async ({ commit }, { campaignId, websiteToken }) => {
try {
await triggerCampaign({ campaignId, websiteToken });
+ commit('setCampaignExecuted');
+ commit('setActiveCampaign', {});
+ } catch (error) {
+ commit('setError', true);
+ }
+ },
+ resetCampaign: async ({ commit }) => {
+ try {
commit('setActiveCampaign', {});
} catch (error) {
commit('setError', true);
@@ -107,6 +129,9 @@ export const mutations = {
setHasFetched($state, value) {
Vue.set($state.uiFlags, 'hasFetched', value);
},
+ setCampaignExecuted($state) {
+ Vue.set($state, 'campaignHasExecuted', true);
+ },
};
export default {
diff --git a/app/javascript/widget/store/modules/specs/campaign/actions.spec.js b/app/javascript/widget/store/modules/specs/campaign/actions.spec.js
index a9bd07fa2..49f441111 100644
--- a/app/javascript/widget/store/modules/specs/campaign/actions.spec.js
+++ b/app/javascript/widget/store/modules/specs/campaign/actions.spec.js
@@ -94,14 +94,28 @@ describe('#actions', () => {
it('reset campaign if campaign id is not present in the campaign list', async () => {
API.get.mockResolvedValue({ data: campaigns });
await actions.startCampaign(
- { dispatch, getters: { getCampaigns: campaigns }, commit },
+ {
+ dispatch,
+ getters: { getCampaigns: campaigns },
+ commit,
+ rootState: {
+ events: { isOpen: true },
+ },
+ },
{ campaignId: 32 }
);
});
it('start campaign if campaign id passed', async () => {
API.get.mockResolvedValue({ data: campaigns });
await actions.startCampaign(
- { dispatch, getters: { getCampaigns: campaigns }, commit },
+ {
+ dispatch,
+ getters: { getCampaigns: campaigns },
+ commit,
+ rootState: {
+ events: { isOpen: false },
+ },
+ },
{ campaignId: 1 }
);
expect(commit.mock.calls).toEqual([['setActiveCampaign', campaigns[0]]]);
@@ -112,7 +126,10 @@ describe('#actions', () => {
const params = { campaignId: 12, websiteToken: 'XDsafmADasd' };
API.post.mockResolvedValue({});
await actions.executeCampaign({ commit }, params);
- expect(commit.mock.calls).toEqual([['setActiveCampaign', {}]]);
+ expect(commit.mock.calls).toEqual([
+ ['setCampaignExecuted'],
+ ['setActiveCampaign', {}],
+ ]);
});
it('sends correct actions if execute campaign API is failed', async () => {
const params = { campaignId: 12, websiteToken: 'XDsafmADasd' };
@@ -121,4 +138,12 @@ describe('#actions', () => {
expect(commit.mock.calls).toEqual([['setError', true]]);
});
});
+
+ describe('#resetCampaign', () => {
+ it('sends correct actions if execute campaign API is success', async () => {
+ API.post.mockResolvedValue({});
+ await actions.resetCampaign({ commit });
+ expect(commit.mock.calls).toEqual([['setActiveCampaign', {}]]);
+ });
+ });
});
diff --git a/app/javascript/widget/store/modules/specs/campaign/getters.spec.js b/app/javascript/widget/store/modules/specs/campaign/getters.spec.js
index 2d027426c..ceb9185e2 100644
--- a/app/javascript/widget/store/modules/specs/campaign/getters.spec.js
+++ b/app/javascript/widget/store/modules/specs/campaign/getters.spec.js
@@ -129,4 +129,17 @@ describe('#getters', () => {
updated_at: '2021-05-03T04:53:36.354Z',
});
});
+ it('getCampaignHasExecuted', () => {
+ const state = {
+ records: [],
+ uiFlags: {
+ isError: false,
+ hasFetched: false,
+ },
+ activeCampaign: {},
+ campaignHasExecuted: false,
+ };
+
+ expect(getters.getCampaignHasExecuted(state)).toEqual(false);
+ });
});
diff --git a/app/javascript/widget/store/modules/specs/campaign/mutations.spec.js b/app/javascript/widget/store/modules/specs/campaign/mutations.spec.js
index 1ca364751..7a519028e 100644
--- a/app/javascript/widget/store/modules/specs/campaign/mutations.spec.js
+++ b/app/javascript/widget/store/modules/specs/campaign/mutations.spec.js
@@ -33,4 +33,12 @@ describe('#mutations', () => {
expect(state.activeCampaign).toEqual(campaigns[0]);
});
});
+
+ describe('#setCampaignExecuted', () => {
+ it('set campaign executed flag', () => {
+ const state = { records: [], uiFlags: {}, campaignHasExecuted: false };
+ mutations.setCampaignExecuted(state);
+ expect(state.campaignHasExecuted).toEqual(true);
+ });
+ });
});
diff --git a/app/javascript/widget/views/Home.vue b/app/javascript/widget/views/Home.vue
index adb8f137d..33deb60e1 100755
--- a/app/javascript/widget/views/Home.vue
+++ b/app/javascript/widget/views/Home.vue
@@ -83,6 +83,8 @@ import { mapGetters } from 'vuex';
import { MAXIMUM_FILE_UPLOAD_SIZE } from 'shared/constants/messages';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import PreChatForm from '../components/PreChat/Form';
+import { isEmptyObject } from 'widget/helpers/utils';
+
export default {
name: 'Home',
components: {
@@ -106,6 +108,10 @@ export default {
type: Boolean,
default: false,
},
+ isCampaignViewClicked: {
+ type: Boolean,
+ default: false,
+ },
},
data() {
return {
@@ -121,16 +127,24 @@ export default {
groupedMessages: 'conversation/getGroupedConversation',
isFetchingList: 'conversation/getIsFetchingList',
currentUser: 'contacts/getCurrentUser',
+ activeCampaign: 'campaign/getActiveCampaign',
+ getCampaignHasExecuted: 'campaign/getCampaignHasExecuted',
}),
currentView() {
const { email: currentUserEmail = '' } = this.currentUser;
+
if (this.isHeaderCollapsed) {
if (this.conversationSize) {
return 'messageView';
}
+
if (
- this.isOnNewConversation ||
- (this.preChatFormEnabled && !currentUserEmail)
+ !this.getCampaignHasExecuted &&
+ ((this.preChatFormEnabled &&
+ !isEmptyObject(this.activeCampaign) &&
+ this.preChatFormOptions.requireEmail) ||
+ this.isOnNewConversation ||
+ (this.preChatFormEnabled && !currentUserEmail))
) {
return 'preChatFormView';
}
@@ -145,10 +159,13 @@ export default {
return MAXIMUM_FILE_UPLOAD_SIZE;
},
isHeaderCollapsed() {
- if (!this.hasIntroText || this.conversationSize) {
+ if (
+ !this.hasIntroText ||
+ this.conversationSize ||
+ this.isCampaignViewClicked
+ ) {
return true;
}
-
return this.isOnCollapsedView;
},
hasIntroText() {
diff --git a/app/javascript/widget/views/Router.vue b/app/javascript/widget/views/Router.vue
index 3f21497bc..fb90cbd24 100644
--- a/app/javascript/widget/views/Router.vue
+++ b/app/javascript/widget/views/Router.vue
@@ -13,6 +13,7 @@
:has-fetched="hasFetched"
:unread-message-count="unreadMessageCount"
:show-popout-button="showPopoutButton"
+ :is-campaign-view-clicked="isCampaignViewClicked"
/>