feat: Add flat
design for widget (#4065)
This commit is contained in:
parent
dcecbf4b80
commit
6c94768bdb
18 changed files with 251 additions and 109 deletions
|
@ -1,5 +1,8 @@
|
||||||
class WidgetTestsController < ActionController::Base
|
class WidgetTestsController < ActionController::Base
|
||||||
before_action :set_web_widget
|
before_action :ensure_web_widget
|
||||||
|
before_action :ensure_widget_position
|
||||||
|
before_action :ensure_widget_type
|
||||||
|
before_action :ensure_widget_style
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render
|
render
|
||||||
|
@ -7,7 +10,24 @@ class WidgetTestsController < ActionController::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_web_widget
|
def ensure_widget_style
|
||||||
@web_widget = Channel::WebWidget.first
|
@widget_style = params[:widget_style] || 'standard'
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_widget_position
|
||||||
|
@widget_position = params[:position] || 'left'
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_widget_type
|
||||||
|
@widget_type = params[:type] || 'expanded_bubble'
|
||||||
|
end
|
||||||
|
|
||||||
|
def inbox_id
|
||||||
|
@inbox_id ||= params[:inbox_id] || Channel::WebWidget.first.inbox.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_web_widget
|
||||||
|
@inbox = Inbox.find(inbox_id)
|
||||||
|
@web_widget = @inbox.channel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import { IFrameHelper } from '../sdk/IFrameHelper';
|
import { IFrameHelper } from '../sdk/IFrameHelper';
|
||||||
import { getBubbleView } from '../sdk/bubbleHelpers';
|
import { getBubbleView } from '../sdk/settingsHelper';
|
||||||
import md5 from 'md5';
|
import {
|
||||||
import { getUserCookieName } from '../sdk/cookieHelpers';
|
computeHashForUserData,
|
||||||
|
getUserCookieName,
|
||||||
const REQUIRED_USER_KEYS = ['avatar_url', 'email', 'name'];
|
hasUserKeys,
|
||||||
|
} from '../sdk/cookieHelpers';
|
||||||
const ALLOWED_USER_ATTRIBUTES = [...REQUIRED_USER_KEYS, 'identifier_hash'];
|
|
||||||
|
|
||||||
export const getUserString = ({ identifier = '', user }) => {
|
|
||||||
const userStringWithSortedKeys = ALLOWED_USER_ATTRIBUTES.reduce(
|
|
||||||
(acc, key) => `${acc}${key}${user[key] || ''}`,
|
|
||||||
''
|
|
||||||
);
|
|
||||||
return `${userStringWithSortedKeys}identifier${identifier}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const computeHashForUserData = (...args) => md5(getUserString(...args));
|
|
||||||
|
|
||||||
export const hasUserKeys = user =>
|
|
||||||
REQUIRED_USER_KEYS.reduce((acc, key) => acc || !!user[key], false);
|
|
||||||
|
|
||||||
const runSDK = ({ baseUrl, websiteToken }) => {
|
const runSDK = ({ baseUrl, websiteToken }) => {
|
||||||
if (window.$chatwoot) {
|
if (window.$chatwoot) {
|
||||||
|
@ -38,6 +24,7 @@ const runSDK = ({ baseUrl, websiteToken }) => {
|
||||||
type: getBubbleView(chatwootSettings.type),
|
type: getBubbleView(chatwootSettings.type),
|
||||||
launcherTitle: chatwootSettings.launcherTitle || '',
|
launcherTitle: chatwootSettings.launcherTitle || '',
|
||||||
showPopoutButton: chatwootSettings.showPopoutButton || false,
|
showPopoutButton: chatwootSettings.showPopoutButton || false,
|
||||||
|
widgetStyle: chatwootSettings.widgetStyle || 'standard',
|
||||||
|
|
||||||
toggle(state) {
|
toggle(state) {
|
||||||
IFrameHelper.events.toggleBubble(state);
|
IFrameHelper.events.toggleBubble(state);
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { dispatchWindowEvent } from 'shared/helpers/CustomEventHelper';
|
||||||
import { CHATWOOT_ERROR, CHATWOOT_READY } from '../widget/constants/sdkEvents';
|
import { CHATWOOT_ERROR, CHATWOOT_READY } from '../widget/constants/sdkEvents';
|
||||||
import { SET_USER_ERROR } from '../widget/constants/errorTypes';
|
import { SET_USER_ERROR } from '../widget/constants/errorTypes';
|
||||||
import { getUserCookieName } from './cookieHelpers';
|
import { getUserCookieName } from './cookieHelpers';
|
||||||
|
import { isFlatWidgetStyle } from './settingsHelper';
|
||||||
|
|
||||||
export const IFrameHelper = {
|
export const IFrameHelper = {
|
||||||
getUrl({ baseUrl, websiteToken }) {
|
getUrl({ baseUrl, websiteToken }) {
|
||||||
|
@ -52,6 +53,10 @@ export const IFrameHelper = {
|
||||||
if (window.$chatwoot.hideMessageBubble) {
|
if (window.$chatwoot.hideMessageBubble) {
|
||||||
holderClassName += ` woot-widget--without-bubble`;
|
holderClassName += ` woot-widget--without-bubble`;
|
||||||
}
|
}
|
||||||
|
if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) {
|
||||||
|
holderClassName += ` woot-widget-holder--flat`;
|
||||||
|
}
|
||||||
|
|
||||||
addClass(widgetHolder, holderClassName);
|
addClass(widgetHolder, holderClassName);
|
||||||
widgetHolder.appendChild(iframe);
|
widgetHolder.appendChild(iframe);
|
||||||
body.appendChild(widgetHolder);
|
body.appendChild(widgetHolder);
|
||||||
|
@ -121,6 +126,7 @@ export const IFrameHelper = {
|
||||||
position: window.$chatwoot.position,
|
position: window.$chatwoot.position,
|
||||||
hideMessageBubble: window.$chatwoot.hideMessageBubble,
|
hideMessageBubble: window.$chatwoot.hideMessageBubble,
|
||||||
showPopoutButton: window.$chatwoot.showPopoutButton,
|
showPopoutButton: window.$chatwoot.showPopoutButton,
|
||||||
|
widgetStyle: window.$chatwoot.widgetStyle,
|
||||||
});
|
});
|
||||||
IFrameHelper.onLoad({
|
IFrameHelper.onLoad({
|
||||||
widgetColor: message.config.channelConfig.widgetColor,
|
widgetColor: message.config.channelConfig.widgetColor,
|
||||||
|
@ -222,21 +228,27 @@ export const IFrameHelper = {
|
||||||
createBubbleHolder();
|
createBubbleHolder();
|
||||||
onLocationChangeListener();
|
onLocationChangeListener();
|
||||||
if (!window.$chatwoot.hideMessageBubble) {
|
if (!window.$chatwoot.hideMessageBubble) {
|
||||||
|
let className = 'woot-widget-bubble';
|
||||||
|
let closeBtnClassName = `woot-elements--${window.$chatwoot.position} woot-widget-bubble woot--close woot--hide`;
|
||||||
|
|
||||||
|
if (isFlatWidgetStyle(window.$chatwoot.widgetStyle)) {
|
||||||
|
className += ' woot-widget-bubble--flat';
|
||||||
|
closeBtnClassName += ' woot-widget-bubble--flat';
|
||||||
|
}
|
||||||
|
|
||||||
const chatIcon = createBubbleIcon({
|
const chatIcon = createBubbleIcon({
|
||||||
className: 'woot-widget-bubble',
|
className,
|
||||||
src: bubbleImg,
|
src: bubbleImg,
|
||||||
target: chatBubble,
|
target: chatBubble,
|
||||||
});
|
});
|
||||||
|
|
||||||
const closeIcon = closeBubble;
|
addClass(closeBubble, closeBtnClassName);
|
||||||
const closeIconclassName = `woot-elements--${window.$chatwoot.position} woot-widget-bubble woot--close woot--hide`;
|
|
||||||
addClass(closeIcon, closeIconclassName);
|
|
||||||
|
|
||||||
chatIcon.style.background = widgetColor;
|
chatIcon.style.background = widgetColor;
|
||||||
closeIcon.style.background = widgetColor;
|
closeBubble.style.background = widgetColor;
|
||||||
|
|
||||||
bubbleHolder.appendChild(chatIcon);
|
bubbleHolder.appendChild(chatIcon);
|
||||||
bubbleHolder.appendChild(closeIcon);
|
bubbleHolder.appendChild(closeBubble);
|
||||||
bubbleHolder.appendChild(createNotificationBubble());
|
bubbleHolder.appendChild(createNotificationBubble());
|
||||||
onClickChatBubble();
|
onClickChatBubble();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { addClass, removeClass, toggleClass, wootOn } from './DOMHelpers';
|
import { addClass, removeClass, toggleClass, wootOn } from './DOMHelpers';
|
||||||
import { IFrameHelper } from './IFrameHelper';
|
import { IFrameHelper } from './IFrameHelper';
|
||||||
import { BUBBLE_DESIGN } from './constants';
|
import { isExpandedView } from './settingsHelper';
|
||||||
|
|
||||||
export const bubbleImg =
|
export const bubbleImg =
|
||||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAUVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////8IN+deAAAAGnRSTlMAAwgJEBk0TVheY2R5eo+ut8jb5OXs8fX2+cjRDTIAAADsSURBVHgBldZbkoMgFIThRgQv8SKKgGf/C51UnJqaRI30/9zfe+NQUQ3TvG7bOk9DVeCmshmj/CuOTYnrdBfkUOg0zlOtl9OWVuEk4+QyZ3DIevmSt/ioTvK1VH/s5bY3YdM9SBZ/mUUyWgx+U06ycgp7D8msxSvtc4HXL9BLdj2elSEfhBJAI0QNgJEBI1BEBsQClVBVGDgwYOLAhJkDM1YOrNg4sLFAsLJgZsHEgoEFFQt0JAFGFjQsKAMJ0LFAexKgZYFyJIDxJIBNJEDNAtSJBLCeBDCOBFAPzwFA94ED+zmhwDO9358r8ANtIsMXi7qVAwAAAABJRU5ErkJggg==';
|
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAUVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////8IN+deAAAAGnRSTlMAAwgJEBk0TVheY2R5eo+ut8jb5OXs8fX2+cjRDTIAAADsSURBVHgBldZbkoMgFIThRgQv8SKKgGf/C51UnJqaRI30/9zfe+NQUQ3TvG7bOk9DVeCmshmj/CuOTYnrdBfkUOg0zlOtl9OWVuEk4+QyZ3DIevmSt/ioTvK1VH/s5bY3YdM9SBZ/mUUyWgx+U06ycgp7D8msxSvtc4HXL9BLdj2elSEfhBJAI0QNgJEBI1BEBsQClVBVGDgwYOLAhJkDM1YOrNg4sLFAsLJgZsHEgoEFFQt0JAFGFjQsKAMJ0LFAexKgZYFyJIDxJIBNJEDNAtSJBLCeBDCOBFAPzwFA94ED+zmhwDO9358r8ANtIsMXi7qVAwAAAABJRU5ErkJggg==';
|
||||||
|
@ -13,10 +13,6 @@ export const chatBubble = document.createElement('button');
|
||||||
export const closeBubble = document.createElement('button');
|
export const closeBubble = document.createElement('button');
|
||||||
export const notificationBubble = document.createElement('span');
|
export const notificationBubble = document.createElement('span');
|
||||||
|
|
||||||
export const getBubbleView = type =>
|
|
||||||
BUBBLE_DESIGN.includes(type) ? type : BUBBLE_DESIGN[0];
|
|
||||||
export const isExpandedView = type => getBubbleView(type) === BUBBLE_DESIGN[1];
|
|
||||||
|
|
||||||
export const setBubbleText = bubbleText => {
|
export const setBubbleText = bubbleText => {
|
||||||
if (isExpandedView(window.$chatwoot.type)) {
|
if (isExpandedView(window.$chatwoot.type)) {
|
||||||
const textNode = document.getElementById('woot-widget--expanded__text');
|
const textNode = document.getElementById('woot-widget--expanded__text');
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
export const BUBBLE_DESIGN = ['standard', 'expanded_bubble'];
|
export const BUBBLE_DESIGN = ['standard', 'expanded_bubble'];
|
||||||
|
export const WIDGET_DESIGN = ['standard', 'flat'];
|
||||||
|
|
|
@ -1,5 +1,23 @@
|
||||||
|
import md5 from 'md5';
|
||||||
|
|
||||||
|
const REQUIRED_USER_KEYS = ['avatar_url', 'email', 'name'];
|
||||||
|
const ALLOWED_USER_ATTRIBUTES = [...REQUIRED_USER_KEYS, 'identifier_hash'];
|
||||||
|
|
||||||
export const getUserCookieName = () => {
|
export const getUserCookieName = () => {
|
||||||
const SET_USER_COOKIE_PREFIX = 'cw_user_';
|
const SET_USER_COOKIE_PREFIX = 'cw_user_';
|
||||||
const { websiteToken: websiteIdentifier } = window.$chatwoot;
|
const { websiteToken: websiteIdentifier } = window.$chatwoot;
|
||||||
return `${SET_USER_COOKIE_PREFIX}${websiteIdentifier}`;
|
return `${SET_USER_COOKIE_PREFIX}${websiteIdentifier}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUserString = ({ identifier = '', user }) => {
|
||||||
|
const userStringWithSortedKeys = ALLOWED_USER_ATTRIBUTES.reduce(
|
||||||
|
(acc, key) => `${acc}${key}${user[key] || ''}`,
|
||||||
|
''
|
||||||
|
);
|
||||||
|
return `${userStringWithSortedKeys}identifier${identifier}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const computeHashForUserData = (...args) => md5(getUserString(...args));
|
||||||
|
|
||||||
|
export const hasUserKeys = user =>
|
||||||
|
REQUIRED_USER_KEYS.reduce((acc, key) => acc || !!user[key], false);
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
export const SDK_CSS = `.woot-widget-holder {
|
export const SDK_CSS = `
|
||||||
box-shadow: 0 5px 40px rgba(0, 0, 0, .16) !important;
|
:root {
|
||||||
|
--b-100: #F2F3F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woot-widget-holder {
|
||||||
|
box-shadow: 0 5px 40px rgba(0, 0, 0, .16);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
will-change: transform, opacity;
|
will-change: transform, opacity;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
|
@ -9,6 +14,12 @@ export const SDK_CSS = `.woot-widget-holder {
|
||||||
z-index: 2147483000 !important;
|
z-index: 2147483000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.woot-widget-holder.woot-widget-holder--flat {
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 0;
|
||||||
|
border: 1px solid var(--b-100);
|
||||||
|
}
|
||||||
|
|
||||||
.woot-widget-holder iframe {
|
.woot-widget-holder iframe {
|
||||||
border: 0;
|
border: 0;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
|
@ -22,21 +33,45 @@ export const SDK_CSS = `.woot-widget-holder {
|
||||||
height: auto;
|
height: auto;
|
||||||
bottom: 94px;
|
bottom: 94px;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.woot-widget-bubble {
|
.woot-widget-bubble {
|
||||||
background: #1f93ff;
|
background: #1f93ff;
|
||||||
border-radius: 100px !important;
|
border-radius: 100px;
|
||||||
border-width: 0px;
|
border-width: 0px;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
padding: 0px;
|
|
||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, .16) !important;
|
box-shadow: 0 8px 24px rgba(0, 0, 0, .16) !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 64px !important;
|
height: 64px;
|
||||||
|
padding: 0px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 64px !important;
|
|
||||||
z-index: 2147483000 !important;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
width: 64px;
|
||||||
|
z-index: 2147483000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woot-widget-bubble.woot-widget-bubble--flat {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woot-widget-holder.woot-widget-holder--flat {
|
||||||
|
bottom: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woot-widget-bubble.woot-widget-bubble--flat {
|
||||||
|
height: 56px;
|
||||||
|
width: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woot-widget-bubble.woot-widget-bubble--flat img {
|
||||||
|
margin: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woot-widget-bubble.woot-widget-bubble--flat.woot--close::before,
|
||||||
|
.woot-widget-bubble.woot-widget-bubble--flat.woot--close::after {
|
||||||
|
left: 28px;
|
||||||
|
top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.woot-widget-bubble.unread-notification::after {
|
.woot-widget-bubble.unread-notification::after {
|
||||||
|
@ -184,7 +219,7 @@ export const SDK_CSS = `.woot-widget-holder {
|
||||||
|
|
||||||
@media only screen and (min-width: 667px) {
|
@media only screen and (min-width: 667px) {
|
||||||
.woot-widget-holder {
|
.woot-widget-holder {
|
||||||
border-radius: 16px !important;
|
border-radius: 16px;
|
||||||
bottom: 104px;
|
bottom: 104px;
|
||||||
height: calc(85% - 64px - 20px);
|
height: calc(85% - 64px - 20px);
|
||||||
max-height: 590px !important;
|
max-height: 590px !important;
|
||||||
|
|
11
app/javascript/sdk/settingsHelper.js
Normal file
11
app/javascript/sdk/settingsHelper.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { BUBBLE_DESIGN, WIDGET_DESIGN } from './constants';
|
||||||
|
|
||||||
|
export const getBubbleView = type =>
|
||||||
|
BUBBLE_DESIGN.includes(type) ? type : BUBBLE_DESIGN[0];
|
||||||
|
|
||||||
|
export const isExpandedView = type => getBubbleView(type) === BUBBLE_DESIGN[1];
|
||||||
|
|
||||||
|
export const getWidgetStyle = style =>
|
||||||
|
WIDGET_DESIGN.includes(style) ? style : WIDGET_DESIGN[0];
|
||||||
|
|
||||||
|
export const isFlatWidgetStyle = style => style === 'flat';
|
|
@ -1,17 +0,0 @@
|
||||||
import { getBubbleView, isExpandedView } from '../bubbleHelpers';
|
|
||||||
|
|
||||||
describe('#getBubbleView', () => {
|
|
||||||
it('returns correct view', () => {
|
|
||||||
expect(getBubbleView('')).toEqual('standard');
|
|
||||||
expect(getBubbleView('standard')).toEqual('standard');
|
|
||||||
expect(getBubbleView('expanded_bubble')).toEqual('expanded_bubble');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#isExpandedView', () => {
|
|
||||||
it('returns true if it is expanded view', () => {
|
|
||||||
expect(isExpandedView('')).toEqual(false);
|
|
||||||
expect(isExpandedView('standard')).toEqual(false);
|
|
||||||
expect(isExpandedView('expanded_bubble')).toEqual(true);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,4 +1,8 @@
|
||||||
import { getUserCookieName } from '../cookieHelpers';
|
import {
|
||||||
|
getUserCookieName,
|
||||||
|
getUserString,
|
||||||
|
hasUserKeys,
|
||||||
|
} from '../cookieHelpers';
|
||||||
|
|
||||||
describe('#getUserCookieName', () => {
|
describe('#getUserCookieName', () => {
|
||||||
it('returns correct cookie name', () => {
|
it('returns correct cookie name', () => {
|
||||||
|
@ -6,3 +10,40 @@ describe('#getUserCookieName', () => {
|
||||||
expect(getUserCookieName()).toBe('cw_user_123456');
|
expect(getUserCookieName()).toBe('cw_user_123456');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getUserString', () => {
|
||||||
|
it('returns correct user string', () => {
|
||||||
|
expect(
|
||||||
|
getUserString({
|
||||||
|
user: {
|
||||||
|
name: 'Pranav',
|
||||||
|
email: 'pranav@example.com',
|
||||||
|
avatar_url: 'https://images.chatwoot.com/placeholder',
|
||||||
|
identifier_hash: '12345',
|
||||||
|
},
|
||||||
|
identifier: '12345',
|
||||||
|
})
|
||||||
|
).toBe(
|
||||||
|
'avatar_urlhttps://images.chatwoot.com/placeholderemailpranav@example.comnamePranavidentifier_hash12345identifier12345'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
getUserString({
|
||||||
|
user: {
|
||||||
|
email: 'pranav@example.com',
|
||||||
|
avatar_url: 'https://images.chatwoot.com/placeholder',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).toBe(
|
||||||
|
'avatar_urlhttps://images.chatwoot.com/placeholderemailpranav@example.comnameidentifier_hashidentifier'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#hasUserKeys', () => {
|
||||||
|
it('checks whether the allowed list of keys are present', () => {
|
||||||
|
expect(hasUserKeys({})).toBe(false);
|
||||||
|
expect(hasUserKeys({ randomKey: 'randomValue' })).toBe(false);
|
||||||
|
expect(hasUserKeys({ avatar_url: 'randomValue' })).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
38
app/javascript/sdk/specs/settingsHelpers.spec.js
Normal file
38
app/javascript/sdk/specs/settingsHelpers.spec.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import {
|
||||||
|
getBubbleView,
|
||||||
|
getWidgetStyle,
|
||||||
|
isExpandedView,
|
||||||
|
isFlatWidgetStyle,
|
||||||
|
} from '../settingsHelper';
|
||||||
|
|
||||||
|
describe('#getBubbleView', () => {
|
||||||
|
it('returns correct view', () => {
|
||||||
|
expect(getBubbleView('')).toEqual('standard');
|
||||||
|
expect(getBubbleView('standard')).toEqual('standard');
|
||||||
|
expect(getBubbleView('expanded_bubble')).toEqual('expanded_bubble');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#isExpandedView', () => {
|
||||||
|
it('returns true if it is expanded view', () => {
|
||||||
|
expect(isExpandedView('')).toEqual(false);
|
||||||
|
expect(isExpandedView('standard')).toEqual(false);
|
||||||
|
expect(isExpandedView('expanded_bubble')).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#getWidgetStyle', () => {
|
||||||
|
it('returns correct view', () => {
|
||||||
|
expect(getWidgetStyle('')).toEqual('standard');
|
||||||
|
expect(getWidgetStyle('standard')).toEqual('standard');
|
||||||
|
expect(getWidgetStyle('flat')).toEqual('flat');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#isFlatWidgetStyle', () => {
|
||||||
|
it('returns true if it is expanded view', () => {
|
||||||
|
expect(isFlatWidgetStyle('')).toEqual(false);
|
||||||
|
expect(isFlatWidgetStyle('standard')).toEqual(false);
|
||||||
|
expect(isFlatWidgetStyle('flat')).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,38 +0,0 @@
|
||||||
import { getUserString, hasUserKeys } from '../../packs/sdk';
|
|
||||||
|
|
||||||
describe('#getUserString', () => {
|
|
||||||
it('returns correct user string', () => {
|
|
||||||
expect(
|
|
||||||
getUserString({
|
|
||||||
user: {
|
|
||||||
name: 'Pranav',
|
|
||||||
email: 'pranav@example.com',
|
|
||||||
avatar_url: 'https://images.chatwoot.com/placeholder',
|
|
||||||
identifier_hash: '12345',
|
|
||||||
},
|
|
||||||
identifier: '12345',
|
|
||||||
})
|
|
||||||
).toBe(
|
|
||||||
'avatar_urlhttps://images.chatwoot.com/placeholderemailpranav@example.comnamePranavidentifier_hash12345identifier12345'
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
getUserString({
|
|
||||||
user: {
|
|
||||||
email: 'pranav@example.com',
|
|
||||||
avatar_url: 'https://images.chatwoot.com/placeholder',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).toBe(
|
|
||||||
'avatar_urlhttps://images.chatwoot.com/placeholderemailpranav@example.comnameidentifier_hashidentifier'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#hasUserKeys', () => {
|
|
||||||
it('checks whether the allowed list of keys are present', () => {
|
|
||||||
expect(hasUserKeys({})).toBe(false);
|
|
||||||
expect(hasUserKeys({ randomKey: 'randomValue' })).toBe(false);
|
|
||||||
expect(hasUserKeys({ avatar_url: 'randomValue' })).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -12,6 +12,7 @@
|
||||||
'is-mobile': isMobile,
|
'is-mobile': isMobile,
|
||||||
'is-widget-right': isRightAligned,
|
'is-widget-right': isRightAligned,
|
||||||
'is-bubble-hidden': hideMessageBubble,
|
'is-bubble-hidden': hideMessageBubble,
|
||||||
|
'is-flat-design': isWidgetStyleFlat,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
|
@ -61,6 +62,7 @@ export default {
|
||||||
isWidgetOpen: 'appConfig/getIsWidgetOpen',
|
isWidgetOpen: 'appConfig/getIsWidgetOpen',
|
||||||
messageCount: 'conversation/getMessageCount',
|
messageCount: 'conversation/getMessageCount',
|
||||||
unreadMessageCount: 'conversation/getUnreadMessageCount',
|
unreadMessageCount: 'conversation/getUnreadMessageCount',
|
||||||
|
isWidgetStyleFlat: 'appConfig/isWidgetStyleFlat',
|
||||||
}),
|
}),
|
||||||
isIFrame() {
|
isIFrame() {
|
||||||
return IFrameHelper.isIFrame();
|
return IFrameHelper.isIFrame();
|
||||||
|
|
|
@ -57,3 +57,30 @@ body {
|
||||||
padding-left: $space-normal;
|
padding-left: $space-normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.is-flat-design {
|
||||||
|
.chat-bubble {
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message--input {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
|
||||||
|
&.is-focused {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<footer
|
<footer
|
||||||
v-if="!hideReplyBox"
|
v-if="!hideReplyBox"
|
||||||
class="shadow-sm rounded-lg bg-white mb-1 z-50 relative"
|
class="shadow-sm bg-white mb-1 z-50 relative"
|
||||||
|
:class="{ 'rounded-lg': !isWidgetStyleFlat }"
|
||||||
>
|
>
|
||||||
<chat-input-wrap
|
<chat-input-wrap
|
||||||
:on-send-message="handleSendMessage"
|
:on-send-message="handleSendMessage"
|
||||||
|
@ -54,6 +55,7 @@ export default {
|
||||||
widgetColor: 'appConfig/getWidgetColor',
|
widgetColor: 'appConfig/getWidgetColor',
|
||||||
getConversationSize: 'conversation/getConversationSize',
|
getConversationSize: 'conversation/getConversationSize',
|
||||||
currentUser: 'contacts/getCurrentUser',
|
currentUser: 'contacts/getCurrentUser',
|
||||||
|
isWidgetStyleFlat: 'appConfig/isWidgetStyleFlat',
|
||||||
}),
|
}),
|
||||||
textColor() {
|
textColor() {
|
||||||
return getContrastingTextColor(this.widgetColor);
|
return getContrastingTextColor(this.widgetColor);
|
||||||
|
|
|
@ -97,7 +97,6 @@ export default {
|
||||||
@import '~widget/assets/scss/mixins';
|
@import '~widget/assets/scss/mixins';
|
||||||
|
|
||||||
.header-wrap {
|
.header-wrap {
|
||||||
border-radius: $space-normal $space-normal 0 0;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
transition: max-height 300ms;
|
transition: max-height 300ms;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
|
|
|
@ -6,14 +6,15 @@ import {
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
showPopoutButton: false,
|
|
||||||
hideMessageBubble: false,
|
hideMessageBubble: false,
|
||||||
position: 'right',
|
|
||||||
isWebWidgetTriggered: false,
|
|
||||||
isCampaignViewClicked: false,
|
isCampaignViewClicked: false,
|
||||||
|
isWebWidgetTriggered: false,
|
||||||
isWidgetOpen: false,
|
isWidgetOpen: false,
|
||||||
widgetColor: '',
|
position: 'right',
|
||||||
referrerHost: '',
|
referrerHost: '',
|
||||||
|
showPopoutButton: false,
|
||||||
|
widgetColor: '',
|
||||||
|
widgetStyle: 'standard',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
|
@ -23,14 +24,19 @@ export const getters = {
|
||||||
getIsWidgetOpen: $state => $state.isWidgetOpen,
|
getIsWidgetOpen: $state => $state.isWidgetOpen,
|
||||||
getWidgetColor: $state => $state.widgetColor,
|
getWidgetColor: $state => $state.widgetColor,
|
||||||
getReferrerHost: $state => $state.referrerHost,
|
getReferrerHost: $state => $state.referrerHost,
|
||||||
|
isWidgetStyleFlat: $state => $state.widgetStyle === 'flat',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
setAppConfig({ commit }, { showPopoutButton, position, hideMessageBubble }) {
|
setAppConfig(
|
||||||
|
{ commit },
|
||||||
|
{ showPopoutButton, position, hideMessageBubble, widgetStyle = 'rounded' }
|
||||||
|
) {
|
||||||
commit(SET_WIDGET_APP_CONFIG, {
|
commit(SET_WIDGET_APP_CONFIG, {
|
||||||
showPopoutButton: !!showPopoutButton,
|
|
||||||
position: position || 'right',
|
|
||||||
hideMessageBubble: !!hideMessageBubble,
|
hideMessageBubble: !!hideMessageBubble,
|
||||||
|
position: position || 'right',
|
||||||
|
showPopoutButton: !!showPopoutButton,
|
||||||
|
widgetStyle,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toggleWidgetOpen({ commit }, isWidgetOpen) {
|
toggleWidgetOpen({ commit }, isWidgetOpen) {
|
||||||
|
@ -49,6 +55,7 @@ export const mutations = {
|
||||||
$state.showPopoutButton = data.showPopoutButton;
|
$state.showPopoutButton = data.showPopoutButton;
|
||||||
$state.position = data.position;
|
$state.position = data.position;
|
||||||
$state.hideMessageBubble = data.hideMessageBubble;
|
$state.hideMessageBubble = data.hideMessageBubble;
|
||||||
|
$state.widgetStyle = data.widgetStyle;
|
||||||
},
|
},
|
||||||
[TOGGLE_WIDGET_OPEN]($state, isWidgetOpen) {
|
[TOGGLE_WIDGET_OPEN]($state, isWidgetOpen) {
|
||||||
$state.isWidgetOpen = isWidgetOpen;
|
$state.isWidgetOpen = isWidgetOpen;
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
|
|
||||||
window.chatwootSettings = {
|
window.chatwootSettings = {
|
||||||
hideMessageBubble: false,
|
hideMessageBubble: false,
|
||||||
position: 'left',
|
position: '<%= @widget_position %>',
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
type: 'expanded_bubble',
|
type: '<%= @widget_type %>',
|
||||||
showPopoutButton: true,
|
showPopoutButton: true,
|
||||||
|
widgetStyle: '<%= @widget_style %>',
|
||||||
};
|
};
|
||||||
|
|
||||||
(function(d,t) {
|
(function(d,t) {
|
||||||
|
|
Loading…
Reference in a new issue