feat: Use vue-router on widget route management (#3415)

* feat: Add vue-router to widget

Co-authored-by: Pranav <pranav@chatwoot.com>

* Move to dynamic imports

* Move to routerMixin

* Fix popup button display

* Remove unnecessary import

* router -> route

* Fix open state

* Fix issues

* Remove used CSS

* Fix specs

* Fix specs

* Fix widgetColor specs

* Fix mutation specs

* Fixes broken lint errors

* Fixes issues with widget flow

Co-authored-by: Nithin <nithin@chatwoot.com>
Co-authored-by: Nithin David <1277421+nithindavid@users.noreply.github.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
Pranav Raj S
2022-01-12 02:55:27 -08:00
committed by GitHub
parent 991a42c417
commit 9c31d7c672
38 changed files with 617 additions and 725 deletions

View File

@@ -1,18 +1,43 @@
import { SET_REFERRER_HOST, SET_WIDGET_COLOR } from '../types';
import {
SET_REFERRER_HOST,
SET_WIDGET_APP_CONFIG,
SET_WIDGET_COLOR,
TOGGLE_WIDGET_OPEN,
} from '../types';
const state = {
showPopoutButton: false,
hideMessageBubble: false,
position: 'right',
isWebWidgetTriggered: false,
isCampaignViewClicked: false,
isWidgetOpen: false,
widgetColor: '',
referrerHost: '',
};
export const getters = {
getAppConfig: $state => $state,
isRightAligned: $state => $state.position === 'right',
getHideMessageBubble: $state => $state.hideMessageBubble,
getIsWidgetOpen: $state => $state.isWidgetOpen,
getWidgetColor: $state => $state.widgetColor,
getReferrerHost: $state => $state.referrerHost,
};
export const actions = {
setWidgetColor({ commit }, data) {
commit(SET_WIDGET_COLOR, data);
setAppConfig({ commit }, { showPopoutButton, position, hideMessageBubble }) {
commit(SET_WIDGET_APP_CONFIG, {
showPopoutButton: !!showPopoutButton,
position: position || 'right',
hideMessageBubble: !!hideMessageBubble,
});
},
toggleWidgetOpen({ commit }, isWidgetOpen) {
commit(TOGGLE_WIDGET_OPEN, isWidgetOpen);
},
setWidgetColor({ commit }, widgetColor) {
commit(SET_WIDGET_COLOR, widgetColor);
},
setReferrerHost({ commit }, referrerHost) {
commit(SET_REFERRER_HOST, referrerHost);
@@ -20,8 +45,16 @@ export const actions = {
};
export const mutations = {
[SET_WIDGET_COLOR]($state, data) {
$state.widgetColor = data.widgetColor;
[SET_WIDGET_APP_CONFIG]($state, data) {
$state.showPopoutButton = data.showPopoutButton;
$state.position = data.position;
$state.hideMessageBubble = data.hideMessageBubble;
},
[TOGGLE_WIDGET_OPEN]($state, isWidgetOpen) {
$state.isWidgetOpen = isWidgetOpen;
},
[SET_WIDGET_COLOR]($state, widgetColor) {
$state.widgetColor = widgetColor;
},
[SET_REFERRER_HOST]($state, referrerHost) {
$state.referrerHost = referrerHost;

View File

@@ -9,10 +9,8 @@ const state = {
records: [],
uiFlags: {
isError: false,
hasFetched: false,
},
activeCampaign: {},
campaignHasExecuted: false,
};
const resetCampaignTimers = (
@@ -32,10 +30,8 @@ const resetCampaignTimers = (
};
export const getters = {
getHasFetched: $state => $state.uiFlags.hasFetched,
getCampaigns: $state => $state.records,
getActiveCampaign: $state => $state.activeCampaign,
getCampaignHasExecuted: $state => $state.campaignHasExecuted,
};
export const actions = {
@@ -47,7 +43,6 @@ export const actions = {
const { data: campaigns } = await getCampaigns(websiteToken);
commit('setCampaigns', campaigns);
commit('setError', false);
commit('setHasFetched', true);
resetCampaignTimers(
campaigns,
currentURL,
@@ -56,7 +51,6 @@ export const actions = {
);
} catch (error) {
commit('setError', true);
commit('setHasFetched', true);
}
},
initCampaigns: async (
@@ -82,13 +76,13 @@ export const actions = {
{
commit,
rootState: {
events: { isOpen },
appConfig: { isWidgetOpen },
},
},
{ websiteToken, campaignId }
) => {
// Disable campaign execution if widget is opened
if (!isOpen) {
if (!isWidgetOpen) {
const { data: campaigns } = await getCampaigns(websiteToken);
// Check campaign is disabled or not
const campaign = campaigns.find(item => item.id === campaignId);
@@ -100,11 +94,21 @@ export const actions = {
executeCampaign: async ({ commit }, { campaignId, websiteToken }) => {
try {
commit(
'conversation/setConversationUIFlag',
{ isCreating: true },
{ root: true }
);
await triggerCampaign({ campaignId, websiteToken });
commit('setCampaignExecuted');
commit('setActiveCampaign', {});
} catch (error) {
commit('setError', true);
} finally {
commit(
'conversation/setConversationUIFlag',
{ isCreating: false },
{ root: true }
);
}
},
resetCampaign: async ({ commit }) => {
@@ -126,12 +130,6 @@ export const mutations = {
setError($state, value) {
Vue.set($state.uiFlags, 'isError', value);
},
setHasFetched($state, value) {
Vue.set($state.uiFlags, 'hasFetched', value);
},
setCampaignExecuted($state) {
Vue.set($state, 'campaignHasExecuted', true);
},
};
export default {

View File

@@ -1,9 +1,5 @@
import events from 'widget/api/events';
const state = {
isOpen: false,
};
const actions = {
create: async (_, { name }) => {
try {
@@ -14,16 +10,10 @@ const actions = {
},
};
const mutations = {
toggleOpen($state) {
$state.isOpen = !$state.isOpen;
},
};
export default {
namespaced: true,
state,
state: {},
getters: {},
actions,
mutations,
mutations: {},
};

View File

@@ -18,7 +18,7 @@ describe('#mutations', () => {
});
});
describe('#setError', () => {
describe('#setHasFetched', () => {
it('set fetched flag', () => {
const state = { records: [], uiFlags: {} };
mutations.setHasFetched(state, true);

View File

@@ -13,10 +13,8 @@ describe('#actions', () => {
describe('#setWidgetColor', () => {
it('creates actions properly', () => {
actions.setWidgetColor({ commit }, { widgetColor: '#eaeaea' });
expect(commit.mock.calls).toEqual([
['SET_WIDGET_COLOR', { widgetColor: '#eaeaea' }],
]);
actions.setWidgetColor({ commit }, '#eaeaea');
expect(commit.mock.calls).toEqual([['SET_WIDGET_COLOR', '#eaeaea']]);
});
});
});

View File

@@ -12,7 +12,7 @@ describe('#mutations', () => {
describe('#SET_WIDGET_COLOR', () => {
it('sets widget color properly', () => {
const state = { widgetColor: '' };
mutations.SET_WIDGET_COLOR(state, { widgetColor: '#00bcd4' });
mutations.SET_WIDGET_COLOR(state, '#00bcd4');
expect(state.widgetColor).toEqual('#00bcd4');
});
});

View File

@@ -24,7 +24,6 @@ describe('#actions', () => {
expect(commit.mock.calls).toEqual([
['setCampaigns', campaigns],
['setError', false],
['setHasFetched', true],
]);
expect(campaignTimer.initTimers).toHaveBeenCalledWith(
{
@@ -50,10 +49,7 @@ describe('#actions', () => {
isInBusinessHours: true,
}
);
expect(commit.mock.calls).toEqual([
['setError', true],
['setHasFetched', true],
]);
expect(commit.mock.calls).toEqual([['setError', true]]);
});
});
describe('#initCampaigns', () => {
@@ -99,7 +95,7 @@ describe('#actions', () => {
getters: { getCampaigns: campaigns },
commit,
rootState: {
events: { isOpen: true },
appConfig: { isWidgetOpen: true },
},
},
{ campaignId: 32 }
@@ -113,7 +109,7 @@ describe('#actions', () => {
getters: { getCampaigns: campaigns },
commit,
rootState: {
events: { isOpen: false },
appConfig: { isWidgetOpen: false },
},
},
{ campaignId: 1 }
@@ -127,15 +123,52 @@ describe('#actions', () => {
API.post.mockResolvedValue({});
await actions.executeCampaign({ commit }, params);
expect(commit.mock.calls).toEqual([
['setCampaignExecuted'],
[
'conversation/setConversationUIFlag',
{
isCreating: true,
},
{
root: true,
},
],
['setActiveCampaign', {}],
[
'conversation/setConversationUIFlag',
{
isCreating: false,
},
{
root: true,
},
],
]);
});
it('sends correct actions if execute campaign API is failed', async () => {
const params = { campaignId: 12, websiteToken: 'XDsafmADasd' };
API.post.mockRejectedValue({ message: 'Authentication required' });
await actions.executeCampaign({ commit }, params);
expect(commit.mock.calls).toEqual([['setError', true]]);
expect(commit.mock.calls).toEqual([
[
'conversation/setConversationUIFlag',
{
isCreating: true,
},
{
root: true,
},
],
['setError', true],
[
'conversation/setConversationUIFlag',
{
isCreating: false,
},
{
root: true,
},
],
]);
});
});

View File

@@ -129,17 +129,4 @@ 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);
});
});

View File

@@ -18,14 +18,6 @@ describe('#mutations', () => {
});
});
describe('#setHasFetched', () => {
it('set fetched flag', () => {
const state = { records: [], uiFlags: {} };
mutations.setHasFetched(state, true);
expect(state.uiFlags.hasFetched).toEqual(true);
});
});
describe('#setActiveCampaign', () => {
it('set active campaign', () => {
const state = { records: [] };
@@ -33,12 +25,4 @@ 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);
});
});
});