Skip to content

Commit

Permalink
Open and close Zendesk widget via a link in the footer
Browse files Browse the repository at this point in the history
Javascript in this commit

- shows the link when the support team come online, or if they are
  already online
- hides the link when the team go or are offline
- opens the chat popup when the link is clicked

default (no-JS) behaviour is not to show the link to the widget.
  • Loading branch information
duncanjbrown committed Jul 2, 2021
1 parent 4da74c4 commit 19d61e8
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 17 deletions.
2 changes: 2 additions & 0 deletions app/frontend/packs/application-provider.js
Expand Up @@ -5,6 +5,7 @@ import filter from './components/paginated_filter'
import checkboxSearchFilter from './components/checkbox_search_filter'
import '../styles/application-provider.scss'
import cookieBanners from './cookies/cookie-banners'
import webchat from './webchat'

require.context('govuk-frontend/govuk/assets')

Expand All @@ -14,3 +15,4 @@ initAddFurtherConditions()
checkboxSearchFilter('subject', 'Search for subject')
filter()
cookieBanners()
webchat()
71 changes: 71 additions & 0 deletions app/frontend/packs/webchat.js
@@ -0,0 +1,71 @@
function Webchat () {
this.container = document.getElementById('app-web-chat')

this.configureWidget()
this.setupElements()
this.addButtonListener()
this.addStatusChangeListener()
}

Webchat.prototype.configureWidget = function () {
window.zESettings = {
webWidget: {
chat: {
suppress: true
}
}
}
}

Webchat.prototype.setupElements = function () {
this.enabledContainer = document.createElement('span')
this.enabledContainer.className = 'moj-hidden'

this.defaultContainer = document.querySelector('.app-web-chat__unavailable')

this.button = document.createElement('a')
this.button.href = '#'
this.button.className = 'govuk-link govuk-footer__link app-web-chat__button'
this.button.innerHTML = 'Speak to an advisor now (opens in new window)'
this.enabledContainer.append(this.button)

this.disabledContainer = document.createElement('span')
this.disabledContainer.className = 'app-web-chat__offline moj-hidden'
this.disabledContainer.innerHTML = 'Available Monday to Friday, 10am to midday (except public holidays).'

this.container.append(this.enabledContainer)
this.container.append(this.disabledContainer)
}

Webchat.prototype.addButtonListener = function () {
this.button.addEventListener('click', function (e) {
e.preventDefault()

zE('webWidget', 'popout')
}, false)
}

Webchat.prototype.addStatusChangeListener = function () {
zE('webWidget:on', 'chat:status', function (status) {
this.defaultContainer.classList.add('moj-hidden')

if (status === 'online') {
this.enableChat()
} else {
this.disableChat()
}
}.bind(this))
}

Webchat.prototype.enableChat = function () {
this.disabledContainer.classList.add('moj-hidden')
this.enabledContainer.classList.remove('moj-hidden')
}

Webchat.prototype.disableChat = function () {
this.disabledContainer.classList.remove('moj-hidden')
this.enabledContainer.classList.add('moj-hidden')
}

const webchat = () => new Webchat()
export default webchat
18 changes: 18 additions & 0 deletions app/frontend/packs/zendesk-stub.js
@@ -0,0 +1,18 @@
window.zendeskPopupOpen = false

window.setZendeskStatus = function (status) {
const statusChangeEvent = new CustomEvent('setZendeskStubStatus', { detail: status })
document.body.dispatchEvent(statusChangeEvent)
}

window.zE = function (scope, command, callback = null) {
if (scope === 'webWidget' && command === 'popout') {
window.zendeskPopupOpen = true
} else if (scope === 'webWidget:on' && command === 'chat:status') {
document.body.addEventListener('setZendeskStubStatus', function (e) {
callback(e.detail)
})
} else {
throw Error('Unexpected Zendesk API function call')
}
}
40 changes: 31 additions & 9 deletions app/views/layouts/_footer_meta_provider.html.erb
@@ -1,14 +1,36 @@
<h2 class="govuk-heading-m"><%= t('layout.support.title') %></h2>
<ul class="govuk-footer__meta-custom govuk-list govuk-!-font-size-16">
<li>Email: <%= bat_contact_mail_to(html_options: { class: 'govuk-footer__link' }) %></li>
<li><%= t('layout.support.response_time') %></li>
<li>Alternatively, <%= link_to 'give feedback through our survey', ProviderInterface::FEEDBACK_LINK, class: 'govuk-footer__link' %></li>
</ul>
<p class="govuk-body govuk-list govuk-!-font-size-16 govuk-!-margin-bottom-8">
<%= link_to t('layout.support.provider_service_guidance'), provider_interface_service_guidance_path, class: 'govuk-footer__link' %>
</p>

<div class="govuk-footer__meta-custom">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<div class="govuk-!-padding-right-1">
<h3 class="govuk-heading-s govuk-!-margin-bottom-1">
Online chat
</h3>

<p class="govuk-!-margin-top-0 govuk-!-font-size-16"><span id="app-web-chat">
<span class="app-web-chat__unavailable">
You cannot use online chat because there’s a problem. Send an email if you keep seeing this message.</span>
</span></p>
</div>
</div>
<div class="govuk-grid-column-one-half">
<div class="govuk-!-padding-left-1">
<h3 class="govuk-heading-s govuk-!-margin-bottom-1">
Email
</h3>
<p class="govuk-!-margin-top-0 govuk-!-font-size-16 govuk-!-margin-bottom-1"><%= bat_contact_mail_to(html_options: { class: 'govuk-footer__link' }) %></p>
<p class="govuk-!-font-size-16"><%= t('layout.support.response_time') %></p>
</div>
</div>
</div>
</div>

<h2 class="govuk-visually-hidden"><%= t('layout.support_links.title') %></h2>
<ul class="govuk-footer__inline-list govuk-!-margin-bottom-0">
<ul class="govuk-footer__inline-list">
<li class="govuk-footer__inline-list-item">
<%= link_to t('layout.support.provider_service_guidance'), provider_interface_service_guidance_path, class: 'govuk-footer__link' %>
</li>
<li class="govuk-footer__inline-list-item">
<%= link_to t('layout.support_links.accessibility'), provider_interface_accessibility_path, class: 'govuk-footer__link' %>
</li>
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/base.html.erb
Expand Up @@ -66,8 +66,8 @@
<% when 'support_interface' %>
<%= javascript_pack_tag 'application-support' %>
<% when 'provider_interface' %>
<%= javascript_pack_tag 'application-provider' %>
<%= render 'shared/zendesk_snippet' if HostingEnvironment.test_environment? %>
<%= javascript_pack_tag 'application-provider' %>
<% when /api_docs/ %>
<%= javascript_pack_tag 'application-api-docs' %>
<% else %>
Expand Down
14 changes: 9 additions & 5 deletions app/views/shared/_zendesk_snippet.html.erb
@@ -1,5 +1,9 @@
<script
id="ze-snippet"
nonce="<%= request.content_security_policy_nonce %>"
src=https://static.zdassets.com/ekr/snippet.js?key=904d04ae-8027-4ebb-ad39-d0e9f68d6ab1>
</script>
<% if Rails.env.test? %>
<%= javascript_pack_tag('zendesk-stub') %>
<% else %>
<script
id="ze-snippet"
nonce="<%= request.content_security_policy_nonce %>"
src=https://static.zdassets.com/ekr/snippet.js?key=904d04ae-8027-4ebb-ad39-d0e9f68d6ab1>
</script>
<% end %>
2 changes: 1 addition & 1 deletion config/locales/en.yml
Expand Up @@ -250,7 +250,7 @@ en:
telephone: Telephone
online_chat: Online chat
talk_to_advisor: Talk to an adviser online
response_time: "- response times are usually under one working day"
response_time: You’ll get a response within 5 working days, or one working day for urgent requests.
provider_service_guidance: How to use this service
support_links:
title: Support links
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -35,7 +35,9 @@
],
"globals": [
"$",
"history"
"history",
"zE",
"CustomEvent"
]
},
"stylelint": {
Expand Down
58 changes: 58 additions & 0 deletions spec/system/provider_interface/provider_uses_webchat_spec.rb
@@ -0,0 +1,58 @@
require 'rails_helper'

RSpec.feature 'Provider uses webchat' do
include DfESignInHelpers

scenario 'controlling the widget via a link in the footer', js: true do
given_i_am_a_provider_user
and_i_sign_in_to_the_provider_interface
when_i_visit_the_provider_interface
and_there_is_no_support_agent_online

then_i_should_see_no_link_in_the_footer

when_a_support_agent_comes_online
then_i_should_see_a_link_in_the_footer
and_when_i_click_the_link_i_see_a_popup

when_the_support_agent_goes_offline
then_i_should_see_no_link_in_the_footer
end

def given_i_am_a_provider_user
provider_user = create(:provider_user)
user_exists_in_dfe_sign_in(email_address: provider_user.email_address)
end

def and_i_sign_in_to_the_provider_interface
provider_signs_in_using_dfe_sign_in
end

def when_i_visit_the_provider_interface
visit provider_interface_applications_path
end

def and_there_is_no_support_agent_online; end

def then_i_should_see_no_link_in_the_footer
expect(page).not_to have_content('speak to an advisor now')
end

def when_a_support_agent_comes_online
page.evaluate_script('setZendeskStatus("online")')
end

def then_i_should_see_a_link_in_the_footer
expect(page).to have_content('speak to an advisor now')
end

def and_when_i_click_the_link_i_see_a_popup
click_link 'speak to an advisor now'

expect(page.evaluate_script('window.zendeskPopupOpen')).to eq true
end

def when_the_support_agent_goes_offline
page.evaluate_script('setZendeskStatus("offline")')
end
end

0 comments on commit 19d61e8

Please sign in to comment.